Copy disabled (too large)
Download .txt
Showing preview only (12,919K chars total). Download the full file to get everything.
Repository: google/go-cloud
Branch: master
Commit: 515d2d303ad4
Files: 1056
Total size: 12.1 MB
Directory structure:
gitextract_d66nvpyk/
├── .codecov.yml
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── pull_request_template.md
│ └── workflows/
│ └── tests.yml
├── .gitignore
├── AUTHORS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── CONTRIBUTORS
├── LICENSE
├── README.md
├── allmodules
├── aws/
│ ├── aws.go
│ ├── aws_test.go
│ ├── awscloud/
│ │ ├── awscloud.go
│ │ └── example_test.go
│ └── rds/
│ └── rds.go
├── azure/
│ ├── azurecloud/
│ │ └── azurecloud.go
│ └── azuredb/
│ └── azuredb.go
├── blob/
│ ├── azureblob/
│ │ ├── azureblob.go
│ │ ├── azureblob_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ ├── TestAttributes.replay
│ │ ├── TestCanceledWrite/
│ │ │ ├── BlobExists.replay
│ │ │ ├── EmptyContentType.replay
│ │ │ └── NonEmptyContentType.replay
│ │ ├── TestConcurrentWriteAndRead.replay
│ │ ├── TestCopy/
│ │ │ ├── NonExistentSourceFails.replay
│ │ │ └── Works.replay
│ │ ├── TestDelete/
│ │ │ ├── NonExistentFails.replay
│ │ │ └── Works.replay
│ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ ├── TestIfNotExist.replay
│ │ ├── TestKeys/
│ │ │ ├── ascii-1.replay
│ │ │ ├── ascii-2.replay
│ │ │ ├── ascii-3.replay
│ │ │ ├── ascii-4.replay
│ │ │ ├── ascii-5.replay
│ │ │ ├── ascii-6.replay
│ │ │ ├── ascii-7.replay
│ │ │ ├── ascii-8.replay
│ │ │ ├── backslashes.replay
│ │ │ ├── dotdotbackslash.replay
│ │ │ ├── dotdotslash.replay
│ │ │ ├── fwdslashes.replay
│ │ │ ├── non-UTF8_fails.replay
│ │ │ ├── quote.replay
│ │ │ ├── repeatedbackslashes.replay
│ │ │ ├── repeatedfwdslashes.replay
│ │ │ ├── spaces.replay
│ │ │ ├── startwithdigit.replay
│ │ │ └── unicode.replay
│ │ ├── TestList/
│ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ ├── by_1.replay
│ │ │ ├── by_2.replay
│ │ │ ├── by_3.replay
│ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ ├── no_objects.replay
│ │ │ └── no_pagination.replay
│ │ ├── TestListDelimiters/
│ │ │ ├── abc.replay
│ │ │ ├── backslash.replay
│ │ │ └── fwdslash.replay
│ │ ├── TestListWeirdKeys.replay
│ │ ├── TestMD5.replay
│ │ ├── TestMetadata/
│ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ ├── empty.replay
│ │ │ ├── empty_key_fails.replay
│ │ │ ├── non-utf8_metadata_key.replay
│ │ │ ├── non-utf8_metadata_value.replay
│ │ │ ├── valid_metadata.replay
│ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ └── weird_metadata_keys.replay
│ │ ├── TestNonexistentBucket.replay
│ │ ├── TestRead/
│ │ │ ├── length_0_read.replay
│ │ │ ├── negative_offset_fails.replay
│ │ │ ├── read_a_part_in_middle.replay
│ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ ├── read_in_full.replay
│ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ └── read_of_nonexistent_key_fails.replay
│ │ ├── TestSignedURL.replay
│ │ ├── TestUploadDownload.replay
│ │ └── TestWrite/
│ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ ├── Content_md5_did_not_match.replay
│ │ ├── Content_md5_match.replay
│ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ ├── invalid_ContentType_fails.replay
│ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ ├── write_to_empty_key_fails.replay
│ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ ├── blob.go
│ ├── blob_fs.go
│ ├── blob_fs_test.go
│ ├── blob_iter_test.go
│ ├── blob_reader_test.go
│ ├── blob_test.go
│ ├── blob_writer_test.go
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ ├── bindata.go
│ │ └── drivertest.go
│ ├── example_openbucket_test.go
│ ├── example_test.go
│ ├── fileblob/
│ │ ├── attrs.go
│ │ ├── example_test.go
│ │ ├── fileblob.go
│ │ └── fileblob_test.go
│ ├── gcsblob/
│ │ ├── example_test.go
│ │ ├── gcsblob.go
│ │ ├── gcsblob_test.go
│ │ ├── iam.go
│ │ ├── iam_test.go
│ │ └── testdata/
│ │ ├── TestBeforeReadNonExistentKey.replay
│ │ ├── TestConformance/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ │ ├── TestAttributes.replay
│ │ │ ├── TestCanceledWrite/
│ │ │ │ ├── BlobExists.replay
│ │ │ │ ├── EmptyContentType.replay
│ │ │ │ └── NonEmptyContentType.replay
│ │ │ ├── TestConcurrentWriteAndRead.replay
│ │ │ ├── TestCopy/
│ │ │ │ ├── NonExistentSourceFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDelete/
│ │ │ │ ├── NonExistentFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ │ ├── TestIfNotExist.replay
│ │ │ ├── TestKeys/
│ │ │ │ ├── ascii-1.replay
│ │ │ │ ├── ascii-2.replay
│ │ │ │ ├── ascii-3.replay
│ │ │ │ ├── ascii-4.replay
│ │ │ │ ├── ascii-5.replay
│ │ │ │ ├── ascii-6.replay
│ │ │ │ ├── ascii-7.replay
│ │ │ │ ├── ascii-8.replay
│ │ │ │ ├── backslashes.replay
│ │ │ │ ├── dotdotbackslash.replay
│ │ │ │ ├── dotdotslash.replay
│ │ │ │ ├── fwdslashes.replay
│ │ │ │ ├── non-UTF8_fails.replay
│ │ │ │ ├── quote.replay
│ │ │ │ ├── repeatedbackslashes.replay
│ │ │ │ ├── repeatedfwdslashes.replay
│ │ │ │ ├── spaces.replay
│ │ │ │ ├── startwithdigit.replay
│ │ │ │ └── unicode.replay
│ │ │ ├── TestList/
│ │ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ │ ├── by_1.replay
│ │ │ │ ├── by_2.replay
│ │ │ │ ├── by_3.replay
│ │ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ │ ├── no_objects.replay
│ │ │ │ └── no_pagination.replay
│ │ │ ├── TestListDelimiters/
│ │ │ │ ├── abc.replay
│ │ │ │ ├── backslash.replay
│ │ │ │ └── fwdslash.replay
│ │ │ ├── TestListWeirdKeys.replay
│ │ │ ├── TestMD5.replay
│ │ │ ├── TestMetadata/
│ │ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ │ ├── empty.replay
│ │ │ │ ├── empty_key_fails.replay
│ │ │ │ ├── non-utf8_metadata_key.replay
│ │ │ │ ├── non-utf8_metadata_value.replay
│ │ │ │ ├── valid_metadata.replay
│ │ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ │ └── weird_metadata_keys.replay
│ │ │ ├── TestNonexistentBucket.replay
│ │ │ ├── TestRead/
│ │ │ │ ├── length_0_read.replay
│ │ │ │ ├── negative_offset_fails.replay
│ │ │ │ ├── read_a_part_in_middle.replay
│ │ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ │ ├── read_in_full.replay
│ │ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ │ └── read_of_nonexistent_key_fails.replay
│ │ │ ├── TestSignedURL.replay
│ │ │ ├── TestUploadDownload.replay
│ │ │ └── TestWrite/
│ │ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ │ ├── Content_md5_did_not_match.replay
│ │ │ ├── Content_md5_match.replay
│ │ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ │ ├── invalid_ContentType_fails.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ │ ├── write_to_empty_key_fails.replay
│ │ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ │ ├── TestOpenBucket/
│ │ │ ├── empty_bucket_name_results_in_error.replay
│ │ │ └── success.replay
│ │ └── TestPreconditions.replay
│ ├── memblob/
│ │ ├── example_test.go
│ │ ├── memblob.go
│ │ └── memblob_test.go
│ ├── otel_test.go
│ ├── s3blob/
│ │ ├── example_test.go
│ │ ├── s3blob.go
│ │ ├── s3blob_test.go
│ │ └── testdata/
│ │ ├── TestConformance/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ │ ├── TestAttributes.replay
│ │ │ ├── TestCanceledWrite/
│ │ │ │ ├── BlobExists.replay
│ │ │ │ ├── EmptyContentType.replay
│ │ │ │ └── NonEmptyContentType.replay
│ │ │ ├── TestConcurrentWriteAndRead.replay
│ │ │ ├── TestCopy/
│ │ │ │ ├── NonExistentSourceFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDelete/
│ │ │ │ ├── NonExistentFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ │ ├── TestIfNotExist.replay
│ │ │ ├── TestKeys/
│ │ │ │ ├── ascii-1.replay
│ │ │ │ ├── ascii-2.replay
│ │ │ │ ├── ascii-3.replay
│ │ │ │ ├── ascii-4.replay
│ │ │ │ ├── ascii-5.replay
│ │ │ │ ├── ascii-6.replay
│ │ │ │ ├── ascii-7.replay
│ │ │ │ ├── ascii-8.replay
│ │ │ │ ├── backslashes.replay
│ │ │ │ ├── dotdotbackslash.replay
│ │ │ │ ├── dotdotslash.replay
│ │ │ │ ├── fwdslashes.replay
│ │ │ │ ├── non-UTF8_fails.replay
│ │ │ │ ├── quote.replay
│ │ │ │ ├── repeatedbackslashes.replay
│ │ │ │ ├── repeatedfwdslashes.replay
│ │ │ │ ├── spaces.replay
│ │ │ │ ├── startwithdigit.replay
│ │ │ │ └── unicode.replay
│ │ │ ├── TestList/
│ │ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ │ ├── by_1.replay
│ │ │ │ ├── by_2.replay
│ │ │ │ ├── by_3.replay
│ │ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ │ ├── no_objects.replay
│ │ │ │ └── no_pagination.replay
│ │ │ ├── TestListDelimiters/
│ │ │ │ ├── abc.replay
│ │ │ │ ├── backslash.replay
│ │ │ │ └── fwdslash.replay
│ │ │ ├── TestListWeirdKeys.replay
│ │ │ ├── TestMD5.replay
│ │ │ ├── TestMetadata/
│ │ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ │ ├── empty.replay
│ │ │ │ ├── empty_key_fails.replay
│ │ │ │ ├── non-utf8_metadata_key.replay
│ │ │ │ ├── non-utf8_metadata_value.replay
│ │ │ │ ├── valid_metadata.replay
│ │ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ │ └── weird_metadata_keys.replay
│ │ │ ├── TestNonexistentBucket.replay
│ │ │ ├── TestRead/
│ │ │ │ ├── length_0_read.replay
│ │ │ │ ├── negative_offset_fails.replay
│ │ │ │ ├── read_a_part_in_middle.replay
│ │ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ │ ├── read_in_full.replay
│ │ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ │ └── read_of_nonexistent_key_fails.replay
│ │ │ ├── TestSignedURL.replay
│ │ │ ├── TestUploadDownload.replay
│ │ │ └── TestWrite/
│ │ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ │ ├── Content_md5_did_not_match.replay
│ │ │ ├── Content_md5_match.replay
│ │ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ │ ├── invalid_ContentType_fails.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ │ ├── write_to_empty_key_fails.replay
│ │ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ │ ├── TestConformanceUsingLegacyList/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ │ ├── TestAttributes.replay
│ │ │ ├── TestCanceledWrite/
│ │ │ │ ├── BlobExists.replay
│ │ │ │ ├── EmptyContentType.replay
│ │ │ │ └── NonEmptyContentType.replay
│ │ │ ├── TestConcurrentWriteAndRead.replay
│ │ │ ├── TestCopy/
│ │ │ │ ├── NonExistentSourceFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDelete/
│ │ │ │ ├── NonExistentFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ │ ├── TestIfNotExist.replay
│ │ │ ├── TestKeys/
│ │ │ │ ├── ascii-1.replay
│ │ │ │ ├── ascii-2.replay
│ │ │ │ ├── ascii-3.replay
│ │ │ │ ├── ascii-4.replay
│ │ │ │ ├── ascii-5.replay
│ │ │ │ ├── ascii-6.replay
│ │ │ │ ├── ascii-7.replay
│ │ │ │ ├── ascii-8.replay
│ │ │ │ ├── backslashes.replay
│ │ │ │ ├── dotdotbackslash.replay
│ │ │ │ ├── dotdotslash.replay
│ │ │ │ ├── fwdslashes.replay
│ │ │ │ ├── non-UTF8_fails.replay
│ │ │ │ ├── quote.replay
│ │ │ │ ├── repeatedbackslashes.replay
│ │ │ │ ├── repeatedfwdslashes.replay
│ │ │ │ ├── spaces.replay
│ │ │ │ ├── startwithdigit.replay
│ │ │ │ └── unicode.replay
│ │ │ ├── TestList/
│ │ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ │ ├── by_1.replay
│ │ │ │ ├── by_2.replay
│ │ │ │ ├── by_3.replay
│ │ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ │ ├── no_objects.replay
│ │ │ │ └── no_pagination.replay
│ │ │ ├── TestListDelimiters/
│ │ │ │ ├── abc.replay
│ │ │ │ ├── backslash.replay
│ │ │ │ └── fwdslash.replay
│ │ │ ├── TestListWeirdKeys.replay
│ │ │ ├── TestMD5.replay
│ │ │ ├── TestMetadata/
│ │ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ │ ├── empty.replay
│ │ │ │ ├── empty_key_fails.replay
│ │ │ │ ├── non-utf8_metadata_key.replay
│ │ │ │ ├── non-utf8_metadata_value.replay
│ │ │ │ ├── valid_metadata.replay
│ │ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ │ └── weird_metadata_keys.replay
│ │ │ ├── TestNonexistentBucket.replay
│ │ │ ├── TestRead/
│ │ │ │ ├── length_0_read.replay
│ │ │ │ ├── negative_offset_fails.replay
│ │ │ │ ├── read_a_part_in_middle.replay
│ │ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ │ ├── read_in_full.replay
│ │ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ │ └── read_of_nonexistent_key_fails.replay
│ │ │ ├── TestSignedURL.replay
│ │ │ ├── TestUploadDownload.replay
│ │ │ └── TestWrite/
│ │ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ │ ├── Content_md5_did_not_match.replay
│ │ │ ├── Content_md5_match.replay
│ │ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ │ ├── invalid_ContentType_fails.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ │ ├── write_to_empty_key_fails.replay
│ │ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ │ └── TestOpenBucket/
│ │ ├── empty_bucket_name_results_in_error.replay
│ │ ├── empty_bucket_name_results_in_error_V2.replay
│ │ ├── success.replay
│ │ └── success_V2.replay
│ └── wrapped_bucket_test.go
├── contrib/
│ └── upgrade-dependency.sh
├── doc.go
├── docstore/
│ ├── awsdynamodb/
│ │ └── v2/
│ │ ├── benchmark_test.go
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── create_tables.sh
│ │ ├── dynamo.go
│ │ ├── dynamo_test.go
│ │ ├── example_test.go
│ │ ├── query.go
│ │ ├── query_test.go
│ │ ├── testdata/
│ │ │ ├── TestConformance/
│ │ │ │ ├── ActionsOnStructNoRev.replay
│ │ │ │ ├── ActionsWithCompositeID.replay
│ │ │ │ ├── As/
│ │ │ │ │ ├── verify_As.replay
│ │ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ ├── AtomicWrites.replay
│ │ │ │ ├── AtomicWritesFail.replay
│ │ │ │ ├── BeforeDo.replay
│ │ │ │ ├── BeforeQuery.replay
│ │ │ │ ├── Create.replay
│ │ │ │ ├── Data.replay
│ │ │ │ ├── Delete.replay
│ │ │ │ ├── ExampleInDoc.replay
│ │ │ │ ├── Get.replay
│ │ │ │ ├── GetQuery.replay
│ │ │ │ ├── GetQueryKeyField.replay
│ │ │ │ ├── MultipleActions.replay
│ │ │ │ ├── Proto.replay
│ │ │ │ ├── Put.replay
│ │ │ │ ├── Replace.replay
│ │ │ │ ├── SerializeRevision.replay
│ │ │ │ └── Update.replay
│ │ │ └── TestQueryErrors.replay
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── doc.go
│ ├── docstore.go
│ ├── docstore_test.go
│ ├── driver/
│ │ ├── actionkind_string.go
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── compare.go
│ │ ├── compare_test.go
│ │ ├── document.go
│ │ ├── document_test.go
│ │ ├── driver.go
│ │ ├── util.go
│ │ └── util_test.go
│ ├── drivertest/
│ │ ├── driverbenchmark.go
│ │ ├── drivertest.go
│ │ └── util.go
│ ├── example_test.go
│ ├── gcpfirestore/
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── create_indexes.sh
│ │ ├── example_test.go
│ │ ├── fs.go
│ │ ├── fs_test.go
│ │ ├── native_codec_test.go
│ │ ├── query.go
│ │ ├── query_test.go
│ │ ├── testdata/
│ │ │ └── TestConformance/
│ │ │ ├── ActionsOnStructNoRev.replay
│ │ │ ├── ActionsWithCompositeID.replay
│ │ │ ├── As/
│ │ │ │ ├── verify_As.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── AtomicWrites.replay
│ │ │ ├── AtomicWritesFail.replay
│ │ │ ├── BeforeDo.replay
│ │ │ ├── BeforeQuery.replay
│ │ │ ├── Create.replay
│ │ │ ├── Data.replay
│ │ │ ├── Delete.replay
│ │ │ ├── ExampleInDoc.replay
│ │ │ ├── Get.replay
│ │ │ ├── GetQuery.replay
│ │ │ ├── GetQueryKeyField.replay
│ │ │ ├── MultipleActions.replay
│ │ │ ├── Proto.replay
│ │ │ ├── Put.replay
│ │ │ ├── Query.replay
│ │ │ ├── Replace.replay
│ │ │ ├── SerializeRevision.replay
│ │ │ └── Update.replay
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── internal/
│ │ └── fields/
│ │ ├── README.md
│ │ ├── fields.go
│ │ ├── fields_test.go
│ │ ├── fold.go
│ │ └── fold_test.go
│ ├── memdocstore/
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── example_test.go
│ │ ├── mem.go
│ │ ├── mem_test.go
│ │ ├── query.go
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── mongodocstore/
│ │ ├── awsdocdb/
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
│ │ ├── codec.go
│ │ ├── cosmos_test.go
│ │ ├── docdb_test.go
│ │ ├── docker-compose.yml
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── localmongo.sh
│ │ ├── mongo.go
│ │ ├── mongo_test.go
│ │ ├── query.go
│ │ ├── testdata/
│ │ │ └── README
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── otel_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── urls.go
│ └── urls_test.go
├── gcerrors/
│ ├── errors.go
│ └── errors_test.go
├── gcp/
│ ├── cloudsql/
│ │ └── cloudsql.go
│ ├── gcp.go
│ ├── gcp_test.go
│ └── gcpcloud/
│ ├── example_test.go
│ └── gcpcloud.go
├── go.mod
├── go.sum
├── gocloud.code-workspace
├── internal/
│ ├── docs/
│ │ ├── README.md
│ │ ├── design.md
│ │ ├── pubsub/
│ │ │ └── design.md
│ │ └── release.md
│ ├── escape/
│ │ ├── escape.go
│ │ └── escape_test.go
│ ├── gcerr/
│ │ ├── errorcode_string.go
│ │ ├── gcerr.go
│ │ └── gcerr_test.go
│ ├── openurl/
│ │ ├── openurl.go
│ │ └── openurl_test.go
│ ├── otel/
│ │ ├── metrics.go
│ │ ├── trace.go
│ │ └── trace_test.go
│ ├── releasehelper/
│ │ ├── releasehelper.go
│ │ └── releasehelper_test.go
│ ├── retry/
│ │ ├── retry.go
│ │ └── retry_test.go
│ ├── testing/
│ │ ├── alldeps
│ │ ├── check_mod_tidy.sh
│ │ ├── deploywebsite.sh
│ │ ├── git_tag_modules.sh
│ │ ├── gomodcleanup.sh
│ │ ├── listdeps.sh
│ │ ├── oteltest/
│ │ │ ├── diff.go
│ │ │ ├── exporter.go
│ │ │ └── init.go
│ │ ├── runchecks.sh
│ │ ├── setup/
│ │ │ └── setup.go
│ │ ├── start_local_deps.sh
│ │ ├── terraform/
│ │ │ └── terraform.go
│ │ ├── test-summary/
│ │ │ ├── test-summary.go
│ │ │ └── test-summary_test.go
│ │ └── update_deps.sh
│ ├── useragent/
│ │ └── useragent.go
│ └── website/
│ ├── README.md
│ ├── archetypes/
│ │ ├── default.md
│ │ └── howto.md
│ ├── config.toml
│ ├── content/
│ │ ├── _index.md
│ │ ├── aws/
│ │ │ ├── _index.md
│ │ │ ├── awscloud/
│ │ │ │ └── _index.md
│ │ │ └── rds/
│ │ │ └── _index.md
│ │ ├── azure/
│ │ │ ├── azurecloud/
│ │ │ │ └── _index.md
│ │ │ └── azuredb/
│ │ │ └── _index.md
│ │ ├── blob/
│ │ │ ├── _index.md
│ │ │ ├── azureblob/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── fileblob/
│ │ │ │ └── _index.md
│ │ │ ├── gcsblob/
│ │ │ │ └── _index.md
│ │ │ ├── memblob/
│ │ │ │ └── _index.md
│ │ │ └── s3blob/
│ │ │ └── _index.md
│ │ ├── concepts/
│ │ │ ├── _index.md
│ │ │ ├── as.md
│ │ │ ├── structure/
│ │ │ │ └── index.md
│ │ │ └── urls.md
│ │ ├── docstore/
│ │ │ ├── _index.md
│ │ │ ├── awsdynamodb/
│ │ │ │ └── v2/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── dynamodocstore/
│ │ │ │ └── _index.md
│ │ │ ├── firedocstore/
│ │ │ │ └── _index.md
│ │ │ ├── gcpfirestore/
│ │ │ │ └── _index.md
│ │ │ ├── internal/
│ │ │ │ └── fields/
│ │ │ │ └── _index.md
│ │ │ ├── memdocstore/
│ │ │ │ └── _index.md
│ │ │ └── mongodocstore/
│ │ │ └── _index.md
│ │ ├── gcerrors/
│ │ │ └── _index.md
│ │ ├── gcp/
│ │ │ ├── _index.md
│ │ │ ├── cloudsql/
│ │ │ │ └── _index.md
│ │ │ └── gcpcloud/
│ │ │ └── _index.md
│ │ ├── health/
│ │ │ ├── _index.md
│ │ │ └── sqlhealth/
│ │ │ └── _index.md
│ │ ├── howto/
│ │ │ ├── _index.md
│ │ │ ├── blob/
│ │ │ │ └── _index.md
│ │ │ ├── docstore/
│ │ │ │ └── _index.md
│ │ │ ├── pubsub/
│ │ │ │ ├── _index.md
│ │ │ │ ├── publish.md
│ │ │ │ └── subscribe.md
│ │ │ ├── runtimevar/
│ │ │ │ └── _index.md
│ │ │ ├── secrets/
│ │ │ │ └── _index.md
│ │ │ ├── server/
│ │ │ │ └── _index.md
│ │ │ └── sql/
│ │ │ └── _index.md
│ │ ├── internal/
│ │ │ ├── batcher/
│ │ │ │ └── _index.md
│ │ │ ├── escape/
│ │ │ │ └── _index.md
│ │ │ ├── gcerr/
│ │ │ │ └── _index.md
│ │ │ ├── oc/
│ │ │ │ └── _index.md
│ │ │ ├── openurl/
│ │ │ │ └── _index.md
│ │ │ ├── otel/
│ │ │ │ └── _index.md
│ │ │ ├── releasehelper/
│ │ │ │ └── _index.md
│ │ │ ├── retry/
│ │ │ │ └── _index.md
│ │ │ ├── testing/
│ │ │ │ ├── _index.md
│ │ │ │ ├── cmdtest/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── octest/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── oteltest/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── setup/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── terraform/
│ │ │ │ │ └── _index.md
│ │ │ │ └── test-summary/
│ │ │ │ └── _index.md
│ │ │ ├── trace/
│ │ │ │ └── _index.md
│ │ │ ├── useragent/
│ │ │ │ └── _index.md
│ │ │ └── website/
│ │ │ └── gatherexamples/
│ │ │ └── _index.md
│ │ ├── mysql/
│ │ │ ├── _index.md
│ │ │ ├── awsmysql/
│ │ │ │ └── _index.md
│ │ │ ├── azuremysql/
│ │ │ │ └── _index.md
│ │ │ ├── cloudmysql/
│ │ │ │ └── _index.md
│ │ │ ├── gcpmysql/
│ │ │ │ └── _index.md
│ │ │ └── rdsmysql/
│ │ │ └── _index.md
│ │ ├── postgres/
│ │ │ ├── _index.md
│ │ │ ├── awspostgres/
│ │ │ │ └── _index.md
│ │ │ ├── cloudpostgres/
│ │ │ │ └── _index.md
│ │ │ ├── gcppostgres/
│ │ │ │ └── _index.md
│ │ │ └── rdspostgres/
│ │ │ └── _index.md
│ │ ├── pubsub/
│ │ │ ├── _index.md
│ │ │ ├── awssnssqs/
│ │ │ │ └── _index.md
│ │ │ ├── azurepubsub/
│ │ │ │ └── _index.md
│ │ │ ├── azuresb/
│ │ │ │ └── _index.md
│ │ │ ├── batcher/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── gcppubsub/
│ │ │ │ └── _index.md
│ │ │ ├── gcppubsubv2/
│ │ │ │ └── _index.md
│ │ │ ├── kafkapubsub/
│ │ │ │ └── _index.md
│ │ │ ├── mempubsub/
│ │ │ │ └── _index.md
│ │ │ ├── natspubsub/
│ │ │ │ └── _index.md
│ │ │ └── rabbitpubsub/
│ │ │ └── _index.md
│ │ ├── requestlog/
│ │ │ └── _index.md
│ │ ├── runtimevar/
│ │ │ ├── _index.md
│ │ │ ├── awsparamstore/
│ │ │ │ └── _index.md
│ │ │ ├── awssecretsmanager/
│ │ │ │ └── _index.md
│ │ │ ├── blobvar/
│ │ │ │ └── _index.md
│ │ │ ├── constantvar/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── etcdvar/
│ │ │ │ └── _index.md
│ │ │ ├── filevar/
│ │ │ │ ├── _demo/
│ │ │ │ │ └── _index.md
│ │ │ │ └── _index.md
│ │ │ ├── gcpruntimeconfig/
│ │ │ │ └── _index.md
│ │ │ ├── gcpsecretmanager/
│ │ │ │ └── _index.md
│ │ │ ├── hashivault/
│ │ │ │ └── _index.md
│ │ │ └── httpvar/
│ │ │ └── _index.md
│ │ ├── samples/
│ │ │ ├── appengine/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-blob/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-docstore/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-pubsub/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-runtimevar/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-secrets/
│ │ │ │ └── _index.md
│ │ │ ├── guestbook/
│ │ │ │ ├── _index.md
│ │ │ │ ├── aws/
│ │ │ │ │ └── provision_db/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── gcp/
│ │ │ │ │ ├── deploy/
│ │ │ │ │ │ └── _index.md
│ │ │ │ │ └── provision_db/
│ │ │ │ │ └── _index.md
│ │ │ │ └── localdb/
│ │ │ │ └── _index.md
│ │ │ ├── order/
│ │ │ │ └── _index.md
│ │ │ ├── server/
│ │ │ │ └── _index.md
│ │ │ └── tutorial/
│ │ │ └── _index.md
│ │ ├── secrets/
│ │ │ ├── _index.md
│ │ │ ├── awskms/
│ │ │ │ └── _index.md
│ │ │ ├── azurekeyvault/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── gcpkms/
│ │ │ │ └── _index.md
│ │ │ ├── hashivault/
│ │ │ │ └── _index.md
│ │ │ ├── localsecrets/
│ │ │ │ └── _index.md
│ │ │ └── vault/
│ │ │ └── _index.md
│ │ ├── server/
│ │ │ ├── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── health/
│ │ │ │ ├── _index.md
│ │ │ │ └── sqlhealth/
│ │ │ │ └── _index.md
│ │ │ ├── requestlog/
│ │ │ │ └── _index.md
│ │ │ ├── sdserver/
│ │ │ │ └── _index.md
│ │ │ └── xrayserver/
│ │ │ └── _index.md
│ │ ├── tests/
│ │ │ ├── aws/
│ │ │ │ └── app/
│ │ │ │ └── _index.md
│ │ │ ├── gcp/
│ │ │ │ └── app/
│ │ │ │ └── _index.md
│ │ │ └── internal/
│ │ │ └── testutil/
│ │ │ └── _index.md
│ │ └── tutorials/
│ │ ├── _index.md
│ │ ├── cli-uploader.md
│ │ ├── guestbook.md
│ │ └── order.md
│ ├── data/
│ │ └── examples.json
│ ├── gatherexamples/
│ │ ├── gatherexamples.go
│ │ ├── gatherexamples_test.go
│ │ └── run.sh
│ ├── go.mod
│ ├── go.sum
│ ├── layouts/
│ │ ├── 404.html
│ │ ├── _default/
│ │ │ ├── baseof.html
│ │ │ ├── li.html
│ │ │ ├── list.html
│ │ │ ├── single.html
│ │ │ └── sitemap.xml
│ │ ├── howto/
│ │ │ ├── li.html
│ │ │ └── list.html
│ │ ├── index.html
│ │ ├── partials/
│ │ │ ├── header-link.html
│ │ │ ├── hook_head_end.html
│ │ │ └── page-toc.html
│ │ ├── pkg/
│ │ │ ├── list.html
│ │ │ └── single.html
│ │ └── shortcodes/
│ │ ├── goexample.html
│ │ └── snippet.html
│ ├── listnewpkgs.sh
│ ├── makeimports.sh
│ └── static/
│ └── css/
│ ├── style.css
│ └── syntax.css
├── mysql/
│ ├── awsmysql/
│ │ ├── awsmysql.go
│ │ ├── awsmysql_test.go
│ │ ├── example_test.go
│ │ ├── main.tf
│ │ └── otel_test.go
│ ├── azuremysql/
│ │ ├── azuremysql.go
│ │ ├── azuremysql_test.go
│ │ ├── example_test.go
│ │ └── main.tf
│ ├── example_test.go
│ ├── gcpmysql/
│ │ ├── example_test.go
│ │ ├── gcpmysql.go
│ │ ├── gcpmysql_test.go
│ │ └── main.tf
│ ├── main.tf
│ ├── mysql.go
│ └── mysql_test.go
├── postgres/
│ ├── awspostgres/
│ │ ├── awspostgres.go
│ │ ├── awspostgres_test.go
│ │ ├── example_test.go
│ │ └── main.tf
│ ├── example_test.go
│ ├── gcppostgres/
│ │ ├── example_test.go
│ │ ├── gcppostgres.go
│ │ ├── gcppostgres_test.go
│ │ └── main.tf
│ ├── postgres.go
│ └── postgres_test.go
├── pubsub/
│ ├── acks_test.go
│ ├── awssnssqs/
│ │ ├── awssnssqs.go
│ │ ├── awssnssqs_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ ├── TestConformanceSNSTopic/
│ │ │ ├── TestAs/
│ │ │ │ ├── aws_test.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestBatching.replay
│ │ │ ├── TestCancelSendReceive.replay
│ │ │ ├── TestDoubleAck.replay
│ │ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ │ ├── TestMetadata.replay
│ │ │ ├── TestNack.replay
│ │ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ │ ├── TestNonUTF8MessageBody.replay
│ │ │ ├── TestSendReceive.replay
│ │ │ ├── TestSendReceiveJSON.replay
│ │ │ └── TestSendReceiveTwo.replay
│ │ ├── TestConformanceSNSTopicRaw/
│ │ │ ├── TestAs/
│ │ │ │ ├── aws_test.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestBatching.replay
│ │ │ ├── TestCancelSendReceive.replay
│ │ │ ├── TestDoubleAck.replay
│ │ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ │ ├── TestMetadata.replay
│ │ │ ├── TestNack.replay
│ │ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ │ ├── TestNonUTF8MessageBody.replay
│ │ │ ├── TestSendReceive.replay
│ │ │ ├── TestSendReceiveJSON.replay
│ │ │ └── TestSendReceiveTwo.replay
│ │ ├── TestConformanceSQSTopic/
│ │ │ ├── TestAs/
│ │ │ │ ├── aws_test.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestBatching.replay
│ │ │ ├── TestCancelSendReceive.replay
│ │ │ ├── TestDoubleAck.replay
│ │ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ │ ├── TestMetadata.replay
│ │ │ ├── TestNack.replay
│ │ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ │ ├── TestNonUTF8MessageBody.replay
│ │ │ ├── TestSendReceive.replay
│ │ │ ├── TestSendReceiveJSON.replay
│ │ │ └── TestSendReceiveTwo.replay
│ │ └── TestFIFO/
│ │ ├── TestSNSTopic/
│ │ │ ├── TestSendReceiveInvalidNoDeduplicationID.replay
│ │ │ ├── TestSendReceiveInvalidNoMessageGroupID.replay
│ │ │ └── TestSendReceiveValid.replay
│ │ └── TestSQSTopic/
│ │ ├── TestSendReceiveInvalidNoDeduplicationID.replay
│ │ ├── TestSendReceiveInvalidNoMessageGroupID.replay
│ │ └── TestSendReceiveValid.replay
│ ├── azuresb/
│ │ ├── azuresb.go
│ │ ├── azuresb_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── README
│ ├── batcher/
│ │ ├── batcher.go
│ │ └── batcher_test.go
│ ├── benchmark_test.go
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ └── drivertest.go
│ ├── example_test.go
│ ├── gcppubsub/
│ │ ├── example_test.go
│ │ ├── gcppubsub.go
│ │ ├── gcppubsub_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── gcp_test.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestBatching.replay
│ │ ├── TestCancelSendReceive.replay
│ │ ├── TestDoubleAck.replay
│ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ ├── TestMetadata.replay
│ │ ├── TestNack.replay
│ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ ├── TestNonUTF8MessageBody.replay
│ │ ├── TestSendReceive.replay
│ │ ├── TestSendReceiveJSON.replay
│ │ └── TestSendReceiveTwo.replay
│ ├── gcppubsubv2/
│ │ ├── example_test.go
│ │ ├── gcppubsub.go
│ │ └── gcppubsub_test.go
│ ├── kafkapubsub/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── kafka.go
│ │ ├── kafka_test.go
│ │ └── localkafka.sh
│ ├── mempubsub/
│ │ ├── conformance_test.go
│ │ ├── example_test.go
│ │ ├── mem.go
│ │ └── mem_test.go
│ ├── natspubsub/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── nats.go
│ │ └── nats_test.go
│ ├── pub_test.go
│ ├── pubsub.go
│ ├── pubsub_test.go
│ ├── rabbitpubsub/
│ │ ├── amqp.go
│ │ ├── doc.go
│ │ ├── example_test.go
│ │ ├── fake_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── localrabbit.sh
│ │ ├── rabbit.go
│ │ └── rabbit_test.go
│ └── sub_test.go
├── runtimevar/
│ ├── awsparamstore/
│ │ ├── awsparamstore.go
│ │ ├── awsparamstore_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── awssecretsmanager/
│ │ ├── awssecretsmanager.go
│ │ ├── awssecretsmanager_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestConformanceV2/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestDelete.replay
│ │ │ ├── TestInvalidJSON.replay
│ │ │ ├── TestJSON.replay
│ │ │ ├── TestNonExistentVariable.replay
│ │ │ ├── TestString.replay
│ │ │ ├── TestUpdate.replay
│ │ │ └── TestUpdateWithErrors.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── blobvar/
│ │ ├── blobvar.go
│ │ ├── blobvar_test.go
│ │ └── example_test.go
│ ├── constantvar/
│ │ ├── constantvar.go
│ │ ├── constantvar_test.go
│ │ └── example_test.go
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ └── drivertest.go
│ ├── etcdvar/
│ │ ├── etcdvar.go
│ │ ├── etcdvar_test.go
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── localetcd.sh
│ ├── example_openvariable_test.go
│ ├── example_test.go
│ ├── filevar/
│ │ ├── example_test.go
│ │ ├── filevar.go
│ │ └── filevar_test.go
│ ├── gcpruntimeconfig/
│ │ ├── example_test.go
│ │ ├── gcpruntimeconfig.go
│ │ ├── gcpruntimeconfig_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── gcpsecretmanager/
│ │ ├── example_test.go
│ │ ├── gcpsecretmanager.go
│ │ ├── gcpsecretmanager_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── hashivault/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── hashivault.go
│ │ ├── hashivault_test.go
│ │ └── localvault.sh
│ ├── httpvar/
│ │ ├── example_test.go
│ │ ├── httpvar.go
│ │ └── httpvar_test.go
│ ├── otel_test.go
│ ├── runtimevar.go
│ └── runtimevar_test.go
├── samples/
│ ├── appengine/
│ │ ├── .gcloudignore
│ │ ├── README.md
│ │ ├── app.yaml
│ │ └── helloworld.go
│ ├── go.mod
│ ├── go.sum
│ ├── gocdk-blob/
│ │ ├── blob.ct
│ │ ├── main.go
│ │ └── main_test.go
│ ├── gocdk-docstore/
│ │ ├── docstore.ct
│ │ ├── main.go
│ │ └── main_test.go
│ ├── gocdk-pubsub/
│ │ ├── main.go
│ │ ├── main_test.go
│ │ └── pubsub.ct
│ ├── gocdk-runtimevar/
│ │ ├── main.go
│ │ ├── main_test.go
│ │ └── runtimevar.ct
│ ├── gocdk-secrets/
│ │ ├── main.go
│ │ ├── main_test.go
│ │ └── secrets.ct
│ ├── guestbook/
│ │ ├── README.md
│ │ ├── aws/
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ ├── provision_db/
│ │ │ │ └── main.go
│ │ │ └── variables.tf
│ │ ├── azure/
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
│ │ ├── blobs/
│ │ │ └── motd.txt
│ │ ├── gcp/
│ │ │ ├── .gcloudignore
│ │ │ ├── Dockerfile
│ │ │ ├── deploy/
│ │ │ │ └── main.go
│ │ │ ├── guestbook.yaml.in
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ ├── provision_db/
│ │ │ │ └── main.go
│ │ │ └── variables.tf
│ │ ├── inject_aws.go
│ │ ├── inject_azure.go
│ │ ├── inject_gcp.go
│ │ ├── inject_local.go
│ │ ├── localdb/
│ │ │ └── main.go
│ │ ├── main.go
│ │ ├── roles.sql
│ │ ├── schema.sql
│ │ ├── telemetry.go
│ │ └── wire_gen.go
│ ├── order/
│ │ ├── common.go
│ │ ├── frontend.go
│ │ ├── frontend_test.go
│ │ ├── index.html
│ │ ├── list.htmlt
│ │ ├── order-form.htmlt
│ │ ├── order.go
│ │ ├── processor.go
│ │ ├── processor_test.go
│ │ ├── style.css
│ │ └── testdata/
│ │ ├── bad-image
│ │ └── cat1
│ ├── server/
│ │ └── main.go
│ ├── tutorial/
│ │ ├── README.md
│ │ └── main.go
│ └── wire/
│ └── README.md
├── secrets/
│ ├── awskms/
│ │ ├── example_test.go
│ │ ├── kms.go
│ │ ├── kms_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_function.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDecryptMalformedError.replay
│ │ ├── TestEncryptDecrypt.replay
│ │ ├── TestMultipleEncryptionsNotEqual.replay
│ │ └── TestMultipleKeys.replay
│ ├── azurekeyvault/
│ │ ├── akv.go
│ │ ├── akv_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_function.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDecryptMalformedError.replay
│ │ ├── TestEncryptDecrypt.replay
│ │ ├── TestMultipleEncryptionsNotEqual.replay
│ │ └── TestMultipleKeys.replay
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ └── drivertest.go
│ ├── example_openkeeper_test.go
│ ├── example_test.go
│ ├── gcpkms/
│ │ ├── example_test.go
│ │ ├── kms.go
│ │ ├── kms_test.go
│ │ └── testdata/
│ │ ├── TestAdditionalAuthenticatedData.replay
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_function.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDecryptMalformedError.replay
│ │ ├── TestEncryptDecrypt.replay
│ │ ├── TestMultipleEncryptionsNotEqual.replay
│ │ └── TestMultipleKeys.replay
│ ├── hashivault/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── localvault.sh
│ │ ├── vault.go
│ │ └── vault_test.go
│ ├── localsecrets/
│ │ ├── example_test.go
│ │ ├── localsecrets.go
│ │ └── localsecrets_test.go
│ ├── secrets.go
│ └── secrets_test.go
├── server/
│ ├── driver/
│ │ └── driver.go
│ ├── example_test.go
│ ├── health/
│ │ ├── health.go
│ │ ├── health_test.go
│ │ └── sqlhealth/
│ │ ├── sqlhealth.go
│ │ └── sqlhealth_test.go
│ ├── requestlog/
│ │ ├── ncsa.go
│ │ ├── ncsa_test.go
│ │ ├── requestlog.go
│ │ ├── requestlog_test.go
│ │ ├── stackdriver.go
│ │ └── stackdriver_test.go
│ ├── sdserver/
│ │ └── server.go
│ ├── server.go
│ ├── server_test.go
│ └── xrayserver/
│ └── server.go
└── wire/
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .codecov.yml
================================================
codecov:
# Removed hardcoded token for security reasons.
# The token should be set via CI/CD secrets instead.
# Example for GitHub Actions:
# - name: Upload coverage to Codecov
# run: codecov -t ${{ secrets.CODECOV_TOKEN }}
#
# See: https://docs.codecov.com/docs/adding-the-codecov-token
coverage:
status:
project:
default:
target: 0
threshold: null
base: auto
patch:
default:
target: 0
threshold: null
base: auto
================================================
FILE: .gitattributes
================================================
* 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
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
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.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
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.
================================================
FILE: .github/pull_request_template.md
================================================
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.
================================================
FILE: .github/workflows/tests.yml
================================================
# 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.26.x]
include:
- go-version: 1.25.x
os: ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v6
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
================================================
FILE: .gitignore
================================================
# 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
================================================
FILE: AUTHORS
================================================
# 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 <submission email address>
# Individual's name <submission email address> <email2> <emailN>
# See CONTRIBUTORS for the meaning of multiple email addresses.
# Please keep the list sorted.
Andrey Chernov <chernov.andrey1988@gmail.com>
Ben Hinchley <benjaminhinchley@gmail.com>
Boris Popovschi <zyqsempai@mail.ru>
Gerasimos (Makis) Maropoulos <kataras2006@hotmail.com> <omicronmakis@gmail.com>
Google LLC
Oleg Kovalov <iamolegkovalov@gmail.com>
oliverpool <oliverpool@hotmail.fr>
Sendil Kumar N <sendilkumarn@live.com> <sendil.kn@gmail.com>
Steve Jiang <steve.jiang@gmail.com>
Vishal Saroopchand <Vishal.Saroopchand@microsoft.com> <vsaroopchand@hotmail.com>
Zachary Romero <zacromero3@gmail.com>
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# 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
================================================
FILE: CONTRIBUTING.md
================================================
# 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
<https://cla.developers.google.com/> 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.
================================================
FILE: CONTRIBUTORS
================================================
# 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 <submission email address>
# Individual's name <submission email address> <email2> <emailN>
#
# 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 <chernov.andrey1988@gmail.com>
Ben Hinchley <benjaminhinchley@gmail.com>
Boris Popovschi <zyqsempai@mail.ru>
Chris Lewis <cflewis@google.com> <cflewis@golang.org> <c@chris.to>
Eno Compton <enocom@google.com>
Gerasimos (Makis) Maropoulos <kataras2006@hotmail.com> <omicronmakis@gmail.com>
Issac Trotts <issactrotts@google.com> <issac.trotts@gmail.com>
Oleg Kovalov <iamolegkovalov@gmail.com>
oliverpool <oliverpool@hotmail.fr>
Robert van Gent <rvangent@google.com> <vangent@gmail.com>
Ross Light <light@google.com> <ross@zombiezen.com>
Sendil Kumar N <sendilkumarn@live.com> <sendil.kn@gmail.com>
Steve Jiang <steve.jiang@gmail.com>
Tuo Shan <shantuo@google.com> <sturbo89@gmail.com>
Tyler Bui-Palsulich <26876514+tbpg@users.noreply.github.com>
Vishal Saroopchand <Vishal.Saroopchand@microsoft.com> <vsaroopchand@hotmail.com>
Vivek Sekhar <vsekhar@google.com>
Zachary Romero <zacromero3@gmail.com>
================================================
FILE: LICENSE
================================================
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.
================================================
FILE: README.md
================================================
# The Go Cloud Development Kit (Go CDK)
_Write once, run on any cloud ☁️_
[](https://github.com/google/go-cloud/actions)
[](https://goreportcard.com/report/github.com/google/go-cloud)
[][PkgGoDev]
[](https://codecov.io/gh/google/go-cloud)

[](https://opensource.org/licenses/Apache-2.0)
<p align="center">
<img width="509" height="276" src="internal/website/static/go-cdk-logo-gopherblue.png" alt="">
</p>
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]
[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.
================================================
FILE: allmodules
================================================
# 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
runtimevar/hashivault yes
samples no
secrets/hashivault yes
================================================
FILE: aws/aws.go
================================================
// 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"
"strings"
"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"
)
const (
requestChecksumCalculationParamKey = "request_checksum_calculation"
responseChecksumValidationParamKey = "response_checksum_validation"
)
// parseRequestChecksumCalculation parses request checksum calculation mode values.
// Supports AWS SDK documented values: "when_supported", "when_required".
func parseRequestChecksumCalculation(value string) (aws.RequestChecksumCalculation, error) {
switch strings.ToLower(value) {
case "when_supported":
return aws.RequestChecksumCalculationWhenSupported, nil
case "when_required":
return aws.RequestChecksumCalculationWhenRequired, nil
default:
return aws.RequestChecksumCalculationWhenSupported, fmt.Errorf("invalid value for %q: %q. Valid values are: when_supported, when_required", requestChecksumCalculationParamKey, value)
}
}
// parseResponseChecksumValidation parses response checksum validation mode values.
// Supports AWS SDK documented values: "when_supported", "when_required".
func parseResponseChecksumValidation(value string) (aws.ResponseChecksumValidation, error) {
switch strings.ToLower(value) {
case "when_supported":
return aws.ResponseChecksumValidationWhenSupported, nil
case "when_required":
return aws.ResponseChecksumValidationWhenRequired, nil
default:
return aws.ResponseChecksumValidationWhenSupported, fmt.Errorf("invalid value for %q: %q. Valid values are: when_supported, when_required", responseChecksumValidationParamKey, value)
}
}
// NewDefaultV2Config returns a aws.Config for AWS SDK v2, using the default options.
func NewDefaultV2Config(ctx context.Context) (aws.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.
// - request_checksum_calculation: Request checksum calculation mode (when_supported, when_required)
// - response_checksum_validation: Response checksum validation mode (when_supported, when_required)
func V2ConfigFromURLParams(ctx context.Context, q url.Values) (aws.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 aws.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 aws.Config{}, fmt.Errorf("invalid value for dualstack: %w", err)
}
if dualStack {
opts = append(opts, config.WithUseDualStackEndpoint(aws.DualStackEndpointStateEnabled))
}
case "fips":
fips, err := strconv.ParseBool(value)
if err != nil {
return aws.Config{}, fmt.Errorf("invalid value for fips: %w", err)
}
if fips {
opts = append(opts, config.WithUseFIPSEndpoint(aws.FIPSEndpointStateEnabled))
}
case "rate_limiter_capacity":
var err error
rateLimitCapacity, err = strconv.ParseInt(value, 10, 32)
if err != nil {
return aws.Config{}, fmt.Errorf("invalid value for capacity: %w", err)
}
case "anonymous":
anon, err := strconv.ParseBool(value)
if err != nil {
return aws.Config{}, fmt.Errorf("invalid value for anonymous: %w", err)
}
if anon {
opts = append(opts, config.WithCredentialsProvider(aws.AnonymousCredentials{}))
}
case requestChecksumCalculationParamKey:
value, err := parseRequestChecksumCalculation(value)
if err != nil {
return aws.Config{}, err
}
opts = append(opts, config.WithRequestChecksumCalculation(value))
case responseChecksumValidationParamKey:
value, err := parseResponseChecksumValidation(value)
if err != nil {
return aws.Config{}, err
}
opts = append(opts, config.WithResponseChecksumValidation(value))
case "awssdk":
// ignore, should be handled before this
default:
return aws.Config{}, fmt.Errorf("unknown query parameter %q", param)
}
}
if endpoint != "" {
customResolver := aws.EndpointResolverWithOptionsFunc(
func(service, region string, options ...any) (aws.Endpoint, error) {
return aws.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() aws.Retryer {
return retry.NewStandard(func(so *retry.StandardOptions) {
so.RateLimiter = rateLimiter
})
}))
return config.LoadDefaultConfig(ctx, opts...)
}
================================================
FILE: aws/aws_test.go
================================================
// 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"
"strings"
"testing"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/retry"
gcaws "gocloud.dev/aws"
)
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 *aws.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: &aws.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"}},
},
{
name: "Request checksum calculation when_supported",
query: url.Values{"request_checksum_calculation": {"when_supported"}},
},
{
name: "Request checksum calculation when_required",
query: url.Values{"request_checksum_calculation": {"when_required"}},
},
{
name: "Response checksum validation when_supported",
query: url.Values{"response_checksum_validation": {"when_supported"}},
},
{
name: "Response checksum validation when_required",
query: url.Values{"response_checksum_validation": {"when_required"}},
},
{
name: "Both checksum parameters",
query: url.Values{"request_checksum_calculation": {"when_required"}, "response_checksum_validation": {"when_supported"}},
},
{
name: "Invalid request checksum value",
query: url.Values{"request_checksum_calculation": {"invalid"}},
wantErr: true,
},
{
name: "Invalid response checksum value",
query: url.Values{"response_checksum_validation": {"invalid"}},
wantErr: true,
},
{
name: "Empty request checksum value",
query: url.Values{"request_checksum_calculation": {""}},
wantErr: true,
},
{
name: "Empty response checksum value",
query: url.Values{"response_checksum_validation": {""}},
wantErr: true,
},
{
name: "Uppercase request checksum",
query: url.Values{"request_checksum_calculation": {"WHEN_SUPPORTED"}},
},
{
name: "Mixed case response checksum",
query: url.Values{"response_checksum_validation": {"When_Required"}},
},
// 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)
}
// Check checksum configuration based on query parameters
if test.query.Has("request_checksum_calculation") {
expectedValue := test.query.Get("request_checksum_calculation")
var expectedChecksum aws.RequestChecksumCalculation
switch strings.ToLower(expectedValue) {
case "when_supported":
expectedChecksum = aws.RequestChecksumCalculationWhenSupported
case "when_required":
expectedChecksum = aws.RequestChecksumCalculationWhenRequired
}
if got.RequestChecksumCalculation != expectedChecksum {
t.Errorf("got RequestChecksumCalculation %v, want %v", got.RequestChecksumCalculation, expectedChecksum)
}
}
if test.query.Has("response_checksum_validation") {
expectedValue := test.query.Get("response_checksum_validation")
var expectedChecksum aws.ResponseChecksumValidation
switch strings.ToLower(expectedValue) {
case "when_supported":
expectedChecksum = aws.ResponseChecksumValidationWhenSupported
case "when_required":
expectedChecksum = aws.ResponseChecksumValidationWhenRequired
}
if got.ResponseChecksumValidation != expectedChecksum {
t.Errorf("got ResponseChecksumValidation %v, want %v", got.ResponseChecksumValidation, expectedChecksum)
}
}
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().(*retry.Standard)
if !ok {
t.Errorf("expected a standard retryer, got %v, expected retry.Standard", r)
}
})
}
}
================================================
FILE: aws/awscloud/awscloud.go
================================================
// 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"
"gocloud.dev/aws"
"gocloud.dev/aws/rds"
"gocloud.dev/blob/s3blob"
"gocloud.dev/docstore/awsdynamodb/v2"
"gocloud.dev/pubsub/awssnssqs"
"gocloud.dev/runtimevar/awsparamstore"
"gocloud.dev/secrets/awskms"
"gocloud.dev/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.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,
)
================================================
FILE: aws/awscloud/example_test.go
================================================
// 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"
"gocloud.dev/aws/awscloud"
"gocloud.dev/server"
"gocloud.dev/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!")
}
================================================
FILE: aws/rds/rds.go
================================================
// 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
}
================================================
FILE: azure/azurecloud/azurecloud.go
================================================
// 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"
"gocloud.dev/blob/azureblob"
"gocloud.dev/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,
)
================================================
FILE: azure/azuredb/azuredb.go
================================================
// 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
}
================================================
FILE: blob/azureblob/azureblob.go
================================================
// 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<hex>__".
// 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<hex>__". 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/google/wire"
"gocloud.dev/blob"
"gocloud.dev/blob/driver"
"gocloud.dev/gcerrors"
"gocloud.dev/internal/escape"
"gocloud.dev/internal/gcerr"
"gocloud.dev/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
)
// ptrVal returns the value pointed to by p, or the zero value if p is nil.
func ptrVal[T any](p *T) (v T) {
if p != nil {
v = *p
}
return
}
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.SplitSeq(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 "<protocol>://<account name>.<domain>"
// 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 <account name> 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: ptrVal(blobDownloadResponse.ContentType),
Size: getSize(blobDownloadResponse.ContentLength, ptrVal(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 {
var rErr *azcore.ResponseError
if errors.As(err, &rErr) {
switch bloberror.Code(rErr.ErrorCode) {
case bloberror.AuthenticationFailed:
return gcerrors.PermissionDenied
case bloberror.BlobAlreadyExists,
bloberror.ConditionNotMet,
bloberror.TargetConditionNotMet,
bloberror.SourceConditionNotMet:
// the documented error code is a variation of "ConditionNotMet", but "BlobAlreadyExists" has also been observed
return gcerrors.FailedPrecondition
case bloberror.BlobNotFound:
return gcerrors.NotFound
}
if rErr.StatusCode == http.StatusNotFound {
return gcerrors.NotFound
}
}
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: ptrVal(blobPropertiesResponse.CacheControl),
ContentDisposition: ptrVal(blobPropertiesResponse.ContentDisposition),
ContentEncoding: ptrVal(blobPropertiesResponse.ContentEncoding),
ContentLanguage: ptrVal(blobPropertiesResponse.ContentLanguage),
ContentType: ptrVal(blobPropertiesResponse.ContentType),
Size: ptrVal(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 {
page.Objects = append(page.Objects, &driver.ListObject{
Key: unescapeKey(ptrVal(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 {
page.Objects = append(page.Objects, &driver.ListObject{
Key: unescapeKey(ptrVal(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
}
================================================
FILE: blob/azureblob/azureblob_test.go
================================================
// 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"
"gocloud.dev/blob"
"gocloud.dev/blob/driver"
"gocloud.dev/blob/drivertest"
"gocloud.dev/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)
}
}
}
================================================
FILE: blob/azureblob/example_test.go
================================================
// 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"
"gocloud.dev/blob"
"gocloud.dev/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()
}
================================================
FILE: blob/azureblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay
================================================
{
"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": ""
}
}
]
}
================================================
FILE: blob/azureblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay
================================================
{
"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": ""
}
}
]
}
================================================
FILE: blob/azureblob/testdata/TestConformance/TestAttributes.replay
================================================
{
"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": ""
}
}
]
}
================================================
FILE: blob/azureblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay
================================================
{
"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": ""
}
}
]
}
================================================
FILE: blob/azureblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay
================================================
{
"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="
}
}
]
}
================================================
FILE: blob/azureblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay
================================================
{
"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="
}
}
]
}
================================================
FILE: blob/azureblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay
================================================
{
"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": [
"DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD
gitextract_d66nvpyk/
├── .codecov.yml
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── pull_request_template.md
│ └── workflows/
│ └── tests.yml
├── .gitignore
├── AUTHORS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── CONTRIBUTORS
├── LICENSE
├── README.md
├── allmodules
├── aws/
│ ├── aws.go
│ ├── aws_test.go
│ ├── awscloud/
│ │ ├── awscloud.go
│ │ └── example_test.go
│ └── rds/
│ └── rds.go
├── azure/
│ ├── azurecloud/
│ │ └── azurecloud.go
│ └── azuredb/
│ └── azuredb.go
├── blob/
│ ├── azureblob/
│ │ ├── azureblob.go
│ │ ├── azureblob_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ ├── TestAttributes.replay
│ │ ├── TestCanceledWrite/
│ │ │ ├── BlobExists.replay
│ │ │ ├── EmptyContentType.replay
│ │ │ └── NonEmptyContentType.replay
│ │ ├── TestConcurrentWriteAndRead.replay
│ │ ├── TestCopy/
│ │ │ ├── NonExistentSourceFails.replay
│ │ │ └── Works.replay
│ │ ├── TestDelete/
│ │ │ ├── NonExistentFails.replay
│ │ │ └── Works.replay
│ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ ├── TestIfNotExist.replay
│ │ ├── TestKeys/
│ │ │ ├── ascii-1.replay
│ │ │ ├── ascii-2.replay
│ │ │ ├── ascii-3.replay
│ │ │ ├── ascii-4.replay
│ │ │ ├── ascii-5.replay
│ │ │ ├── ascii-6.replay
│ │ │ ├── ascii-7.replay
│ │ │ ├── ascii-8.replay
│ │ │ ├── backslashes.replay
│ │ │ ├── dotdotbackslash.replay
│ │ │ ├── dotdotslash.replay
│ │ │ ├── fwdslashes.replay
│ │ │ ├── non-UTF8_fails.replay
│ │ │ ├── quote.replay
│ │ │ ├── repeatedbackslashes.replay
│ │ │ ├── repeatedfwdslashes.replay
│ │ │ ├── spaces.replay
│ │ │ ├── startwithdigit.replay
│ │ │ └── unicode.replay
│ │ ├── TestList/
│ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ ├── by_1.replay
│ │ │ ├── by_2.replay
│ │ │ ├── by_3.replay
│ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ ├── no_objects.replay
│ │ │ └── no_pagination.replay
│ │ ├── TestListDelimiters/
│ │ │ ├── abc.replay
│ │ │ ├── backslash.replay
│ │ │ └── fwdslash.replay
│ │ ├── TestListWeirdKeys.replay
│ │ ├── TestMD5.replay
│ │ ├── TestMetadata/
│ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ ├── empty.replay
│ │ │ ├── empty_key_fails.replay
│ │ │ ├── non-utf8_metadata_key.replay
│ │ │ ├── non-utf8_metadata_value.replay
│ │ │ ├── valid_metadata.replay
│ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ └── weird_metadata_keys.replay
│ │ ├── TestNonexistentBucket.replay
│ │ ├── TestRead/
│ │ │ ├── length_0_read.replay
│ │ │ ├── negative_offset_fails.replay
│ │ │ ├── read_a_part_in_middle.replay
│ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ ├── read_in_full.replay
│ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ └── read_of_nonexistent_key_fails.replay
│ │ ├── TestSignedURL.replay
│ │ ├── TestUploadDownload.replay
│ │ └── TestWrite/
│ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ ├── Content_md5_did_not_match.replay
│ │ ├── Content_md5_match.replay
│ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ ├── invalid_ContentType_fails.replay
│ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ ├── write_to_empty_key_fails.replay
│ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ ├── blob.go
│ ├── blob_fs.go
│ ├── blob_fs_test.go
│ ├── blob_iter_test.go
│ ├── blob_reader_test.go
│ ├── blob_test.go
│ ├── blob_writer_test.go
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ ├── bindata.go
│ │ └── drivertest.go
│ ├── example_openbucket_test.go
│ ├── example_test.go
│ ├── fileblob/
│ │ ├── attrs.go
│ │ ├── example_test.go
│ │ ├── fileblob.go
│ │ └── fileblob_test.go
│ ├── gcsblob/
│ │ ├── example_test.go
│ │ ├── gcsblob.go
│ │ ├── gcsblob_test.go
│ │ ├── iam.go
│ │ ├── iam_test.go
│ │ └── testdata/
│ │ ├── TestBeforeReadNonExistentKey.replay
│ │ ├── TestConformance/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ │ ├── TestAttributes.replay
│ │ │ ├── TestCanceledWrite/
│ │ │ │ ├── BlobExists.replay
│ │ │ │ ├── EmptyContentType.replay
│ │ │ │ └── NonEmptyContentType.replay
│ │ │ ├── TestConcurrentWriteAndRead.replay
│ │ │ ├── TestCopy/
│ │ │ │ ├── NonExistentSourceFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDelete/
│ │ │ │ ├── NonExistentFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ │ ├── TestIfNotExist.replay
│ │ │ ├── TestKeys/
│ │ │ │ ├── ascii-1.replay
│ │ │ │ ├── ascii-2.replay
│ │ │ │ ├── ascii-3.replay
│ │ │ │ ├── ascii-4.replay
│ │ │ │ ├── ascii-5.replay
│ │ │ │ ├── ascii-6.replay
│ │ │ │ ├── ascii-7.replay
│ │ │ │ ├── ascii-8.replay
│ │ │ │ ├── backslashes.replay
│ │ │ │ ├── dotdotbackslash.replay
│ │ │ │ ├── dotdotslash.replay
│ │ │ │ ├── fwdslashes.replay
│ │ │ │ ├── non-UTF8_fails.replay
│ │ │ │ ├── quote.replay
│ │ │ │ ├── repeatedbackslashes.replay
│ │ │ │ ├── repeatedfwdslashes.replay
│ │ │ │ ├── spaces.replay
│ │ │ │ ├── startwithdigit.replay
│ │ │ │ └── unicode.replay
│ │ │ ├── TestList/
│ │ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ │ ├── by_1.replay
│ │ │ │ ├── by_2.replay
│ │ │ │ ├── by_3.replay
│ │ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ │ ├── no_objects.replay
│ │ │ │ └── no_pagination.replay
│ │ │ ├── TestListDelimiters/
│ │ │ │ ├── abc.replay
│ │ │ │ ├── backslash.replay
│ │ │ │ └── fwdslash.replay
│ │ │ ├── TestListWeirdKeys.replay
│ │ │ ├── TestMD5.replay
│ │ │ ├── TestMetadata/
│ │ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ │ ├── empty.replay
│ │ │ │ ├── empty_key_fails.replay
│ │ │ │ ├── non-utf8_metadata_key.replay
│ │ │ │ ├── non-utf8_metadata_value.replay
│ │ │ │ ├── valid_metadata.replay
│ │ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ │ └── weird_metadata_keys.replay
│ │ │ ├── TestNonexistentBucket.replay
│ │ │ ├── TestRead/
│ │ │ │ ├── length_0_read.replay
│ │ │ │ ├── negative_offset_fails.replay
│ │ │ │ ├── read_a_part_in_middle.replay
│ │ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ │ ├── read_in_full.replay
│ │ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ │ └── read_of_nonexistent_key_fails.replay
│ │ │ ├── TestSignedURL.replay
│ │ │ ├── TestUploadDownload.replay
│ │ │ └── TestWrite/
│ │ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ │ ├── Content_md5_did_not_match.replay
│ │ │ ├── Content_md5_match.replay
│ │ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ │ ├── invalid_ContentType_fails.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ │ ├── write_to_empty_key_fails.replay
│ │ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ │ ├── TestOpenBucket/
│ │ │ ├── empty_bucket_name_results_in_error.replay
│ │ │ └── success.replay
│ │ └── TestPreconditions.replay
│ ├── memblob/
│ │ ├── example_test.go
│ │ ├── memblob.go
│ │ └── memblob_test.go
│ ├── otel_test.go
│ ├── s3blob/
│ │ ├── example_test.go
│ │ ├── s3blob.go
│ │ ├── s3blob_test.go
│ │ └── testdata/
│ │ ├── TestConformance/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ │ ├── TestAttributes.replay
│ │ │ ├── TestCanceledWrite/
│ │ │ │ ├── BlobExists.replay
│ │ │ │ ├── EmptyContentType.replay
│ │ │ │ └── NonEmptyContentType.replay
│ │ │ ├── TestConcurrentWriteAndRead.replay
│ │ │ ├── TestCopy/
│ │ │ │ ├── NonExistentSourceFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDelete/
│ │ │ │ ├── NonExistentFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ │ ├── TestIfNotExist.replay
│ │ │ ├── TestKeys/
│ │ │ │ ├── ascii-1.replay
│ │ │ │ ├── ascii-2.replay
│ │ │ │ ├── ascii-3.replay
│ │ │ │ ├── ascii-4.replay
│ │ │ │ ├── ascii-5.replay
│ │ │ │ ├── ascii-6.replay
│ │ │ │ ├── ascii-7.replay
│ │ │ │ ├── ascii-8.replay
│ │ │ │ ├── backslashes.replay
│ │ │ │ ├── dotdotbackslash.replay
│ │ │ │ ├── dotdotslash.replay
│ │ │ │ ├── fwdslashes.replay
│ │ │ │ ├── non-UTF8_fails.replay
│ │ │ │ ├── quote.replay
│ │ │ │ ├── repeatedbackslashes.replay
│ │ │ │ ├── repeatedfwdslashes.replay
│ │ │ │ ├── spaces.replay
│ │ │ │ ├── startwithdigit.replay
│ │ │ │ └── unicode.replay
│ │ │ ├── TestList/
│ │ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ │ ├── by_1.replay
│ │ │ │ ├── by_2.replay
│ │ │ │ ├── by_3.replay
│ │ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ │ ├── no_objects.replay
│ │ │ │ └── no_pagination.replay
│ │ │ ├── TestListDelimiters/
│ │ │ │ ├── abc.replay
│ │ │ │ ├── backslash.replay
│ │ │ │ └── fwdslash.replay
│ │ │ ├── TestListWeirdKeys.replay
│ │ │ ├── TestMD5.replay
│ │ │ ├── TestMetadata/
│ │ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ │ ├── empty.replay
│ │ │ │ ├── empty_key_fails.replay
│ │ │ │ ├── non-utf8_metadata_key.replay
│ │ │ │ ├── non-utf8_metadata_value.replay
│ │ │ │ ├── valid_metadata.replay
│ │ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ │ └── weird_metadata_keys.replay
│ │ │ ├── TestNonexistentBucket.replay
│ │ │ ├── TestRead/
│ │ │ │ ├── length_0_read.replay
│ │ │ │ ├── negative_offset_fails.replay
│ │ │ │ ├── read_a_part_in_middle.replay
│ │ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ │ ├── read_in_full.replay
│ │ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ │ └── read_of_nonexistent_key_fails.replay
│ │ │ ├── TestSignedURL.replay
│ │ │ ├── TestUploadDownload.replay
│ │ │ └── TestWrite/
│ │ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ │ ├── Content_md5_did_not_match.replay
│ │ │ ├── Content_md5_match.replay
│ │ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ │ ├── invalid_ContentType_fails.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ │ ├── write_to_empty_key_fails.replay
│ │ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ │ ├── TestConformanceUsingLegacyList/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ └── verify_ContentLanguage_can_be_written_and_read_through_As.replay
│ │ │ ├── TestAttributes.replay
│ │ │ ├── TestCanceledWrite/
│ │ │ │ ├── BlobExists.replay
│ │ │ │ ├── EmptyContentType.replay
│ │ │ │ └── NonEmptyContentType.replay
│ │ │ ├── TestConcurrentWriteAndRead.replay
│ │ │ ├── TestCopy/
│ │ │ │ ├── NonExistentSourceFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDelete/
│ │ │ │ ├── NonExistentFails.replay
│ │ │ │ └── Works.replay
│ │ │ ├── TestDirsWithCharactersBeforeDelimiter.replay
│ │ │ ├── TestIfNotExist.replay
│ │ │ ├── TestKeys/
│ │ │ │ ├── ascii-1.replay
│ │ │ │ ├── ascii-2.replay
│ │ │ │ ├── ascii-3.replay
│ │ │ │ ├── ascii-4.replay
│ │ │ │ ├── ascii-5.replay
│ │ │ │ ├── ascii-6.replay
│ │ │ │ ├── ascii-7.replay
│ │ │ │ ├── ascii-8.replay
│ │ │ │ ├── backslashes.replay
│ │ │ │ ├── dotdotbackslash.replay
│ │ │ │ ├── dotdotslash.replay
│ │ │ │ ├── fwdslashes.replay
│ │ │ │ ├── non-UTF8_fails.replay
│ │ │ │ ├── quote.replay
│ │ │ │ ├── repeatedbackslashes.replay
│ │ │ │ ├── repeatedfwdslashes.replay
│ │ │ │ ├── spaces.replay
│ │ │ │ ├── startwithdigit.replay
│ │ │ │ └── unicode.replay
│ │ │ ├── TestList/
│ │ │ │ ├── PaginationConsistencyAfterDelete.replay
│ │ │ │ ├── PaginationConsistencyAfterInsert.replay
│ │ │ │ ├── by_1.replay
│ │ │ │ ├── by_2.replay
│ │ │ │ ├── by_3.replay
│ │ │ │ ├── exactly_1_object_due_to_prefix.replay
│ │ │ │ ├── no_objects.replay
│ │ │ │ └── no_pagination.replay
│ │ │ ├── TestListDelimiters/
│ │ │ │ ├── abc.replay
│ │ │ │ ├── backslash.replay
│ │ │ │ └── fwdslash.replay
│ │ │ ├── TestListWeirdKeys.replay
│ │ │ ├── TestMD5.replay
│ │ │ ├── TestMetadata/
│ │ │ │ ├── duplicate_case-insensitive_key_fails.replay
│ │ │ │ ├── empty.replay
│ │ │ │ ├── empty_key_fails.replay
│ │ │ │ ├── non-utf8_metadata_key.replay
│ │ │ │ ├── non-utf8_metadata_value.replay
│ │ │ │ ├── valid_metadata.replay
│ │ │ │ ├── valid_metadata_with_content_type.replay
│ │ │ │ ├── valid_metadata_with_empty_body.replay
│ │ │ │ └── weird_metadata_keys.replay
│ │ │ ├── TestNonexistentBucket.replay
│ │ │ ├── TestRead/
│ │ │ │ ├── length_0_read.replay
│ │ │ │ ├── negative_offset_fails.replay
│ │ │ │ ├── read_a_part_in_middle.replay
│ │ │ │ ├── read_from_positive_offset_to_end.replay
│ │ │ │ ├── read_in_full.replay
│ │ │ │ ├── read_in_full_with_negative_length_not_-1.replay
│ │ │ │ └── read_of_nonexistent_key_fails.replay
│ │ │ ├── TestSignedURL.replay
│ │ │ ├── TestUploadDownload.replay
│ │ │ └── TestWrite/
│ │ │ ├── ContentType_is_discovered_if_not_provided.replay
│ │ │ ├── ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay
│ │ │ ├── Content_md5_did_not_match,_blob_existed.replay
│ │ │ ├── Content_md5_did_not_match.replay
│ │ │ ├── Content_md5_match.replay
│ │ │ ├── a_large_jpg_file_gets_a_ContentType.replay
│ │ │ ├── a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay
│ │ │ ├── a_small_text_file_gets_a_ContentType.replay
│ │ │ ├── invalid_ContentType_fails.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob,_blob_existed.replay
│ │ │ ├── no_write_then_close_results_in_empty_blob.replay
│ │ │ ├── write_to_empty_key_fails.replay
│ │ │ └── write_with_explicit_ContentType_overrides_discovery.replay
│ │ └── TestOpenBucket/
│ │ ├── empty_bucket_name_results_in_error.replay
│ │ ├── empty_bucket_name_results_in_error_V2.replay
│ │ ├── success.replay
│ │ └── success_V2.replay
│ └── wrapped_bucket_test.go
├── contrib/
│ └── upgrade-dependency.sh
├── doc.go
├── docstore/
│ ├── awsdynamodb/
│ │ └── v2/
│ │ ├── benchmark_test.go
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── create_tables.sh
│ │ ├── dynamo.go
│ │ ├── dynamo_test.go
│ │ ├── example_test.go
│ │ ├── query.go
│ │ ├── query_test.go
│ │ ├── testdata/
│ │ │ ├── TestConformance/
│ │ │ │ ├── ActionsOnStructNoRev.replay
│ │ │ │ ├── ActionsWithCompositeID.replay
│ │ │ │ ├── As/
│ │ │ │ │ ├── verify_As.replay
│ │ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ │ ├── AtomicWrites.replay
│ │ │ │ ├── AtomicWritesFail.replay
│ │ │ │ ├── BeforeDo.replay
│ │ │ │ ├── BeforeQuery.replay
│ │ │ │ ├── Create.replay
│ │ │ │ ├── Data.replay
│ │ │ │ ├── Delete.replay
│ │ │ │ ├── ExampleInDoc.replay
│ │ │ │ ├── Get.replay
│ │ │ │ ├── GetQuery.replay
│ │ │ │ ├── GetQueryKeyField.replay
│ │ │ │ ├── MultipleActions.replay
│ │ │ │ ├── Proto.replay
│ │ │ │ ├── Put.replay
│ │ │ │ ├── Replace.replay
│ │ │ │ ├── SerializeRevision.replay
│ │ │ │ └── Update.replay
│ │ │ └── TestQueryErrors.replay
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── doc.go
│ ├── docstore.go
│ ├── docstore_test.go
│ ├── driver/
│ │ ├── actionkind_string.go
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── compare.go
│ │ ├── compare_test.go
│ │ ├── document.go
│ │ ├── document_test.go
│ │ ├── driver.go
│ │ ├── util.go
│ │ └── util_test.go
│ ├── drivertest/
│ │ ├── driverbenchmark.go
│ │ ├── drivertest.go
│ │ └── util.go
│ ├── example_test.go
│ ├── gcpfirestore/
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── create_indexes.sh
│ │ ├── example_test.go
│ │ ├── fs.go
│ │ ├── fs_test.go
│ │ ├── native_codec_test.go
│ │ ├── query.go
│ │ ├── query_test.go
│ │ ├── testdata/
│ │ │ └── TestConformance/
│ │ │ ├── ActionsOnStructNoRev.replay
│ │ │ ├── ActionsWithCompositeID.replay
│ │ │ ├── As/
│ │ │ │ ├── verify_As.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── AtomicWrites.replay
│ │ │ ├── AtomicWritesFail.replay
│ │ │ ├── BeforeDo.replay
│ │ │ ├── BeforeQuery.replay
│ │ │ ├── Create.replay
│ │ │ ├── Data.replay
│ │ │ ├── Delete.replay
│ │ │ ├── ExampleInDoc.replay
│ │ │ ├── Get.replay
│ │ │ ├── GetQuery.replay
│ │ │ ├── GetQueryKeyField.replay
│ │ │ ├── MultipleActions.replay
│ │ │ ├── Proto.replay
│ │ │ ├── Put.replay
│ │ │ ├── Query.replay
│ │ │ ├── Replace.replay
│ │ │ ├── SerializeRevision.replay
│ │ │ └── Update.replay
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── internal/
│ │ └── fields/
│ │ ├── README.md
│ │ ├── fields.go
│ │ ├── fields_test.go
│ │ ├── fold.go
│ │ └── fold_test.go
│ ├── memdocstore/
│ │ ├── codec.go
│ │ ├── codec_test.go
│ │ ├── example_test.go
│ │ ├── mem.go
│ │ ├── mem_test.go
│ │ ├── query.go
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── mongodocstore/
│ │ ├── awsdocdb/
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
│ │ ├── codec.go
│ │ ├── cosmos_test.go
│ │ ├── docdb_test.go
│ │ ├── docker-compose.yml
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── localmongo.sh
│ │ ├── mongo.go
│ │ ├── mongo_test.go
│ │ ├── query.go
│ │ ├── testdata/
│ │ │ └── README
│ │ ├── urls.go
│ │ └── urls_test.go
│ ├── otel_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── urls.go
│ └── urls_test.go
├── gcerrors/
│ ├── errors.go
│ └── errors_test.go
├── gcp/
│ ├── cloudsql/
│ │ └── cloudsql.go
│ ├── gcp.go
│ ├── gcp_test.go
│ └── gcpcloud/
│ ├── example_test.go
│ └── gcpcloud.go
├── go.mod
├── go.sum
├── gocloud.code-workspace
├── internal/
│ ├── docs/
│ │ ├── README.md
│ │ ├── design.md
│ │ ├── pubsub/
│ │ │ └── design.md
│ │ └── release.md
│ ├── escape/
│ │ ├── escape.go
│ │ └── escape_test.go
│ ├── gcerr/
│ │ ├── errorcode_string.go
│ │ ├── gcerr.go
│ │ └── gcerr_test.go
│ ├── openurl/
│ │ ├── openurl.go
│ │ └── openurl_test.go
│ ├── otel/
│ │ ├── metrics.go
│ │ ├── trace.go
│ │ └── trace_test.go
│ ├── releasehelper/
│ │ ├── releasehelper.go
│ │ └── releasehelper_test.go
│ ├── retry/
│ │ ├── retry.go
│ │ └── retry_test.go
│ ├── testing/
│ │ ├── alldeps
│ │ ├── check_mod_tidy.sh
│ │ ├── deploywebsite.sh
│ │ ├── git_tag_modules.sh
│ │ ├── gomodcleanup.sh
│ │ ├── listdeps.sh
│ │ ├── oteltest/
│ │ │ ├── diff.go
│ │ │ ├── exporter.go
│ │ │ └── init.go
│ │ ├── runchecks.sh
│ │ ├── setup/
│ │ │ └── setup.go
│ │ ├── start_local_deps.sh
│ │ ├── terraform/
│ │ │ └── terraform.go
│ │ ├── test-summary/
│ │ │ ├── test-summary.go
│ │ │ └── test-summary_test.go
│ │ └── update_deps.sh
│ ├── useragent/
│ │ └── useragent.go
│ └── website/
│ ├── README.md
│ ├── archetypes/
│ │ ├── default.md
│ │ └── howto.md
│ ├── config.toml
│ ├── content/
│ │ ├── _index.md
│ │ ├── aws/
│ │ │ ├── _index.md
│ │ │ ├── awscloud/
│ │ │ │ └── _index.md
│ │ │ └── rds/
│ │ │ └── _index.md
│ │ ├── azure/
│ │ │ ├── azurecloud/
│ │ │ │ └── _index.md
│ │ │ └── azuredb/
│ │ │ └── _index.md
│ │ ├── blob/
│ │ │ ├── _index.md
│ │ │ ├── azureblob/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── fileblob/
│ │ │ │ └── _index.md
│ │ │ ├── gcsblob/
│ │ │ │ └── _index.md
│ │ │ ├── memblob/
│ │ │ │ └── _index.md
│ │ │ └── s3blob/
│ │ │ └── _index.md
│ │ ├── concepts/
│ │ │ ├── _index.md
│ │ │ ├── as.md
│ │ │ ├── structure/
│ │ │ │ └── index.md
│ │ │ └── urls.md
│ │ ├── docstore/
│ │ │ ├── _index.md
│ │ │ ├── awsdynamodb/
│ │ │ │ └── v2/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── dynamodocstore/
│ │ │ │ └── _index.md
│ │ │ ├── firedocstore/
│ │ │ │ └── _index.md
│ │ │ ├── gcpfirestore/
│ │ │ │ └── _index.md
│ │ │ ├── internal/
│ │ │ │ └── fields/
│ │ │ │ └── _index.md
│ │ │ ├── memdocstore/
│ │ │ │ └── _index.md
│ │ │ └── mongodocstore/
│ │ │ └── _index.md
│ │ ├── gcerrors/
│ │ │ └── _index.md
│ │ ├── gcp/
│ │ │ ├── _index.md
│ │ │ ├── cloudsql/
│ │ │ │ └── _index.md
│ │ │ └── gcpcloud/
│ │ │ └── _index.md
│ │ ├── health/
│ │ │ ├── _index.md
│ │ │ └── sqlhealth/
│ │ │ └── _index.md
│ │ ├── howto/
│ │ │ ├── _index.md
│ │ │ ├── blob/
│ │ │ │ └── _index.md
│ │ │ ├── docstore/
│ │ │ │ └── _index.md
│ │ │ ├── pubsub/
│ │ │ │ ├── _index.md
│ │ │ │ ├── publish.md
│ │ │ │ └── subscribe.md
│ │ │ ├── runtimevar/
│ │ │ │ └── _index.md
│ │ │ ├── secrets/
│ │ │ │ └── _index.md
│ │ │ ├── server/
│ │ │ │ └── _index.md
│ │ │ └── sql/
│ │ │ └── _index.md
│ │ ├── internal/
│ │ │ ├── batcher/
│ │ │ │ └── _index.md
│ │ │ ├── escape/
│ │ │ │ └── _index.md
│ │ │ ├── gcerr/
│ │ │ │ └── _index.md
│ │ │ ├── oc/
│ │ │ │ └── _index.md
│ │ │ ├── openurl/
│ │ │ │ └── _index.md
│ │ │ ├── otel/
│ │ │ │ └── _index.md
│ │ │ ├── releasehelper/
│ │ │ │ └── _index.md
│ │ │ ├── retry/
│ │ │ │ └── _index.md
│ │ │ ├── testing/
│ │ │ │ ├── _index.md
│ │ │ │ ├── cmdtest/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── octest/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── oteltest/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── setup/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── terraform/
│ │ │ │ │ └── _index.md
│ │ │ │ └── test-summary/
│ │ │ │ └── _index.md
│ │ │ ├── trace/
│ │ │ │ └── _index.md
│ │ │ ├── useragent/
│ │ │ │ └── _index.md
│ │ │ └── website/
│ │ │ └── gatherexamples/
│ │ │ └── _index.md
│ │ ├── mysql/
│ │ │ ├── _index.md
│ │ │ ├── awsmysql/
│ │ │ │ └── _index.md
│ │ │ ├── azuremysql/
│ │ │ │ └── _index.md
│ │ │ ├── cloudmysql/
│ │ │ │ └── _index.md
│ │ │ ├── gcpmysql/
│ │ │ │ └── _index.md
│ │ │ └── rdsmysql/
│ │ │ └── _index.md
│ │ ├── postgres/
│ │ │ ├── _index.md
│ │ │ ├── awspostgres/
│ │ │ │ └── _index.md
│ │ │ ├── cloudpostgres/
│ │ │ │ └── _index.md
│ │ │ ├── gcppostgres/
│ │ │ │ └── _index.md
│ │ │ └── rdspostgres/
│ │ │ └── _index.md
│ │ ├── pubsub/
│ │ │ ├── _index.md
│ │ │ ├── awssnssqs/
│ │ │ │ └── _index.md
│ │ │ ├── azurepubsub/
│ │ │ │ └── _index.md
│ │ │ ├── azuresb/
│ │ │ │ └── _index.md
│ │ │ ├── batcher/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── gcppubsub/
│ │ │ │ └── _index.md
│ │ │ ├── gcppubsubv2/
│ │ │ │ └── _index.md
│ │ │ ├── kafkapubsub/
│ │ │ │ └── _index.md
│ │ │ ├── mempubsub/
│ │ │ │ └── _index.md
│ │ │ ├── natspubsub/
│ │ │ │ └── _index.md
│ │ │ └── rabbitpubsub/
│ │ │ └── _index.md
│ │ ├── requestlog/
│ │ │ └── _index.md
│ │ ├── runtimevar/
│ │ │ ├── _index.md
│ │ │ ├── awsparamstore/
│ │ │ │ └── _index.md
│ │ │ ├── awssecretsmanager/
│ │ │ │ └── _index.md
│ │ │ ├── blobvar/
│ │ │ │ └── _index.md
│ │ │ ├── constantvar/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── etcdvar/
│ │ │ │ └── _index.md
│ │ │ ├── filevar/
│ │ │ │ ├── _demo/
│ │ │ │ │ └── _index.md
│ │ │ │ └── _index.md
│ │ │ ├── gcpruntimeconfig/
│ │ │ │ └── _index.md
│ │ │ ├── gcpsecretmanager/
│ │ │ │ └── _index.md
│ │ │ ├── hashivault/
│ │ │ │ └── _index.md
│ │ │ └── httpvar/
│ │ │ └── _index.md
│ │ ├── samples/
│ │ │ ├── appengine/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-blob/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-docstore/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-pubsub/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-runtimevar/
│ │ │ │ └── _index.md
│ │ │ ├── gocdk-secrets/
│ │ │ │ └── _index.md
│ │ │ ├── guestbook/
│ │ │ │ ├── _index.md
│ │ │ │ ├── aws/
│ │ │ │ │ └── provision_db/
│ │ │ │ │ └── _index.md
│ │ │ │ ├── gcp/
│ │ │ │ │ ├── deploy/
│ │ │ │ │ │ └── _index.md
│ │ │ │ │ └── provision_db/
│ │ │ │ │ └── _index.md
│ │ │ │ └── localdb/
│ │ │ │ └── _index.md
│ │ │ ├── order/
│ │ │ │ └── _index.md
│ │ │ ├── server/
│ │ │ │ └── _index.md
│ │ │ └── tutorial/
│ │ │ └── _index.md
│ │ ├── secrets/
│ │ │ ├── _index.md
│ │ │ ├── awskms/
│ │ │ │ └── _index.md
│ │ │ ├── azurekeyvault/
│ │ │ │ └── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── drivertest/
│ │ │ │ └── _index.md
│ │ │ ├── gcpkms/
│ │ │ │ └── _index.md
│ │ │ ├── hashivault/
│ │ │ │ └── _index.md
│ │ │ ├── localsecrets/
│ │ │ │ └── _index.md
│ │ │ └── vault/
│ │ │ └── _index.md
│ │ ├── server/
│ │ │ ├── _index.md
│ │ │ ├── driver/
│ │ │ │ └── _index.md
│ │ │ ├── health/
│ │ │ │ ├── _index.md
│ │ │ │ └── sqlhealth/
│ │ │ │ └── _index.md
│ │ │ ├── requestlog/
│ │ │ │ └── _index.md
│ │ │ ├── sdserver/
│ │ │ │ └── _index.md
│ │ │ └── xrayserver/
│ │ │ └── _index.md
│ │ ├── tests/
│ │ │ ├── aws/
│ │ │ │ └── app/
│ │ │ │ └── _index.md
│ │ │ ├── gcp/
│ │ │ │ └── app/
│ │ │ │ └── _index.md
│ │ │ └── internal/
│ │ │ └── testutil/
│ │ │ └── _index.md
│ │ └── tutorials/
│ │ ├── _index.md
│ │ ├── cli-uploader.md
│ │ ├── guestbook.md
│ │ └── order.md
│ ├── data/
│ │ └── examples.json
│ ├── gatherexamples/
│ │ ├── gatherexamples.go
│ │ ├── gatherexamples_test.go
│ │ └── run.sh
│ ├── go.mod
│ ├── go.sum
│ ├── layouts/
│ │ ├── 404.html
│ │ ├── _default/
│ │ │ ├── baseof.html
│ │ │ ├── li.html
│ │ │ ├── list.html
│ │ │ ├── single.html
│ │ │ └── sitemap.xml
│ │ ├── howto/
│ │ │ ├── li.html
│ │ │ └── list.html
│ │ ├── index.html
│ │ ├── partials/
│ │ │ ├── header-link.html
│ │ │ ├── hook_head_end.html
│ │ │ └── page-toc.html
│ │ ├── pkg/
│ │ │ ├── list.html
│ │ │ └── single.html
│ │ └── shortcodes/
│ │ ├── goexample.html
│ │ └── snippet.html
│ ├── listnewpkgs.sh
│ ├── makeimports.sh
│ └── static/
│ └── css/
│ ├── style.css
│ └── syntax.css
├── mysql/
│ ├── awsmysql/
│ │ ├── awsmysql.go
│ │ ├── awsmysql_test.go
│ │ ├── example_test.go
│ │ ├── main.tf
│ │ └── otel_test.go
│ ├── azuremysql/
│ │ ├── azuremysql.go
│ │ ├── azuremysql_test.go
│ │ ├── example_test.go
│ │ └── main.tf
│ ├── example_test.go
│ ├── gcpmysql/
│ │ ├── example_test.go
│ │ ├── gcpmysql.go
│ │ ├── gcpmysql_test.go
│ │ └── main.tf
│ ├── main.tf
│ ├── mysql.go
│ └── mysql_test.go
├── postgres/
│ ├── awspostgres/
│ │ ├── awspostgres.go
│ │ ├── awspostgres_test.go
│ │ ├── example_test.go
│ │ └── main.tf
│ ├── example_test.go
│ ├── gcppostgres/
│ │ ├── example_test.go
│ │ ├── gcppostgres.go
│ │ ├── gcppostgres_test.go
│ │ └── main.tf
│ ├── postgres.go
│ └── postgres_test.go
├── pubsub/
│ ├── acks_test.go
│ ├── awssnssqs/
│ │ ├── awssnssqs.go
│ │ ├── awssnssqs_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ ├── TestConformanceSNSTopic/
│ │ │ ├── TestAs/
│ │ │ │ ├── aws_test.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestBatching.replay
│ │ │ ├── TestCancelSendReceive.replay
│ │ │ ├── TestDoubleAck.replay
│ │ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ │ ├── TestMetadata.replay
│ │ │ ├── TestNack.replay
│ │ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ │ ├── TestNonUTF8MessageBody.replay
│ │ │ ├── TestSendReceive.replay
│ │ │ ├── TestSendReceiveJSON.replay
│ │ │ └── TestSendReceiveTwo.replay
│ │ ├── TestConformanceSNSTopicRaw/
│ │ │ ├── TestAs/
│ │ │ │ ├── aws_test.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestBatching.replay
│ │ │ ├── TestCancelSendReceive.replay
│ │ │ ├── TestDoubleAck.replay
│ │ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ │ ├── TestMetadata.replay
│ │ │ ├── TestNack.replay
│ │ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ │ ├── TestNonUTF8MessageBody.replay
│ │ │ ├── TestSendReceive.replay
│ │ │ ├── TestSendReceiveJSON.replay
│ │ │ └── TestSendReceiveTwo.replay
│ │ ├── TestConformanceSQSTopic/
│ │ │ ├── TestAs/
│ │ │ │ ├── aws_test.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestBatching.replay
│ │ │ ├── TestCancelSendReceive.replay
│ │ │ ├── TestDoubleAck.replay
│ │ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ │ ├── TestMetadata.replay
│ │ │ ├── TestNack.replay
│ │ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ │ ├── TestNonUTF8MessageBody.replay
│ │ │ ├── TestSendReceive.replay
│ │ │ ├── TestSendReceiveJSON.replay
│ │ │ └── TestSendReceiveTwo.replay
│ │ └── TestFIFO/
│ │ ├── TestSNSTopic/
│ │ │ ├── TestSendReceiveInvalidNoDeduplicationID.replay
│ │ │ ├── TestSendReceiveInvalidNoMessageGroupID.replay
│ │ │ └── TestSendReceiveValid.replay
│ │ └── TestSQSTopic/
│ │ ├── TestSendReceiveInvalidNoDeduplicationID.replay
│ │ ├── TestSendReceiveInvalidNoMessageGroupID.replay
│ │ └── TestSendReceiveValid.replay
│ ├── azuresb/
│ │ ├── azuresb.go
│ │ ├── azuresb_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── README
│ ├── batcher/
│ │ ├── batcher.go
│ │ └── batcher_test.go
│ ├── benchmark_test.go
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ └── drivertest.go
│ ├── example_test.go
│ ├── gcppubsub/
│ │ ├── example_test.go
│ │ ├── gcppubsub.go
│ │ ├── gcppubsub_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── gcp_test.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestBatching.replay
│ │ ├── TestCancelSendReceive.replay
│ │ ├── TestDoubleAck.replay
│ │ ├── TestErrorOnReceiveFromClosedSubscription.replay
│ │ ├── TestErrorOnSendToClosedTopic.replay
│ │ ├── TestMetadata.replay
│ │ ├── TestNack.replay
│ │ ├── TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay
│ │ ├── TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay
│ │ ├── TestNonUTF8MessageBody.replay
│ │ ├── TestSendReceive.replay
│ │ ├── TestSendReceiveJSON.replay
│ │ └── TestSendReceiveTwo.replay
│ ├── gcppubsubv2/
│ │ ├── example_test.go
│ │ ├── gcppubsub.go
│ │ └── gcppubsub_test.go
│ ├── kafkapubsub/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── kafka.go
│ │ ├── kafka_test.go
│ │ └── localkafka.sh
│ ├── mempubsub/
│ │ ├── conformance_test.go
│ │ ├── example_test.go
│ │ ├── mem.go
│ │ └── mem_test.go
│ ├── natspubsub/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── nats.go
│ │ └── nats_test.go
│ ├── pub_test.go
│ ├── pubsub.go
│ ├── pubsub_test.go
│ ├── rabbitpubsub/
│ │ ├── amqp.go
│ │ ├── doc.go
│ │ ├── example_test.go
│ │ ├── fake_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── localrabbit.sh
│ │ ├── rabbit.go
│ │ └── rabbit_test.go
│ └── sub_test.go
├── runtimevar/
│ ├── awsparamstore/
│ │ ├── awsparamstore.go
│ │ ├── awsparamstore_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── awssecretsmanager/
│ │ ├── awssecretsmanager.go
│ │ ├── awssecretsmanager_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestConformanceV2/
│ │ │ ├── TestAs/
│ │ │ │ ├── verify_As.replay
│ │ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ │ ├── TestDelete.replay
│ │ │ ├── TestInvalidJSON.replay
│ │ │ ├── TestJSON.replay
│ │ │ ├── TestNonExistentVariable.replay
│ │ │ ├── TestString.replay
│ │ │ ├── TestUpdate.replay
│ │ │ └── TestUpdateWithErrors.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── blobvar/
│ │ ├── blobvar.go
│ │ ├── blobvar_test.go
│ │ └── example_test.go
│ ├── constantvar/
│ │ ├── constantvar.go
│ │ ├── constantvar_test.go
│ │ └── example_test.go
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ └── drivertest.go
│ ├── etcdvar/
│ │ ├── etcdvar.go
│ │ ├── etcdvar_test.go
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── localetcd.sh
│ ├── example_openvariable_test.go
│ ├── example_test.go
│ ├── filevar/
│ │ ├── example_test.go
│ │ ├── filevar.go
│ │ └── filevar_test.go
│ ├── gcpruntimeconfig/
│ │ ├── example_test.go
│ │ ├── gcpruntimeconfig.go
│ │ ├── gcpruntimeconfig_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── gcpsecretmanager/
│ │ ├── example_test.go
│ │ ├── gcpsecretmanager.go
│ │ ├── gcpsecretmanager_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDelete.replay
│ │ ├── TestInvalidJSON.replay
│ │ ├── TestJSON.replay
│ │ ├── TestNonExistentVariable.replay
│ │ ├── TestString.replay
│ │ ├── TestUpdate.replay
│ │ └── TestUpdateWithErrors.replay
│ ├── hashivault/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── hashivault.go
│ │ ├── hashivault_test.go
│ │ └── localvault.sh
│ ├── httpvar/
│ │ ├── example_test.go
│ │ ├── httpvar.go
│ │ └── httpvar_test.go
│ ├── otel_test.go
│ ├── runtimevar.go
│ └── runtimevar_test.go
├── samples/
│ ├── appengine/
│ │ ├── .gcloudignore
│ │ ├── README.md
│ │ ├── app.yaml
│ │ └── helloworld.go
│ ├── go.mod
│ ├── go.sum
│ ├── gocdk-blob/
│ │ ├── blob.ct
│ │ ├── main.go
│ │ └── main_test.go
│ ├── gocdk-docstore/
│ │ ├── docstore.ct
│ │ ├── main.go
│ │ └── main_test.go
│ ├── gocdk-pubsub/
│ │ ├── main.go
│ │ ├── main_test.go
│ │ └── pubsub.ct
│ ├── gocdk-runtimevar/
│ │ ├── main.go
│ │ ├── main_test.go
│ │ └── runtimevar.ct
│ ├── gocdk-secrets/
│ │ ├── main.go
│ │ ├── main_test.go
│ │ └── secrets.ct
│ ├── guestbook/
│ │ ├── README.md
│ │ ├── aws/
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ ├── provision_db/
│ │ │ │ └── main.go
│ │ │ └── variables.tf
│ │ ├── azure/
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
│ │ ├── blobs/
│ │ │ └── motd.txt
│ │ ├── gcp/
│ │ │ ├── .gcloudignore
│ │ │ ├── Dockerfile
│ │ │ ├── deploy/
│ │ │ │ └── main.go
│ │ │ ├── guestbook.yaml.in
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ ├── provision_db/
│ │ │ │ └── main.go
│ │ │ └── variables.tf
│ │ ├── inject_aws.go
│ │ ├── inject_azure.go
│ │ ├── inject_gcp.go
│ │ ├── inject_local.go
│ │ ├── localdb/
│ │ │ └── main.go
│ │ ├── main.go
│ │ ├── roles.sql
│ │ ├── schema.sql
│ │ ├── telemetry.go
│ │ └── wire_gen.go
│ ├── order/
│ │ ├── common.go
│ │ ├── frontend.go
│ │ ├── frontend_test.go
│ │ ├── index.html
│ │ ├── list.htmlt
│ │ ├── order-form.htmlt
│ │ ├── order.go
│ │ ├── processor.go
│ │ ├── processor_test.go
│ │ ├── style.css
│ │ └── testdata/
│ │ ├── bad-image
│ │ └── cat1
│ ├── server/
│ │ └── main.go
│ ├── tutorial/
│ │ ├── README.md
│ │ └── main.go
│ └── wire/
│ └── README.md
├── secrets/
│ ├── awskms/
│ │ ├── example_test.go
│ │ ├── kms.go
│ │ ├── kms_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_function.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDecryptMalformedError.replay
│ │ ├── TestEncryptDecrypt.replay
│ │ ├── TestMultipleEncryptionsNotEqual.replay
│ │ └── TestMultipleKeys.replay
│ ├── azurekeyvault/
│ │ ├── akv.go
│ │ ├── akv_test.go
│ │ ├── example_test.go
│ │ └── testdata/
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_function.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDecryptMalformedError.replay
│ │ ├── TestEncryptDecrypt.replay
│ │ ├── TestMultipleEncryptionsNotEqual.replay
│ │ └── TestMultipleKeys.replay
│ ├── driver/
│ │ └── driver.go
│ ├── drivertest/
│ │ └── drivertest.go
│ ├── example_openkeeper_test.go
│ ├── example_test.go
│ ├── gcpkms/
│ │ ├── example_test.go
│ │ ├── kms.go
│ │ ├── kms_test.go
│ │ └── testdata/
│ │ ├── TestAdditionalAuthenticatedData.replay
│ │ └── TestConformance/
│ │ ├── TestAs/
│ │ │ ├── verify_As_function.replay
│ │ │ └── verify_As_returns_false_when_passed_nil.replay
│ │ ├── TestDecryptMalformedError.replay
│ │ ├── TestEncryptDecrypt.replay
│ │ ├── TestMultipleEncryptionsNotEqual.replay
│ │ └── TestMultipleKeys.replay
│ ├── hashivault/
│ │ ├── example_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── localvault.sh
│ │ ├── vault.go
│ │ └── vault_test.go
│ ├── localsecrets/
│ │ ├── example_test.go
│ │ ├── localsecrets.go
│ │ └── localsecrets_test.go
│ ├── secrets.go
│ └── secrets_test.go
├── server/
│ ├── driver/
│ │ └── driver.go
│ ├── example_test.go
│ ├── health/
│ │ ├── health.go
│ │ ├── health_test.go
│ │ └── sqlhealth/
│ │ ├── sqlhealth.go
│ │ └── sqlhealth_test.go
│ ├── requestlog/
│ │ ├── ncsa.go
│ │ ├── ncsa_test.go
│ │ ├── requestlog.go
│ │ ├── requestlog_test.go
│ │ ├── stackdriver.go
│ │ └── stackdriver_test.go
│ ├── sdserver/
│ │ └── server.go
│ ├── server.go
│ ├── server_test.go
│ └── xrayserver/
│ └── server.go
└── wire/
└── README.md
Showing preview only (344K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3929 symbols across 294 files)
FILE: aws/aws.go
constant requestChecksumCalculationParamKey (line 32) | requestChecksumCalculationParamKey = "request_checksum_calculation"
constant responseChecksumValidationParamKey (line 33) | responseChecksumValidationParamKey = "response_checksum_validation"
function parseRequestChecksumCalculation (line 38) | func parseRequestChecksumCalculation(value string) (aws.RequestChecksumC...
function parseResponseChecksumValidation (line 51) | func parseResponseChecksumValidation(value string) (aws.ResponseChecksum...
function NewDefaultV2Config (line 63) | func NewDefaultV2Config(ctx context.Context) (aws.Config, error) {
function V2ConfigFromURLParams (line 90) | func V2ConfigFromURLParams(ctx context.Context, q url.Values) (aws.Confi...
FILE: aws/aws_test.go
function TestV2ConfigFromURLParams (line 29) | func TestV2ConfigFromURLParams(t *testing.T) {
FILE: aws/awscloud/example_test.go
function Example (line 33) | func Example() {
function setup (line 59) | func setup(ctx context.Context) (*server.Server, func(), error) {
function greet (line 74) | func greet(w http.ResponseWriter, req *http.Request) {
FILE: aws/rds/rds.go
type CertPoolProvider (line 38) | type CertPoolProvider interface
constant caBundleURL (line 43) | caBundleURL = "https://truststore.pki.rds.amazonaws.com/global/global-bu...
type CertFetcher (line 47) | type CertFetcher struct
method RDSCertPool (line 55) | func (cf *CertFetcher) RDSCertPool(ctx context.Context) (*x509.CertPoo...
method Fetch (line 68) | func (cf *CertFetcher) Fetch(ctx context.Context) ([]*x509.Certificate...
FILE: azure/azuredb/azuredb.go
constant caBundleURL (line 29) | caBundleURL = "https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot....
type CertPoolProvider (line 32) | type CertPoolProvider interface
type CertFetcher (line 38) | type CertFetcher struct
method AzureCertPool (line 46) | func (cf *CertFetcher) AzureCertPool(ctx context.Context) (*x509.CertP...
method Fetch (line 59) | func (cf *CertFetcher) Fetch(ctx context.Context) ([]*x509.Certificate...
FILE: blob/azureblob/azureblob.go
constant defaultPageSize (line 124) | defaultPageSize = 1000
constant defaultUploadBuffers (line 125) | defaultUploadBuffers = 5
constant defaultUploadBlockSize (line 126) | defaultUploadBlockSize = 8 * 1024 * 1024
function ptrVal (line 130) | func ptrVal[T any](p *T) (v T) {
function init (line 137) | func init() {
type Options (line 149) | type Options struct
type ServiceURL (line 152) | type ServiceURL
type ContainerName (line 155) | type ContainerName
type ServiceURLOptions (line 158) | type ServiceURLOptions struct
method withOverrides (line 230) | func (o *ServiceURLOptions) withOverrides(urlValues url.Values) (*Serv...
function NewDefaultServiceURLOptions (line 195) | func NewDefaultServiceURLOptions() *ServiceURLOptions {
function NewServiceURL (line 275) | func NewServiceURL(opts *ServiceURLOptions) (ServiceURL, error) {
type lazyOpener (line 308) | type lazyOpener struct
method OpenBucketURL (line 313) | func (o *lazyOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*...
type credTypeEnumT (line 325) | type credTypeEnumT
constant credTypeDefault (line 328) | credTypeDefault credTypeEnumT = iota
constant credTypeSharedKey (line 329) | credTypeSharedKey
constant credTypeSASViaNone (line 330) | credTypeSASViaNone
constant credTypeConnectionString (line 331) | credTypeConnectionString
type credInfoT (line 334) | type credInfoT struct
method NewClient (line 370) | func (i *credInfoT) NewClient(svcURL ServiceURL, containerName Contain...
function newCredInfoFromEnv (line 345) | func newCredInfoFromEnv() *credInfoT {
constant Scheme (line 405) | Scheme = "azblob"
type URLOpener (line 416) | type URLOpener struct
method OpenBucketURL (line 429) | func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*b...
type bucket (line 448) | type bucket struct
method Close (line 486) | func (b *bucket) Close() error {
method Copy (line 491) | func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts...
method Delete (line 537) | func (b *bucket) Delete(ctx context.Context, key string) error {
method NewRangeReader (line 573) | func (b *bucket) NewRangeReader(ctx context.Context, key string, offse...
method As (line 638) | func (b *bucket) As(i any) bool {
method ErrorAs (line 648) | func (b *bucket) ErrorAs(err error, i any) bool {
method ErrorCode (line 659) | func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode {
method Attributes (line 689) | func (b *bucket) Attributes(ctx context.Context, key string) (*driver....
method ListPaged (line 733) | func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptio...
method SignedURL (line 815) | func (b *bucket) SignedURL(ctx context.Context, key string, opts *driv...
method NewTypedWriter (line 900) | func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType ...
function NewDefaultClient (line 456) | func NewDefaultClient(svcURL ServiceURL, containerName ContainerName) (*...
function OpenBucket (line 464) | func OpenBucket(ctx context.Context, client *container.Client, opts *Opt...
function openBucket (line 472) | func openBucket(ctx context.Context, client *container.Client, opts *Opt...
type reader (line 545) | type reader struct
method Read (line 551) | func (r *reader) Read(p []byte) (int, error) {
method Close (line 555) | func (r *reader) Close() error {
method Attributes (line 559) | func (r *reader) Attributes() *driver.ReaderAttributes {
method As (line 563) | func (r *reader) As(i any) bool {
function getSize (line 617) | func getSize(contentLength *int64, contentRange string) int64 {
type writer (line 852) | type writer struct
method Write (line 975) | func (w *writer) Write(p []byte) (int, error) {
method Upload (line 992) | func (w *writer) Upload(r io.Reader) error {
method open (line 1001) | func (w *writer) open(r io.Reader, closePipeOnError bool) {
method Close (line 1021) | func (w *writer) Close() error {
function escapeKey (line 872) | func escapeKey(key string, isPrefix bool) string {
function unescapeKey (line 895) | func unescapeKey(key string) string {
FILE: blob/azureblob/azureblob_test.go
constant bucketName (line 59) | bucketName = "go-cloud-bucket"
constant accountName (line 60) | accountName = "gocloudblobtests"
type harness (line 63) | type harness struct
method HTTPClient (line 117) | func (h *harness) HTTPClient() *http.Client {
method MakeDriver (line 121) | func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, erro...
method MakeDriverForNonexistentBucket (line 129) | func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) ...
method Close (line 137) | func (h *harness) Close() {
function newHarness (line 69) | func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, ...
type requestInterceptor (line 104) | type requestInterceptor struct
method RoundTrip (line 108) | func (ri *requestInterceptor) RoundTrip(req *http.Request) (*http.Resp...
function TestConformance (line 141) | func TestConformance(t *testing.T) {
function BenchmarkAzureblob (line 147) | func BenchmarkAzureblob(b *testing.B) {
type verifyContentLanguage (line 170) | type verifyContentLanguage struct
method Name (line 172) | func (verifyContentLanguage) Name() string {
method BucketCheck (line 176) | func (verifyContentLanguage) BucketCheck(b *blob.Bucket) error {
method ErrorCheck (line 184) | func (verifyContentLanguage) ErrorCheck(b *blob.Bucket, err error) err...
method BeforeRead (line 188) | func (verifyContentLanguage) BeforeRead(as func(any) bool) error {
method BeforeWrite (line 196) | func (verifyContentLanguage) BeforeWrite(as func(any) bool) error {
method BeforeCopy (line 205) | func (verifyContentLanguage) BeforeCopy(as func(any) bool) error {
method BeforeList (line 213) | func (verifyContentLanguage) BeforeList(as func(any) bool) error {
method BeforeSign (line 221) | func (verifyContentLanguage) BeforeSign(as func(any) bool) error {
method AttributesCheck (line 229) | func (verifyContentLanguage) AttributesCheck(attrs *blob.Attributes) e...
method ReaderCheck (line 240) | func (verifyContentLanguage) ReaderCheck(r *blob.Reader) error {
method ListObjectCheck (line 251) | func (verifyContentLanguage) ListObjectCheck(o *blob.ListObject) error {
function TestOpenBucket (line 269) | func TestOpenBucket(t *testing.T) {
function TestOpenerFromEnv (line 313) | func TestOpenerFromEnv(t *testing.T) {
function TestNewServiceURL (line 463) | func TestNewServiceURL(t *testing.T) {
function TestOpenBucketFromURL (line 635) | func TestOpenBucketFromURL(t *testing.T) {
FILE: blob/azureblob/example_test.go
function ExampleOpenBucket (line 25) | func ExampleOpenBucket() {
function Example_openBucketFromURL (line 71) | func Example_openBucketFromURL() {
FILE: blob/blob.go
type Reader (line 98) | type Reader struct
method Read (line 116) | func (r *Reader) Read(p []byte) (int, error) {
method Seek (line 158) | func (r *Reader) Seek(offset int64, whence int) (int64, error) {
method Close (line 197) | func (r *Reader) Close() error {
method ContentType (line 212) | func (r *Reader) ContentType() string {
method ModTime (line 217) | func (r *Reader) ModTime() time.Time {
method Size (line 222) | func (r *Reader) Size() int64 {
method As (line 230) | func (r *Reader) As(i any) bool {
method WriteTo (line 239) | func (r *Reader) WriteTo(w io.Writer) (int64, error) {
method downloadAndClose (line 258) | func (r *Reader) downloadAndClose(w io.Writer) (err error) {
function readFromWriteTo (line 280) | func readFromWriteTo(r io.Reader, w io.Writer) (int64, int64, error) {
type Attributes (line 306) | type Attributes struct
method As (line 350) | func (a *Attributes) As(i any) bool {
type Writer (line 361) | type Writer struct
method Write (line 397) | func (w *Writer) Write(p []byte) (int, error) {
method Close (line 435) | func (w *Writer) Close() (err error) {
method open (line 474) | func (w *Writer) open(p []byte) (int, error) {
method write (line 488) | func (w *Writer) write(p []byte) (int, error) {
method ReadFrom (line 498) | func (w *Writer) ReadFrom(r io.Reader) (int64, error) {
method uploadAndClose (line 517) | func (w *Writer) uploadAndClose(r io.Reader) (err error) {
constant sniffLen (line 390) | sniffLen = 512
type ListOptions (line 541) | type ListOptions struct
type ListIterator (line 568) | type ListIterator struct
method Next (line 577) | func (i *ListIterator) Next(ctx context.Context) (*ListObject, error) {
method All (line 657) | func (i *ListIterator) All(ctx context.Context) (iter.Seq2[*ListObject...
type errorState (line 615) | type errorState struct
method Done (line 621) | func (es *errorState) Done() {
method Set (line 627) | func (es *errorState) Set(err error) {
method Err (line 635) | func (es *errorState) Err() error {
method Func (line 641) | func (es *errorState) Func() func() error {
type ListObject (line 681) | type ListObject struct
method As (line 703) | func (o *ListObject) As(i any) bool {
type Bucket (line 713) | type Bucket struct
method As (line 768) | func (b *Bucket) As(i any) bool {
method ErrorAs (line 779) | func (b *Bucket) ErrorAs(err error, i any) bool {
method ReadAll (line 787) | func (b *Bucket) ReadAll(ctx context.Context, key string) (_ []byte, e...
method Download (line 802) | func (b *Bucket) Download(ctx context.Context, key string, w io.Writer...
method List (line 823) | func (b *Bucket) List(opts *ListOptions) *ListIterator {
method ListPage (line 863) | func (b *Bucket) ListPage(ctx context.Context, pageToken []byte, pageS...
method IsAccessible (line 932) | func (b *Bucket) IsAccessible(ctx context.Context) (bool, error) {
method Exists (line 947) | func (b *Bucket) Exists(ctx context.Context, key string) (bool, error) {
method Attributes (line 962) | func (b *Bucket) Attributes(ctx context.Context, key string) (_ *Attri...
method NewReader (line 1006) | func (b *Bucket) NewReader(ctx context.Context, key string, opts *Read...
method NewRangeReader (line 1026) | func (b *Bucket) NewRangeReader(ctx context.Context, key string, offse...
method newRangeReader (line 1030) | func (b *Bucket) newRangeReader(ctx context.Context, key string, offse...
method WriteAll (line 1093) | func (b *Bucket) WriteAll(ctx context.Context, key string, p []byte, o...
method Upload (line 1116) | func (b *Bucket) Upload(ctx context.Context, key string, r io.Reader, ...
method NewWriter (line 1142) | func (b *Bucket) NewWriter(ctx context.Context, key string, opts *Writ...
method Copy (line 1250) | func (b *Bucket) Copy(ctx context.Context, dstKey, srcKey string, opts...
method Delete (line 1277) | func (b *Bucket) Delete(ctx context.Context, key string) (err error) {
method SignedURL (line 1300) | func (b *Bucket) SignedURL(ctx context.Context, key string, opts *Sign...
method Close (line 1343) | func (b *Bucket) Close() error {
constant pkgName (line 732) | pkgName = "gocloud.dev/blob"
function newBucket (line 752) | func newBucket(b driver.Bucket) *Bucket {
constant DefaultSignedURLExpiry (line 1355) | DefaultSignedURLExpiry = 1 * time.Hour
type SignedURLOptions (line 1358) | type SignedURLOptions struct
type ReaderOptions (line 1396) | type ReaderOptions struct
type WriterOptions (line 1410) | type WriterOptions struct
type CopyOptions (line 1494) | type CopyOptions struct
type BucketURLOpener (line 1508) | type BucketURLOpener interface
type URLMux (line 1518) | type URLMux struct
method BucketSchemes (line 1523) | func (mux *URLMux) BucketSchemes() []string { return mux.schemes.Schem...
method ValidBucketScheme (line 1526) | func (mux *URLMux) ValidBucketScheme(scheme string) bool { return mux....
method RegisterBucket (line 1530) | func (mux *URLMux) RegisterBucket(scheme string, opener BucketURLOpene...
method OpenBucket (line 1536) | func (mux *URLMux) OpenBucket(ctx context.Context, urlstr string) (*Bu...
method OpenBucketURL (line 1546) | func (mux *URLMux) OpenBucketURL(ctx context.Context, u *url.URL) (*Bu...
function applyPrefixParam (line 1554) | func applyPrefixParam(ctx context.Context, opener BucketURLOpener, u *ur...
function DefaultURLMux (line 1584) | func DefaultURLMux() *URLMux {
function OpenBucket (line 1601) | func OpenBucket(ctx context.Context, urlstr string) (*Bucket, error) {
function wrapError (line 1605) | func wrapError(b driver.Bucket, err error, key string) error {
function PrefixedBucket (line 1630) | func PrefixedBucket(bucket *Bucket, prefix string) *Bucket {
function SingleKeyBucket (line 1642) | func SingleKeyBucket(bucket *Bucket, singleKey string) *Bucket {
FILE: blob/blob_fs.go
type iofsFileInfo (line 37) | type iofsFileInfo struct
method Name (line 42) | func (f *iofsFileInfo) Name() string { return f.name }
method Size (line 43) | func (f *iofsFileInfo) Size() int64 { return f.lo.Size }
method Mode (line 44) | func (f *iofsFileInfo) Mode() fs.FileMode { return fs.ModeIrr...
method ModTime (line 45) | func (f *iofsFileInfo) ModTime() time.Time { return f.lo.ModTi...
method IsDir (line 46) | func (f *iofsFileInfo) IsDir() bool { return false }
method Sys (line 47) | func (f *iofsFileInfo) Sys() any { return f.lo }
method Info (line 48) | func (f *iofsFileInfo) Info() (fs.FileInfo, error) { return f, nil }
method Type (line 49) | func (f *iofsFileInfo) Type() fs.FileMode { return fs.ModeIrr...
type iofsOpenFile (line 53) | type iofsOpenFile struct
method Name (line 58) | func (f *iofsOpenFile) Name() string { return f.name }
method Mode (line 59) | func (f *iofsOpenFile) Mode() fs.FileMode { return fs.ModeIrr...
method IsDir (line 60) | func (f *iofsOpenFile) IsDir() bool { return false }
method Sys (line 61) | func (f *iofsOpenFile) Sys() any { return f.r }
method Stat (line 62) | func (f *iofsOpenFile) Stat() (fs.FileInfo, error) { return f, nil }
type iofsDir (line 66) | type iofsDir struct
method Name (line 80) | func (d *iofsDir) Name() string { return d.name }
method Size (line 81) | func (d *iofsDir) Size() int64 { return 0 }
method Mode (line 82) | func (d *iofsDir) Mode() fs.FileMode { return fs.ModeDir }
method Type (line 83) | func (d *iofsDir) Type() fs.FileMode { return fs.ModeDir }
method ModTime (line 84) | func (d *iofsDir) ModTime() time.Time { return time.Time{} }
method IsDir (line 85) | func (d *iofsDir) IsDir() bool { return true }
method Sys (line 86) | func (d *iofsDir) Sys() any { return d }
method Info (line 87) | func (d *iofsDir) Info() (fs.FileInfo, error) { return d, nil }
method Stat (line 88) | func (d *iofsDir) Stat() (fs.FileInfo, error) { return d, nil }
method Read (line 89) | func (d *iofsDir) Read([]byte) (int, error) {
method Close (line 92) | func (d *iofsDir) Close() error { return nil }
method ReadDir (line 93) | func (d *iofsDir) ReadDir(count int) ([]fs.DirEntry, error) {
method openOnce (line 112) | func (d *iofsDir) openOnce() error {
function newDir (line 76) | func newDir(b *Bucket, key, name string) *iofsDir {
method SetIOFSCallback (line 164) | func (b *Bucket) SetIOFSCallback(fn func() (context.Context, *ReaderOpti...
method Open (line 169) | func (b *Bucket) Open(path string) (fs.File, error) {
method Sub (line 221) | func (b *Bucket) Sub(dir string) (fs.FS, error) {
FILE: blob/blob_fs_test.go
function initBucket (line 39) | func initBucket(t *testing.T, files []string) *blob.Bucket {
function TestIOFS (line 54) | func TestIOFS(t *testing.T) {
function TestGlob (line 81) | func TestGlob(t *testing.T) {
function TestWalkDir (line 115) | func TestWalkDir(t *testing.T) {
FILE: blob/blob_iter_test.go
function TestListIterator_All (line 14) | func TestListIterator_All(t *testing.T) {
FILE: blob/blob_reader_test.go
function TestReader (line 28) | func TestReader(t *testing.T) {
FILE: blob/blob_test.go
function TestExists (line 39) | func TestExists(t *testing.T) {
type fakeAttributes (line 84) | type fakeAttributes struct
method Attributes (line 89) | func (b *fakeAttributes) Attributes(ctx context.Context, key string) (...
method ErrorCode (line 96) | func (b *fakeAttributes) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 103) | func (b *fakeAttributes) Close() error { return nil }
function TestListIterator (line 106) | func TestListIterator(t *testing.T) {
function TestListPage (line 133) | func TestListPage(t *testing.T) {
type fakeLister (line 167) | type fakeLister struct
method ListPaged (line 173) | func (b *fakeLister) ListPaged(ctx context.Context, opts *driver.ListO...
method Close (line 194) | func (*fakeLister) Close() error { return nil }
method ErrorCode (line 195) | func (*fakeLister) ErrorCode(err error) gcerrors.ErrorCode { return gc...
type stubReader (line 197) | type stubReader struct
method Download (line 202) | func (r *stubReader) Download(w io.Writer) error {
method Close (line 207) | func (*stubReader) Close() error { return nil }
type stubWriter (line 209) | type stubWriter struct
method Upload (line 214) | func (w *stubWriter) Upload(r io.Reader) error {
method Close (line 219) | func (*stubWriter) Close() error { return nil }
type loaderBucket (line 224) | type loaderBucket struct
method NewTypedWriter (line 230) | func (b *loaderBucket) NewTypedWriter(ctx context.Context, key, conten...
method NewRangeReader (line 234) | func (b *loaderBucket) NewRangeReader(ctx context.Context, key string,...
method Close (line 238) | func (*loaderBucket) Close() error { return nil }
function TestUploader (line 240) | func TestUploader(t *testing.T) {
function TestDownloader (line 254) | func TestDownloader(t *testing.T) {
function TestSeekAfterReadFailure (line 268) | func TestSeekAfterReadFailure(t *testing.T) {
type oneTimeReadBucket (line 309) | type oneTimeReadBucket struct
method NewRangeReader (line 325) | func (b *oneTimeReadBucket) NewRangeReader(ctx context.Context, key st...
method ErrorCode (line 333) | func (b *oneTimeReadBucket) ErrorCode(err error) gcerrors.ErrorCode { ...
method Close (line 334) | func (b *oneTimeReadBucket) Close() error { ...
type workingReader (line 314) | type workingReader struct
method Read (line 318) | func (r *workingReader) Read(p []byte) (int, error) {
method Attributes (line 322) | func (r *workingReader) Attributes() *driver.ReaderAttributes { return...
method Close (line 323) | func (r *workingReader) Close() error { return...
type erroringBucket (line 341) | type erroringBucket struct
method Attributes (line 369) | func (b *erroringBucket) Attributes(ctx context.Context, key string) (...
method ListPaged (line 373) | func (b *erroringBucket) ListPaged(ctx context.Context, opts *driver.L...
method NewRangeReader (line 377) | func (b *erroringBucket) NewRangeReader(ctx context.Context, key strin...
method NewTypedWriter (line 384) | func (b *erroringBucket) NewTypedWriter(ctx context.Context, key, cont...
method Copy (line 391) | func (b *erroringBucket) Copy(ctx context.Context, dstKey, srcKey stri...
method Delete (line 395) | func (b *erroringBucket) Delete(ctx context.Context, key string) error {
method SignedURL (line 399) | func (b *erroringBucket) SignedURL(ctx context.Context, key string, op...
method Close (line 403) | func (b *erroringBucket) Close() error {
method ErrorCode (line 407) | func (b *erroringBucket) ErrorCode(err error) gcerrors.ErrorCode {
type erroringReader (line 345) | type erroringReader struct
method Read (line 349) | func (r *erroringReader) Read(p []byte) (int, error) {
method Close (line 353) | func (r *erroringReader) Close() error {
type erroringWriter (line 357) | type erroringWriter struct
method Write (line 361) | func (r *erroringWriter) Write(p []byte) (int, error) {
method Close (line 365) | func (r *erroringWriter) Close() error {
function TestErrorsAreWrapped (line 413) | func TestErrorsAreWrapped(t *testing.T) {
function TestBucketIsClosed (line 495) | func TestBucketIsClosed(t *testing.T) {
function TestURLMux (line 539) | func TestURLMux(t *testing.T) {
type fakeOpener (line 642) | type fakeOpener struct
method OpenBucketURL (line 646) | func (o *fakeOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*...
FILE: blob/blob_writer_test.go
function TestWriteReturnValues (line 32) | func TestWriteReturnValues(t *testing.T) {
function randomData (line 65) | func randomData(nBytes int64) ([]byte, error) {
function TestReadFrom (line 80) | func TestReadFrom(t *testing.T) {
function TestWriteTo (line 118) | func TestWriteTo(t *testing.T) {
function TestCopyBytes (line 159) | func TestCopyBytes(t *testing.T) {
FILE: blob/driver/driver.go
type ReaderOptions (line 31) | type ReaderOptions struct
type Reader (line 41) | type Reader interface
type Downloader (line 55) | type Downloader interface
type Writer (line 61) | type Writer interface
type Uploader (line 66) | type Uploader interface
type WriterOptions (line 72) | type WriterOptions struct
type CopyOptions (line 121) | type CopyOptions struct
type ReaderAttributes (line 130) | type ReaderAttributes struct
type Attributes (line 141) | type Attributes struct
type ListOptions (line 183) | type ListOptions struct
type ListObject (line 214) | type ListObject struct
type ListPage (line 235) | type ListPage struct
type Bucket (line 253) | type Bucket interface
type SignedURLOptions (line 344) | type SignedURLOptions struct
type prefixedBucket (line 380) | type prefixedBucket struct
method ErrorCode (line 391) | func (b *prefixedBucket) ErrorCode(err error) gcerrors.ErrorCode { ret...
method As (line 392) | func (b *prefixedBucket) As(i any) bool { ret...
method ErrorAs (line 393) | func (b *prefixedBucket) ErrorAs(err error, i any) bool { ret...
method Attributes (line 394) | func (b *prefixedBucket) Attributes(ctx context.Context, key string) (...
method ListPaged (line 398) | func (b *prefixedBucket) ListPaged(ctx context.Context, opts *ListOpti...
method NewRangeReader (line 414) | func (b *prefixedBucket) NewRangeReader(ctx context.Context, key strin...
method NewTypedWriter (line 418) | func (b *prefixedBucket) NewTypedWriter(ctx context.Context, key, cont...
method Copy (line 425) | func (b *prefixedBucket) Copy(ctx context.Context, dstKey, srcKey stri...
method Delete (line 429) | func (b *prefixedBucket) Delete(ctx context.Context, key string) error {
method SignedURL (line 433) | func (b *prefixedBucket) SignedURL(ctx context.Context, key string, op...
method Close (line 436) | func (b *prefixedBucket) Close() error { return b.base.Close() }
function NewPrefixedBucket (line 387) | func NewPrefixedBucket(b Bucket, prefix string) Bucket {
type singleKeyBucket (line 439) | type singleKeyBucket struct
method ErrorCode (line 449) | func (b *singleKeyBucket) ErrorCode(err error) gcerrors.ErrorCode { re...
method As (line 450) | func (b *singleKeyBucket) As(i any) bool { re...
method ErrorAs (line 451) | func (b *singleKeyBucket) ErrorAs(err error, i any) bool { re...
method Attributes (line 452) | func (b *singleKeyBucket) Attributes(ctx context.Context, _ string) (*...
method ListPaged (line 456) | func (b *singleKeyBucket) ListPaged(ctx context.Context, opts *ListOpt...
method NewRangeReader (line 460) | func (b *singleKeyBucket) NewRangeReader(ctx context.Context, _ string...
method NewTypedWriter (line 464) | func (b *singleKeyBucket) NewTypedWriter(ctx context.Context, _, conte...
method Copy (line 468) | func (b *singleKeyBucket) Copy(ctx context.Context, dstKey, _ string, ...
method Delete (line 472) | func (b *singleKeyBucket) Delete(ctx context.Context, _ string) error {
method SignedURL (line 476) | func (b *singleKeyBucket) SignedURL(ctx context.Context, _ string, opt...
method Close (line 479) | func (b *singleKeyBucket) Close() error { return b.base.Close() }
function NewSingleKeyBucket (line 445) | func NewSingleKeyBucket(b Bucket, key string) Bucket {
FILE: blob/drivertest/bindata.go
function bindataRead (line 27) | func bindataRead(data []byte, name string) ([]byte, error) {
function testLargeJpg (line 46) | func testLargeJpg() ([]byte, error) {
function testMediumHTML (line 55) | func testMediumHTML() ([]byte, error) {
function testSmallTxt (line 64) | func testSmallTxt() ([]byte, error) {
function Asset (line 74) | func Asset(name string) ([]byte, error) {
function AssetNames (line 83) | func AssetNames() []string {
function AssetDir (line 113) | func AssetDir(name string) ([]string, error) {
type _bintreeT (line 135) | type _bintreeT struct
FILE: blob/drivertest/drivertest.go
type Harness (line 49) | type Harness interface
type HarnessMaker (line 67) | type HarnessMaker
type AsTest (line 96) | type AsTest interface
type verifyAsFailsOnNil (line 129) | type verifyAsFailsOnNil struct
method Name (line 131) | func (verifyAsFailsOnNil) Name() string {
method BucketCheck (line 135) | func (verifyAsFailsOnNil) BucketCheck(b *blob.Bucket) error {
method ErrorCheck (line 142) | func (verifyAsFailsOnNil) ErrorCheck(b *blob.Bucket, err error) (ret e...
method BeforeRead (line 152) | func (verifyAsFailsOnNil) BeforeRead(as func(any) bool) error {
method BeforeWrite (line 159) | func (verifyAsFailsOnNil) BeforeWrite(as func(any) bool) error {
method BeforeCopy (line 166) | func (verifyAsFailsOnNil) BeforeCopy(as func(any) bool) error {
method BeforeList (line 173) | func (verifyAsFailsOnNil) BeforeList(as func(any) bool) error {
method BeforeSign (line 180) | func (verifyAsFailsOnNil) BeforeSign(as func(any) bool) error {
method AttributesCheck (line 187) | func (verifyAsFailsOnNil) AttributesCheck(attrs *blob.Attributes) error {
method ReaderCheck (line 194) | func (verifyAsFailsOnNil) ReaderCheck(r *blob.Reader) error {
method ListObjectCheck (line 201) | func (verifyAsFailsOnNil) ListObjectCheck(o *blob.ListObject) error {
function RunConformanceTests (line 209) | func RunConformanceTests(t *testing.T, newHarness HarnessMaker, asTests ...
function RunBenchmarks (line 280) | func RunBenchmarks(b *testing.B, bkt *blob.Bucket) {
function testNonexistentBucket (line 292) | func testNonexistentBucket(t *testing.T, newHarness HarnessMaker) {
function testList (line 342) | func testList(t *testing.T, newHarness HarnessMaker) {
function testListWeirdKeys (line 577) | func testListWeirdKeys(t *testing.T, newHarness HarnessMaker) {
type listResult (line 636) | type listResult struct
function doList (line 645) | func doList(ctx context.Context, b *blob.Bucket, prefix, delim string, r...
function testListDelimiters (line 679) | func testListDelimiters(t *testing.T, newHarness HarnessMaker) {
function testDirsWithCharactersBeforeDelimiter (line 1007) | func testDirsWithCharactersBeforeDelimiter(t *testing.T, newHarness Harn...
function iterToSetOfKeys (line 1085) | func iterToSetOfKeys(ctx context.Context, t *testing.T, iter *blob.ListI...
function testRead (line 1102) | func testRead(t *testing.T, newHarness HarnessMaker) {
function testAttributes (line 1251) | func testAttributes(t *testing.T, newHarness HarnessMaker) {
function loadTestData (line 1386) | func loadTestData(tb testing.TB, name string) []byte {
function testWrite (line 1397) | func testWrite(t *testing.T, newHarness HarnessMaker) {
function testCanceledWrite (line 1617) | func testCanceledWrite(t *testing.T, newHarness HarnessMaker) {
function testMetadata (line 1732) | func testMetadata(t *testing.T, newHarness HarnessMaker) {
function testMD5 (line 1857) | func testMD5(t *testing.T, newHarness HarnessMaker) {
function testCopy (line 1935) | func testCopy(t *testing.T, newHarness HarnessMaker) {
function testDelete (line 2067) | func testDelete(t *testing.T, newHarness HarnessMaker) {
function testConcurrentWriteAndRead (line 2140) | func testConcurrentWriteAndRead(t *testing.T, newHarness HarnessMaker) {
function testUploadDownload (line 2224) | func testUploadDownload(t *testing.T, newHarness HarnessMaker) {
function testKeys (line 2268) | func testKeys(t *testing.T, newHarness HarnessMaker) {
function testSignedURL (line 2387) | func testSignedURL(t *testing.T, newHarness HarnessMaker) {
function testAs (line 2620) | func testAs(t *testing.T, newHarness HarnessMaker, st AsTest) {
function testIfNotExist (line 2737) | func testIfNotExist(t *testing.T, newHarness HarnessMaker) {
function benchmarkRead (line 2795) | func benchmarkRead(b *testing.B, bkt *blob.Bucket) {
function benchmarkWriteReadDelete (line 2832) | func benchmarkWriteReadDelete(b *testing.B, bkt *blob.Bucket) {
FILE: blob/example_openbucket_test.go
function Example_openFromURL (line 26) | func Example_openFromURL() {
function Example_openFromURLWithPrefix (line 56) | func Example_openFromURLWithPrefix() {
function Example_openFromURLWithSingleKey (line 74) | func Example_openFromURLWithSingleKey() {
FILE: blob/example_test.go
function ExampleBucket_NewReader (line 34) | func ExampleBucket_NewReader() {
function ExampleBucket_NewRangeReader (line 55) | func ExampleBucket_NewRangeReader() {
function ExampleBucket_NewWriter (line 73) | func ExampleBucket_NewWriter() {
function ExampleBucket_NewWriter_cancel (line 95) | func ExampleBucket_NewWriter_cancel() {
function ExampleBucket_Delete (line 122) | func ExampleBucket_Delete() {
function Example (line 133) | func Example() {
function ExampleBucket_ErrorAs (line 164) | func ExampleBucket_ErrorAs() {
function ExampleBucket_List (line 187) | func ExampleBucket_List() {
function ExampleBucket_List_withDelimiter (line 254) | func ExampleBucket_List_withDelimiter() {
function ExampleBucket_ListPage (line 316) | func ExampleBucket_ListPage() {
function ExampleBucket_As (line 390) | func ExampleBucket_As() {
function ExampleWriterOptions (line 417) | func ExampleWriterOptions() {
function ExampleListObject_As (line 445) | func ExampleListObject_As() {
function ExampleListOptions (line 476) | func ExampleListOptions() {
function ExamplePrefixedBucket (line 512) | func ExamplePrefixedBucket() {
function ExampleSingleKeyBucket (line 529) | func ExampleSingleKeyBucket() {
function ExampleReader_As (line 545) | func ExampleReader_As() {
function ExampleAttributes_As (line 572) | func ExampleAttributes_As() {
function newTempDir (line 596) | func newTempDir() (string, func()) {
FILE: blob/fileblob/attrs.go
constant attrsExt (line 23) | attrsExt = ".attrs"
type xattrs (line 30) | type xattrs struct
function setAttrs (line 42) | func setAttrs(path string, xa xattrs) error {
function getAttrs (line 58) | func getAttrs(path string) (xattrs, error) {
FILE: blob/fileblob/example_test.go
function ExampleOpenBucket (line 29) | func ExampleOpenBucket() {
function Example_openBucketFromURL (line 46) | func Example_openBucketFromURL() {
FILE: blob/fileblob/fileblob.go
constant defaultPageSize (line 91) | defaultPageSize = 1000
function init (line 93) | func init() {
constant Scheme (line 99) | Scheme = "file"
type URLOpener (line 140) | type URLOpener struct
method OpenBucketURL (line 146) | func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*b...
method forParams (line 179) | func (o *URLOpener) forParams(ctx context.Context, q url.Values) (*Opt...
type metadataOption (line 169) | type metadataOption
constant MetadataInSidecar (line 174) | MetadataInSidecar metadataOption = ""
constant MetadataDontWrite (line 176) | MetadataDontWrite metadataOption = "skip"
type Options (line 235) | type Options struct
type bucket (line 265) | type bucket struct
method Close (line 313) | func (b *bucket) Close() error {
method ErrorCode (line 360) | func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode {
method path (line 370) | func (b *bucket) path(key string) (string, error) {
method forKey (line 386) | func (b *bucket) forKey(key string) (string, os.FileInfo, *xattrs, err...
method ListPaged (line 406) | func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptio...
method As (line 573) | func (b *bucket) As(i any) bool {
method ErrorAs (line 587) | func (b *bucket) ErrorAs(err error, i any) bool {
method Attributes (line 598) | func (b *bucket) Attributes(ctx context.Context, key string) (*driver....
method NewRangeReader (line 627) | func (b *bucket) NewRangeReader(ctx context.Context, key string, offse...
method NewTypedWriter (line 731) | func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType ...
method Copy (line 908) | func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts...
method Delete (line 949) | func (b *bucket) Delete(ctx context.Context, key string) error {
method SignedURL (line 965) | func (b *bucket) SignedURL(ctx context.Context, key string, opts *driv...
function openBucket (line 272) | func openBucket(dir string, opts *Options) (driver.Bucket, error) {
function OpenBucket (line 305) | func OpenBucket(dir string, opts *Options) (*blob.Bucket, error) {
function escapeKey (line 318) | func escapeKey(s string) string {
function unescapeKey (line 352) | func unescapeKey(s string) string {
type reader (line 668) | type reader struct
method Read (line 674) | func (r *reader) Read(p []byte) (int, error) {
method Close (line 681) | func (r *reader) Close() error {
method Attributes (line 688) | func (r *reader) Attributes() *driver.ReaderAttributes {
method As (line 692) | func (r *reader) As(i any) bool {
function createTemp (line 701) | func createTemp(path string, noTempDir bool) (*os.File, error) {
type writerWithSidecar (line 793) | type writerWithSidecar struct
method Write (line 806) | func (w *writerWithSidecar) Write(p []byte) (n int, err error) {
method Close (line 819) | func (w *writerWithSidecar) Close() error {
type writer (line 863) | type writer struct
method Upload (line 871) | func (w *writer) Upload(r io.Reader) error {
method Close (line 876) | func (w *writer) Close() error {
type URLSigner (line 986) | type URLSigner interface
type URLSignerHMAC (line 1003) | type URLSignerHMAC struct
method URLFromKey (line 1024) | func (h *URLSignerHMAC) URLFromKey(ctx context.Context, key string, op...
method getMAC (line 1041) | func (h *URLSignerHMAC) getMAC(q url.Values) string {
method KeyFromURL (line 1058) | func (h *URLSignerHMAC) KeyFromURL(ctx context.Context, sURL *url.URL)...
method checkMAC (line 1072) | func (h *URLSignerHMAC) checkMAC(q url.Values) bool {
function NewURLSignerHMAC (line 1010) | func NewURLSignerHMAC(baseURL *url.URL, secretKey []byte) *URLSignerHMAC {
FILE: blob/fileblob/fileblob_test.go
type harness (line 37) | type harness struct
method serveSignedURL (line 85) | func (h *harness) serveSignedURL(w http.ResponseWriter, r *http.Reques...
method HTTPClient (line 145) | func (h *harness) HTTPClient() *http.Client {
method MakeDriver (line 149) | func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, erro...
method MakeDriverForNonexistentBucket (line 165) | func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) ...
method Close (line 171) | func (h *harness) Close() {
function newHarness (line 47) | func newHarness(ctx context.Context, t *testing.T, prefix string, metada...
function TestConformance (line 175) | func TestConformance(t *testing.T) {
function TestConformanceNoTempDir (line 184) | func TestConformanceNoTempDir(t *testing.T) {
function TestConformanceWithPrefix (line 193) | func TestConformanceWithPrefix(t *testing.T) {
function TestConformanceSkipMetadata (line 203) | func TestConformanceSkipMetadata(t *testing.T) {
function BenchmarkFileblob (line 212) | func BenchmarkFileblob(b *testing.B) {
function TestNewBucket (line 225) | func TestNewBucket(t *testing.T) {
function TestSignedURLReturnsUnimplementedWithNoURLSigner (line 263) | func TestSignedURLReturnsUnimplementedWithNoURLSigner(t *testing.T) {
type verifyAs (line 277) | type verifyAs struct
method Name (line 281) | func (verifyAs) Name() string { return "verify As types for fileblob" }
method BucketCheck (line 283) | func (verifyAs) BucketCheck(b *blob.Bucket) error {
method BeforeRead (line 291) | func (verifyAs) BeforeRead(as func(any) bool) error {
method BeforeWrite (line 299) | func (verifyAs) BeforeWrite(as func(any) bool) error {
method BeforeCopy (line 307) | func (verifyAs) BeforeCopy(as func(any) bool) error {
method BeforeList (line 314) | func (verifyAs) BeforeList(as func(any) bool) error { return nil }
method BeforeSign (line 315) | func (verifyAs) BeforeSign(as func(any) bool) error { return nil }
method AttributesCheck (line 316) | func (verifyAs) AttributesCheck(attrs *blob.Attributes) error {
method ReaderCheck (line 324) | func (verifyAs) ReaderCheck(r *blob.Reader) error {
method ListObjectCheck (line 332) | func (verifyAs) ListObjectCheck(o *blob.ListObject) error {
method ErrorCheck (line 340) | func (v verifyAs) ErrorCheck(b *blob.Bucket, err error) error {
function TestOpenBucketFromURL (line 352) | func TestOpenBucketFromURL(t *testing.T) {
function TestEscapeBucketRoot (line 457) | func TestEscapeBucketRoot(t *testing.T) {
function TestListAtRoot (line 484) | func TestListAtRoot(t *testing.T) {
function TestSkipMetadata (line 520) | func TestSkipMetadata(t *testing.T) {
FILE: blob/gcsblob/example_test.go
function ExampleOpenBucket (line 26) | func ExampleOpenBucket() {
function Example_openBucketFromURL (line 57) | func Example_openBucketFromURL() {
FILE: blob/gcsblob/gcsblob.go
constant defaultPageSize (line 92) | defaultPageSize = 1000
function init (line 94) | func init() {
function readDefaultCredentials (line 111) | func readDefaultCredentials(credFileAsJSON []byte) (AccessID string, Pri...
type lazyCredsOpener (line 147) | type lazyCredsOpener struct
method OpenBucketURL (line 153) | func (o *lazyCredsOpener) OpenBucketURL(ctx context.Context, u *url.UR...
constant Scheme (line 217) | Scheme = "gs"
type URLOpener (line 230) | type URLOpener struct
method OpenBucketURL (line 240) | func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*b...
method forParams (line 248) | func (o *URLOpener) forParams(ctx context.Context, q url.Values) (*Opt...
type Options (line 291) | type Options struct
method clear (line 326) | func (o *Options) clear() {
type SignBytesFunc (line 334) | type SignBytesFunc
function openBucket (line 337) | func openBucket(ctx context.Context, client *gcp.HTTPClient, bucketName ...
function OpenBucket (line 373) | func OpenBucket(ctx context.Context, client *gcp.HTTPClient, bucketName ...
type bucket (line 383) | type bucket struct
method ErrorCode (line 420) | func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 441) | func (b *bucket) Close() error {
method ListPaged (line 446) | func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptio...
method As (line 516) | func (b *bucket) As(i any) bool {
method ErrorAs (line 526) | func (b *bucket) ErrorAs(err error, i any) bool {
method Attributes (line 538) | func (b *bucket) Attributes(ctx context.Context, key string) (*driver....
method NewRangeReader (line 576) | func (b *bucket) NewRangeReader(ctx context.Context, key string, offse...
method NewTypedWriter (line 653) | func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType ...
method Copy (line 712) | func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts...
method Delete (line 756) | func (b *bucket) Delete(ctx context.Context, key string) error {
method SignedURL (line 763) | func (b *bucket) SignedURL(ctx context.Context, key string, dopts *dri...
type reader (line 392) | type reader struct
method Read (line 398) | func (r *reader) Read(p []byte) (int, error) {
method Close (line 403) | func (r *reader) Close() error {
method Attributes (line 407) | func (r *reader) Attributes() *driver.ReaderAttributes {
method As (line 411) | func (r *reader) As(i any) bool {
function escapeKey (line 633) | func escapeKey(key string) string {
function unescapeKey (line 648) | func unescapeKey(key string) string {
type CopyObjectHandles (line 707) | type CopyObjectHandles struct
function bufferSize (line 805) | func bufferSize(size int) int {
FILE: blob/gcsblob/gcsblob_test.go
constant bucketName (line 56) | bucketName = "go-cloud-blob-test-bucket"
constant serviceAccountID (line 57) | serviceAccountID = "storage-updater@go-cloud-test-216917.iam.gserviceacc...
type harness (line 62) | type harness struct
method HTTPClient (line 92) | func (h *harness) HTTPClient() *http.Client {
method MakeDriver (line 96) | func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, erro...
method MakeDriverForNonexistentBucket (line 100) | func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) ...
method Close (line 104) | func (h *harness) Close() {
function newHarness (line 69) | func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, ...
function TestConformance (line 108) | func TestConformance(t *testing.T) {
function BenchmarkGcsblob (line 112) | func BenchmarkGcsblob(b *testing.B) {
constant language (line 129) | language = "nl"
type verifyContentLanguage (line 133) | type verifyContentLanguage struct
method Name (line 135) | func (verifyContentLanguage) Name() string {
method BucketCheck (line 139) | func (verifyContentLanguage) BucketCheck(b *blob.Bucket) error {
method ErrorCheck (line 147) | func (verifyContentLanguage) ErrorCheck(b *blob.Bucket, err error) err...
method BeforeRead (line 159) | func (verifyContentLanguage) BeforeRead(as func(any) bool) error {
method BeforeWrite (line 171) | func (verifyContentLanguage) BeforeWrite(as func(any) bool) error {
method BeforeCopy (line 184) | func (verifyContentLanguage) BeforeCopy(as func(any) bool) error {
method BeforeList (line 196) | func (verifyContentLanguage) BeforeList(as func(any) bool) error {
method BeforeSign (line 205) | func (verifyContentLanguage) BeforeSign(as func(any) bool) error {
method AttributesCheck (line 214) | func (verifyContentLanguage) AttributesCheck(attrs *blob.Attributes) e...
method ReaderCheck (line 225) | func (verifyContentLanguage) ReaderCheck(r *blob.Reader) error {
method ListObjectCheck (line 234) | func (verifyContentLanguage) ListObjectCheck(o *blob.ListObject) error {
function TestBufferSize (line 249) | func TestBufferSize(t *testing.T) {
function TestOpenBucket (line 275) | func TestOpenBucket(t *testing.T) {
function TestBeforeReadNonExistentKey (line 332) | func TestBeforeReadNonExistentKey(t *testing.T) {
function TestPreconditions (line 367) | func TestPreconditions(t *testing.T) {
function TestURLOpenerForParams (line 519) | func TestURLOpenerForParams(t *testing.T) {
function TestOpenBucketFromURL (line 656) | func TestOpenBucketFromURL(t *testing.T) {
function TestReadDefaultCredentials (line 703) | func TestReadDefaultCredentials(t *testing.T) {
function TestRemainingSignedURLSchemes (line 769) | func TestRemainingSignedURLSchemes(t *testing.T) {
FILE: blob/gcsblob/iam.go
type credentialsClient (line 33) | type credentialsClient struct
method CreateMakeSignBytesWith (line 47) | func (c *credentialsClient) CreateMakeSignBytesWith(lifetimeCtx contex...
FILE: blob/gcsblob/iam_test.go
constant mockKey (line 27) | mockKey = "key0000"
constant mockSignature (line 28) | mockSignature = "signature"
type mockIAMClient (line 31) | type mockIAMClient struct
method SignBlob (line 35) | func (m mockIAMClient) SignBlob(context.Context, *credentialspb.SignBl...
function TestIAMCredentialsClient (line 42) | func TestIAMCredentialsClient(t *testing.T) {
FILE: blob/memblob/example_test.go
function ExampleOpenBucket (line 26) | func ExampleOpenBucket() {
function Example_openBucketFromURL (line 50) | func Example_openBucketFromURL() {
FILE: blob/memblob/memblob.go
constant defaultPageSize (line 51) | defaultPageSize = 1000
function init (line 58) | func init() {
constant Scheme (line 64) | Scheme = "mem"
type URLOpener (line 70) | type URLOpener struct
method OpenBucketURL (line 73) | func (*URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blo...
type Options (line 86) | type Options struct
type blobEntry (line 92) | type blobEntry struct
type bucket (line 97) | type bucket struct
method Close (line 120) | func (b *bucket) Close() error {
method ErrorCode (line 124) | func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode {
method ListPaged (line 137) | func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptio...
method As (line 216) | func (b *bucket) As(i any) bool { return false }
method ErrorAs (line 219) | func (b *bucket) ErrorAs(err error, i any) bool { return false }
method Attributes (line 222) | func (b *bucket) Attributes(ctx context.Context, key string) (*driver....
method NewRangeReader (line 234) | func (b *bucket) NewRangeReader(ctx context.Context, key string, offse...
method NewTypedWriter (line 296) | func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType ...
method Copy (line 397) | func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts...
method Delete (line 415) | func (b *bucket) Delete(ctx context.Context, key string) error {
method SignedURL (line 426) | func (b *bucket) SignedURL(ctx context.Context, key string, opts *driv...
function openBucket (line 105) | func openBucket(opts *Options) driver.Bucket {
function OpenBucket (line 116) | func OpenBucket(opts *Options) *blob.Bucket {
type reader (line 268) | type reader struct
method Read (line 273) | func (r *reader) Read(p []byte) (int, error) {
method Download (line 277) | func (r *reader) Download(w io.Writer) error {
method Close (line 285) | func (r *reader) Close() error {
method Attributes (line 289) | func (r *reader) Attributes() *driver.ReaderAttributes {
method As (line 293) | func (r *reader) As(i any) bool { return false }
type writer (line 327) | type writer struct
method Write (line 341) | func (w *writer) Write(p []byte) (n int, err error) {
method Upload (line 350) | func (w *writer) Upload(r io.Reader) error {
method Close (line 355) | func (w *writer) Close() error {
FILE: blob/memblob/memblob_test.go
type harness (line 27) | type harness struct
method HTTPClient (line 37) | func (h *harness) HTTPClient() *http.Client {
method MakeDriver (line 41) | func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, erro...
method MakeDriverForNonexistentBucket (line 49) | func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) ...
method Close (line 54) | func (h *harness) Close() {}
function newHarness (line 31) | func newHarness(ctx context.Context, t *testing.T, prefix string) (drive...
function TestConformance (line 56) | func TestConformance(t *testing.T) {
function TestConformanceWithPrefix (line 65) | func TestConformanceWithPrefix(t *testing.T) {
function BenchmarkMemblob (line 75) | func BenchmarkMemblob(b *testing.B) {
function TestOpenBucketFromURL (line 79) | func TestOpenBucketFromURL(t *testing.T) {
FILE: blob/otel_test.go
function TestOpenTelemetry (line 27) | func TestOpenTelemetry(t *testing.T) {
FILE: blob/s3blob/example_test.go
function ExampleOpenBucket (line 27) | func ExampleOpenBucket() {
function Example_openBucketFromURL (line 48) | func Example_openBucketFromURL() {
FILE: blob/s3blob/s3blob.go
constant defaultPageSize (line 85) | defaultPageSize = 1000
function init (line 87) | func init() {
function Dial (line 97) | func Dial(cfg aws.Config) *s3.Client {
type urlSessionOpener (line 101) | type urlSessionOpener struct
method OpenBucketURL (line 103) | func (o *urlSessionOpener) OpenBucketURL(ctx context.Context, u *url.U...
constant Scheme (line 110) | Scheme = "s3"
type URLOpener (line 125) | type URLOpener struct
method OpenBucketURL (line 149) | func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*b...
constant sseTypeParamKey (line 131) | sseTypeParamKey = "ssetype"
constant kmsKeyIdParamKey (line 132) | kmsKeyIdParamKey = "kmskeyid"
constant accelerateParamKey (line 133) | accelerateParamKey = "accelerate"
constant usePathStyleParamKey (line 134) | usePathStyleParamKey = "use_path_style"
constant legacyUsePathStyleParamKey (line 135) | legacyUsePathStyleParamKey = "s3ForcePathStyle"
constant disableHTTPSParamKey (line 136) | disableHTTPSParamKey = "disable_https"
function toServerSideEncryptionType (line 139) | func toServerSideEncryptionType(value string) (types.ServerSideEncryptio...
type Options (line 221) | type Options struct
function openBucket (line 244) | func openBucket(ctx context.Context, client *s3.Client, bucketName strin...
function OpenBucket (line 265) | func OpenBucket(ctx context.Context, client *s3.Client, bucketName strin...
type reader (line 276) | type reader struct
method Read (line 282) | func (r *reader) Read(p []byte) (int, error) {
method Close (line 287) | func (r *reader) Close() error {
method As (line 291) | func (r *reader) As(i any) bool {
method Attributes (line 300) | func (r *reader) Attributes() *driver.ReaderAttributes {
type writer (line 305) | type writer struct
method Write (line 324) | func (w *writer) Write(p []byte) (int, error) {
method Upload (line 341) | func (w *writer) Upload(r io.Reader) error {
method open (line 350) | func (w *writer) open(r io.Reader, closePipeOnError bool) {
method Close (line 374) | func (w *writer) Close() error {
type bucket (line 391) | type bucket struct
method Close (line 401) | func (b *bucket) Close() error {
method ErrorCode (line 405) | func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode {
method ListPaged (line 430) | func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptio...
method listObjects (line 498) | func (b *bucket) listObjects(ctx context.Context, in *s3.ListObjectsV2...
method As (line 562) | func (b *bucket) As(i any) bool {
method ErrorAs (line 572) | func (b *bucket) ErrorAs(err error, i any) bool {
method Attributes (line 577) | func (b *bucket) Attributes(ctx context.Context, key string) (*driver....
method NewRangeReader (line 618) | func (b *bucket) NewRangeReader(ctx context.Context, key string, offse...
method NewTypedWriter (line 739) | func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType ...
method Copy (line 828) | func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts...
method Delete (line 861) | func (b *bucket) Delete(ctx context.Context, key string) error {
method SignedURL (line 874) | func (b *bucket) SignedURL(ctx context.Context, key string, opts *driv...
function eTagToMD5 (line 679) | func eTagToMD5(etag *string) []byte {
function getSize (line 700) | func getSize(contentLength int64, contentRange string) int64 {
function escapeKey (line 718) | func escapeKey(key string) string {
function unescapeKey (line 734) | func unescapeKey(key string) string {
FILE: blob/s3blob/s3blob_test.go
constant bucketName (line 49) | bucketName = "go-cloud-testing-2"
constant region (line 50) | region = "us-west-1"
type harness (line 53) | type harness struct
method HTTPClient (line 74) | func (h *harness) HTTPClient() *http.Client {
method MakeDriver (line 78) | func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, erro...
method MakeDriverForNonexistentBucket (line 82) | func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) ...
method Close (line 86) | func (h *harness) Close() {
function newHarness (line 60) | func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, ...
function newHarnessUsingLegacyList (line 67) | func newHarnessUsingLegacyList(ctx context.Context, t *testing.T) (drive...
function TestConformance (line 90) | func TestConformance(t *testing.T) {
function TestConformanceUsingLegacyList (line 94) | func TestConformanceUsingLegacyList(t *testing.T) {
function BenchmarkS3blob (line 98) | func BenchmarkS3blob(b *testing.B) {
constant language (line 112) | language = "nl"
type verifyContentLanguage (line 116) | type verifyContentLanguage struct
method Name (line 120) | func (verifyContentLanguage) Name() string {
method BucketCheck (line 124) | func (v verifyContentLanguage) BucketCheck(b *blob.Bucket) error {
method ErrorCheck (line 132) | func (v verifyContentLanguage) ErrorCheck(b *blob.Bucket, err error) e...
method BeforeRead (line 140) | func (v verifyContentLanguage) BeforeRead(as func(any) bool) error {
method BeforeWrite (line 151) | func (v verifyContentLanguage) BeforeWrite(as func(any) bool) error {
method BeforeCopy (line 167) | func (v verifyContentLanguage) BeforeCopy(as func(any) bool) error {
method BeforeList (line 175) | func (v verifyContentLanguage) BeforeList(as func(any) bool) error {
method BeforeSign (line 194) | func (v verifyContentLanguage) BeforeSign(as func(any) bool) error {
method AttributesCheck (line 206) | func (v verifyContentLanguage) AttributesCheck(attrs *blob.Attributes)...
method ReaderCheck (line 217) | func (v verifyContentLanguage) ReaderCheck(r *blob.Reader) error {
method ListObjectCheck (line 228) | func (v verifyContentLanguage) ListObjectCheck(o *blob.ListObject) err...
function TestOpenBucket (line 246) | func TestOpenBucket(t *testing.T) {
function TestOpenBucketFromURL (line 302) | func TestOpenBucketFromURL(t *testing.T) {
function TestChecksumConfigurationPassthrough (line 379) | func TestChecksumConfigurationPassthrough(t *testing.T) {
function TestToServerSideEncryptionType (line 454) | func TestToServerSideEncryptionType(t *testing.T) {
FILE: blob/wrapped_bucket_test.go
function TestPrefixedBucket (line 14) | func TestPrefixedBucket(t *testing.T) {
function TestSingleKeyBucket (line 40) | func TestSingleKeyBucket(t *testing.T) {
FILE: docstore/awsdynamodb/v2/benchmark_test.go
function BenchmarkPutVSTransact (line 31) | func BenchmarkPutVSTransact(b *testing.B) {
function putItems (line 76) | func putItems(b *testing.B, db *dynamodb.Client, items []map[string]dyn2...
function batchGetTransactWrite (line 105) | func batchGetTransactWrite(b *testing.B, db *dynamodb.Client, items []ma...
FILE: docstore/awsdynamodb/v2/codec.go
type encoder (line 30) | type encoder struct
method EncodeNil (line 34) | func (e *encoder) EncodeNil() { e.av = nullValue }
method EncodeBool (line 35) | func (e *encoder) EncodeBool(x bool) { e.av = &dyn2Types.AttributeValu...
method EncodeInt (line 36) | func (e *encoder) EncodeInt(x int64) {
method EncodeUint (line 39) | func (e *encoder) EncodeUint(x uint64) {
method EncodeBytes (line 42) | func (e *encoder) EncodeBytes(x []byte) { e.av = &dyn2Types.Attribute...
method EncodeFloat (line 43) | func (e *encoder) EncodeFloat(x float64) { e.av = encodeFloat(x) }
method ListIndex (line 45) | func (e *encoder) ListIndex(int) { panic("impossible") }
method MapKey (line 46) | func (e *encoder) MapKey(string) { panic("impossible") }
method EncodeString (line 48) | func (e *encoder) EncodeString(x string) {
method EncodeComplex (line 56) | func (e *encoder) EncodeComplex(x complex128) {
method EncodeList (line 60) | func (e *encoder) EncodeList(n int) driver.Encoder {
method EncodeMap (line 66) | func (e *encoder) EncodeMap(n int) driver.Encoder {
method EncodeSpecial (line 75) | func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) {
type listEncoder (line 86) | type listEncoder struct
method ListIndex (line 91) | func (e *listEncoder) ListIndex(i int) { e.s[i] = e.av }
type mapEncoder (line 93) | type mapEncoder struct
method MapKey (line 98) | func (e *mapEncoder) MapKey(k string) { e.m[k] = e.av }
function encodeDoc (line 100) | func encodeDoc(doc driver.Document) (dyn2Types.AttributeValue, error) {
function encodeDocKeyFields (line 111) | func encodeDocKeyFields(doc driver.Document, pkey, skey string) (*dyn2Ty...
function encodeValue (line 138) | func encodeValue(v any) (dyn2Types.AttributeValue, error) {
function encodeFloat (line 146) | func encodeFloat(f float64) dyn2Types.AttributeValue {
function decodeDoc (line 152) | func decodeDoc(item dyn2Types.AttributeValue, doc driver.Document) error {
type decoder (line 156) | type decoder struct
method String (line 160) | func (d decoder) String() string {
method AsBool (line 167) | func (d decoder) AsBool() (bool, bool) {
method AsNull (line 175) | func (d decoder) AsNull() bool {
method AsString (line 183) | func (d decoder) AsString() (string, bool) {
method AsInt (line 196) | func (d decoder) AsInt() (int64, bool) {
method AsUint (line 208) | func (d decoder) AsUint() (uint64, bool) {
method AsFloat (line 220) | func (d decoder) AsFloat() (float64, bool) {
method AsComplex (line 232) | func (d decoder) AsComplex() (complex128, bool) {
method AsBytes (line 251) | func (d decoder) AsBytes() ([]byte, bool) {
method ListLen (line 259) | func (d decoder) ListLen() (int, bool) {
method DecodeList (line 267) | func (d decoder) DecodeList(f func(i int, vd driver.Decoder) bool) {
method MapLen (line 282) | func (d decoder) MapLen() (int, bool) {
method DecodeMap (line 290) | func (d decoder) DecodeMap(f func(key string, vd driver.Decoder, exact...
method AsInterface (line 305) | func (d decoder) AsInterface() (any, error) {
method AsSpecial (line 362) | func (d decoder) AsSpecial(v reflect.Value) (bool, any, error) {
function toGoValue (line 309) | func toGoValue(av dyn2Types.AttributeValue) (any, error) {
FILE: docstore/awsdynamodb/v2/codec_test.go
function TestEncodeValue (line 42) | func TestEncodeValue(t *testing.T) {
function TestDecodeValue (line 100) | func TestDecodeValue(t *testing.T) {
function TestDecodeErrorOnUnsupported (line 160) | func TestDecodeErrorOnUnsupported(t *testing.T) {
type codecTester (line 176) | type codecTester struct
method UnsupportedTypes (line 178) | func (ct *codecTester) UnsupportedTypes() []drivertest.UnsupportedType {
method NativeEncode (line 182) | func (ct *codecTester) NativeEncode(obj any) (any, error) {
method NativeDecode (line 186) | func (ct *codecTester) NativeDecode(value, dest any) error {
method DocstoreEncode (line 190) | func (ct *codecTester) DocstoreEncode(obj any) (any, error) {
method DocstoreDecode (line 194) | func (ct *codecTester) DocstoreDecode(value, dest any) error {
FILE: docstore/awsdynamodb/v2/dynamo.go
type collection (line 64) | type collection struct
method Key (line 151) | func (c *collection) Key(doc driver.Document) (any, error) {
method RevisionField (line 163) | func (c *collection) RevisionField() string { return c.opts.RevisionFi...
method RunActions (line 165) | func (c *collection) RunActions(ctx context.Context, actions []*driver...
method runGets (line 180) | func (c *collection) runGets(ctx context.Context, actions []*driver.Ac...
method batchGet (line 203) | func (c *collection) batchGet(ctx context.Context, gets []*driver.Acti...
method runWrites (line 307) | func (c *collection) runWrites(ctx context.Context, writes []*driver.A...
method newWriteOp (line 345) | func (c *collection) newWriteOp(a *driver.Action, opts *driver.RunActi...
method newPut (line 358) | func (c *collection) newPut(a *driver.Action, opts *driver.RunActionsO...
method runPut (line 416) | func (c *collection) runPut(ctx context.Context, dput *dyn2Types.Put, ...
method newDelete (line 442) | func (c *collection) newDelete(a *driver.Action, opts *driver.RunActio...
method newUpdate (line 487) | func (c *collection) newUpdate(a *driver.Action, opts *driver.RunActio...
method onSuccess (line 551) | func (c *collection) onSuccess(op *writeOp) error {
method missingKeyField (line 562) | func (c *collection) missingKeyField(m map[string]dyn2Types.AttributeV...
method precondition (line 585) | func (c *collection) precondition(a *driver.Action) (*expression.Condi...
method transactWrite (line 640) | func (c *collection) transactWrite(ctx context.Context, actions []*dri...
method RevisionToBytes (line 693) | func (c *collection) RevisionToBytes(rev any) ([]byte, error) {
method BytesToRevision (line 702) | func (c *collection) BytesToRevision(b []byte) (any, error) {
method As (line 706) | func (c *collection) As(i any) bool {
method ErrorAs (line 716) | func (c *collection) ErrorAs(err error, i any) bool {
method ErrorCode (line 729) | func (c *collection) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 794) | func (c *collection) Close() error { return nil }
type FallbackFunc (line 75) | type FallbackFunc
type Options (line 78) | type Options struct
type RunQueryFunc (line 118) | type RunQueryFunc
function OpenCollection (line 121) | func OpenCollection(db *dyn.Client, tableName, partitionKey, sortKey str...
function newCollection (line 129) | func newCollection(db *dyn.Client, tableName, partitionKey, sortKey stri...
function mapActionIndices (line 298) | func mapActionIndices(actions []*driver.Action, start, end int) map[any]...
type writeOp (line 337) | type writeOp struct
function revisionPrecondition (line 617) | func revisionPrecondition(doc driver.Document, revField string) (*expres...
FILE: docstore/awsdynamodb/v2/dynamo_test.go
constant region (line 52) | region = "us-east-2"
constant collectionName1 (line 53) | collectionName1 = "docstore-test-1"
constant collectionName2 (line 54) | collectionName2 = "docstore-test-2"
constant collectionName3 (line 55) | collectionName3 = "docstore-test-3"
type harness (line 58) | type harness struct
method SupportsAtomicWrites (line 63) | func (h *harness) SupportsAtomicWrites() bool {
method BeforeDoTypes (line 79) | func (*harness) BeforeDoTypes() []any {
method BeforeQueryTypes (line 86) | func (*harness) BeforeQueryTypes() []any {
method RevisionsEqual (line 90) | func (*harness) RevisionsEqual(rev1, rev2 any) bool {
method Close (line 94) | func (h *harness) Close() {
method MakeCollection (line 98) | func (h *harness) MakeCollection(_ context.Context, kind drivertest.Co...
function newHarness (line 67) | func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, ...
function collectHighScores (line 124) | func collectHighScores(ctx context.Context, iter driver.DocumentIterator...
type highScoreSliceIterator (line 141) | type highScoreSliceIterator struct
method Next (line 146) | func (it *highScoreSliceIterator) Next(ctx context.Context, doc driver...
method Stop (line 159) | func (*highScoreSliceIterator) Stop() {}
method As (line 160) | func (*highScoreSliceIterator) As(any) bool { return false }
type verifyAs (line 162) | type verifyAs struct
method Name (line 164) | func (verifyAs) Name() string {
method CollectionCheck (line 168) | func (verifyAs) CollectionCheck(coll *docstore.Collection) error {
method QueryCheck (line 176) | func (verifyAs) QueryCheck(it *docstore.DocumentIterator) error {
method ErrorCheck (line 185) | func (v verifyAs) ErrorCheck(k *docstore.Collection, err error) error {
function TestConformance (line 193) | func TestConformance(t *testing.T) {
function BenchmarkConformance (line 200) | func BenchmarkConformance(b *testing.B) {
function TestQueryErrors (line 214) | func TestQueryErrors(t *testing.T) {
FILE: docstore/awsdynamodb/v2/example_test.go
function ExampleOpenCollection (line 27) | func ExampleOpenCollection() {
function Example_openCollectionFromURL (line 41) | func Example_openCollectionFromURL() {
FILE: docstore/awsdynamodb/v2/query.go
method RunGetQuery (line 45) | func (c *collection) RunGetQuery(ctx context.Context, q *driver.Query) (...
method checkPlan (line 69) | func (c *collection) checkPlan(qr *queryRunner) error {
method planQuery (line 76) | func (c *collection) planQuery(q *driver.Query) (*queryRunner, error) {
method bestQueryable (line 164) | func (c *collection) bestQueryable(q *driver.Query) (indexName *string, ...
function localFieldsIncluded (line 220) | func localFieldsIncluded(q *driver.Query, li dyn2Types.LocalSecondaryInd...
function orderingConsistent (line 226) | func orderingConsistent(q *driver.Query, sortField string) bool {
method globalFieldsIncluded (line 235) | func (c *collection) globalFieldsIncluded(q *driver.Query, gi dyn2Types....
function keyAttributes (line 269) | func keyAttributes(ks []dyn2Types.KeySchemaElement) (pkey, skey string) {
function hasFilter (line 284) | func hasFilter(q *driver.Query, field string) bool {
function hasEqualityFilter (line 297) | func hasEqualityFilter(q *driver.Query, field string) bool {
type queryRunner (line 306) | type queryRunner struct
method run (line 313) | func (qr *queryRunner) run(ctx context.Context, startAfter avmap) (ite...
method queryPlan (line 528) | func (qr *queryRunner) queryPlan() string {
function processFilters (line 372) | func processFilters(cb expression.Builder, fs []driver.Filter, pkey, ske...
function filtersToConditionBuilder (line 393) | func filtersToConditionBuilder(fs []driver.Filter) expression.ConditionB...
function toKeyCondition (line 405) | func toKeyCondition(f driver.Filter, pkey, skey string) (expression.KeyC...
function toFilter (line 428) | func toFilter(f driver.Filter) expression.ConditionBuilder {
function toInCondition (line 451) | func toInCondition(f driver.Filter) expression.ConditionBuilder {
type documentIterator (line 462) | type documentIterator struct
method Next (line 473) | func (it *documentIterator) Next(ctx context.Context, doc driver.Docum...
method next (line 483) | func (it *documentIterator) next(ctx context.Context, doc driver.Docum...
method Stop (line 511) | func (it *documentIterator) Stop() {
method As (line 516) | func (it *documentIterator) As(i any) bool {
method QueryPlan (line 520) | func (c *collection) QueryPlan(q *driver.Query) (string, error) {
function InMemorySortFallback (line 547) | func InMemorySortFallback(createDocument func() any) FallbackFunc {
type docsForSorting (line 596) | type docsForSorting struct
method Len (line 602) | func (d docsForSorting) Len() int { return len(d.docs) }
method Swap (line 604) | func (d docsForSorting) Swap(i, j int) {
method Less (line 609) | func (d docsForSorting) Less(i, j int) bool {
function compare (line 621) | func compare(v1, v2 any) int {
type sliceIterator (line 659) | type sliceIterator struct
method Next (line 664) | func (it *sliceIterator) Next(ctx context.Context, doc driver.Document...
method Stop (line 686) | func (*sliceIterator) Stop() {}
method As (line 687) | func (*sliceIterator) As(any) bool { return false }
function copyTopLevel (line 673) | func copyTopLevel(dest, src driver.Document) error {
FILE: docstore/awsdynamodb/v2/query_test.go
function TestPlanQuery (line 34) | func TestPlanQuery(t *testing.T) {
function TestQueryNoScans (line 386) | func TestQueryNoScans(t *testing.T) {
function keySchema (line 417) | func keySchema(pkey, skey string) []dyn2Types.KeySchemaElement {
function indexProjection (line 424) | func indexProjection(fields []string) *dyn2Types.Projection {
function TestGlobalFieldsIncluded (line 441) | func TestGlobalFieldsIncluded(t *testing.T) {
function TestCompare (line 510) | func TestCompare(t *testing.T) {
function TestCopyTopLevel (line 539) | func TestCopyTopLevel(t *testing.T) {
function Test_documentIterator_Next (line 585) | func Test_documentIterator_Next(t *testing.T) {
FILE: docstore/awsdynamodb/v2/urls.go
function init (line 30) | func init() {
type lazySessionOpener (line 34) | type lazySessionOpener struct
method OpenCollectionURL (line 40) | func (o *lazySessionOpener) OpenCollectionURL(ctx context.Context, u *...
constant Scheme (line 53) | Scheme = "dynamodb"
type URLOpener (line 71) | type URLOpener struct
method OpenCollectionURL (line 75) | func (o *URLOpener) OpenCollectionURL(_ context.Context, u *url.URL) (...
method processURL (line 83) | func (o *URLOpener) processURL(u *url.URL) (db *dyn.Client, tableName,...
function Dial (line 122) | func Dial(p aws.Config) (*dyn.Client, error) {
FILE: docstore/awsdynamodb/v2/urls_test.go
function TestProcessURL (line 22) | func TestProcessURL(t *testing.T) {
FILE: docstore/docstore.go
type Collection (line 49) | type Collection struct
method revisionField (line 97) | func (c *Collection) revisionField() string {
method Actions (line 116) | func (c *Collection) Actions() *ActionList {
method toDriverAction (line 403) | func (c *Collection) toDriverAction(a *Action) (*driver.Action, error) {
method Create (line 560) | func (c *Collection) Create(ctx context.Context, doc Document) error {
method Replace (line 569) | func (c *Collection) Replace(ctx context.Context, doc Document) error {
method Put (line 578) | func (c *Collection) Put(ctx context.Context, doc Document) error {
method Delete (line 587) | func (c *Collection) Delete(ctx context.Context, doc Document) error {
method Get (line 596) | func (c *Collection) Get(ctx context.Context, doc Document, fps ...Fie...
method Update (line 605) | func (c *Collection) Update(ctx context.Context, doc Document, mods Mo...
method RevisionToString (line 631) | func (c *Collection) RevisionToString(rev any) (string, error) {
method StringToRevision (line 644) | func (c *Collection) StringToRevision(s string) (any, error) {
method As (line 663) | func (c *Collection) As(i any) bool {
method Close (line 673) | func (c *Collection) Close() error {
method checkClosed (line 684) | func (c *Collection) checkClosed() error {
method ErrorAs (line 716) | func (c *Collection) ErrorAs(err error, i any) bool {
constant pkgName (line 56) | pkgName = "gocloud.dev/docstore"
function newCollection (line 70) | func newCollection(d driver.Collection) *Collection {
constant DefaultRevisionField (line 95) | DefaultRevisionField = "DocstoreRevision"
type FieldPath (line 112) | type FieldPath
type ActionList (line 135) | type ActionList struct
method add (line 152) | func (l *ActionList) add(a *Action) *ActionList {
method Create (line 172) | func (l *ActionList) Create(doc Document) *ActionList {
method Replace (line 184) | func (l *ActionList) Replace(doc Document) *ActionList {
method Put (line 197) | func (l *ActionList) Put(doc Document) *ActionList {
method Delete (line 207) | func (l *ActionList) Delete(doc Document) *ActionList {
method Get (line 226) | func (l *ActionList) Get(doc Document, fps ...FieldPath) *ActionList {
method Update (line 253) | func (l *ActionList) Update(doc Document, mods Mods) *ActionList {
method BeforeDo (line 320) | func (l *ActionList) BeforeDo(f func(asFunc func(any) bool) error) *Ac...
method Do (line 335) | func (l *ActionList) Do(ctx context.Context) error {
method do (line 340) | func (l *ActionList) do(ctx context.Context, withTracing bool) (err er...
method toDriverActions (line 366) | func (l *ActionList) toDriverActions() ([]*driver.Action, error) {
method String (line 531) | func (l *ActionList) String() string {
method AtomicWrites (line 540) | func (l *ActionList) AtomicWrites() *ActionList {
type Action (line 144) | type Action struct
method String (line 545) | func (a *Action) String() string {
type Mods (line 269) | type Mods
function Increment (line 277) | func Increment(amount any) any {
type ActionListError (line 284) | type ActionListError
method Error (line 291) | func (e ActionListError) Error() string {
method Unwrap (line 302) | func (e ActionListError) Unwrap() error {
function parseFieldPaths (line 451) | func parseFieldPaths(fps []FieldPath) ([][]string, error) {
function toDriverMods (line 463) | func toDriverMods(mods Mods) ([]driver.Mod, error) {
function fpHasPrefix (line 506) | func fpHasPrefix(fp, prefix []string) bool {
function isIncNumber (line 518) | func isIncNumber(x any) bool {
function parseFieldPath (line 612) | func parseFieldPath(fp FieldPath) ([]string, error) {
function wrapError (line 693) | func wrapError(c driver.Collection, err error) error {
FILE: docstore/docstore_test.go
type Book (line 28) | type Book struct
type Name (line 35) | type Name struct
function TestIsIncNumber (line 39) | func TestIsIncNumber(t *testing.T) {
function TestActionsDo (line 52) | func TestActionsDo(t *testing.T) {
function TestClosedErrors (line 111) | func TestClosedErrors(t *testing.T) {
function TestSerializeRevisionErrors (line 149) | func TestSerializeRevisionErrors(t *testing.T) {
type fakeDriverCollection (line 161) | type fakeDriverCollection struct
method Key (line 165) | func (fakeDriverCollection) Key(doc driver.Document) (any, error) {
method RevisionField (line 174) | func (fakeDriverCollection) RevisionField() string { return DefaultRev...
method Close (line 176) | func (fakeDriverCollection) Close() error { return nil }
method RunActions (line 178) | func (fakeDriverCollection) RunActions(ctx context.Context, actions []...
method RunGetQuery (line 182) | func (fakeDriverCollection) RunGetQuery(context.Context, *driver.Query...
type fakeDriverDocumentIterator (line 186) | type fakeDriverDocumentIterator struct
method Next (line 190) | func (fakeDriverDocumentIterator) Next(context.Context, driver.Documen...
FILE: docstore/driver/actionkind_string.go
function _ (line 7) | func _() {
constant _ActionKind_name (line 19) | _ActionKind_name = "CreateReplacePutGetDeleteUpdate"
method String (line 23) | func (i ActionKind) String() string {
FILE: docstore/driver/codec.go
type Encoder (line 48) | type Encoder interface
function Encode (line 114) | func Encode(v reflect.Value, e Encoder) error {
function encode (line 118) | func encode(v reflect.Value, enc Encoder) error {
function encodeList (line 211) | func encodeList(v reflect.Value, enc Encoder) error {
function encodeMap (line 229) | func encodeMap(v reflect.Value, enc Encoder) error {
function stringifyMapKey (line 252) | func stringifyMapKey(k reflect.Value) (string, error) {
function encodeStructWithFields (line 274) | func encodeStructWithFields(v reflect.Value, fields fields.List, e Encod...
function fieldByIndex (line 301) | func fieldByIndex(v reflect.Value, index []int) (reflect.Value, bool) {
type Decoder (line 324) | type Decoder interface
function Decode (line 375) | func Decode(v reflect.Value, d Decoder) error {
function decode (line 379) | func decode(v reflect.Value, d Decoder) error {
function decodeList (line 519) | func decodeList(v reflect.Value, d Decoder) error {
function prepareLength (line 561) | func prepareLength(v reflect.Value, wantLen int) error {
function decodeMap (line 595) | func decodeMap(v reflect.Value, d Decoder) error {
function unstringifyMapKey (line 631) | func unstringifyMapKey(key string, keyType reflect.Type) (reflect.Value,...
function decodeStruct (line 673) | func decodeStruct(v reflect.Value, d Decoder) error {
function fieldByIndexCreate (line 710) | func fieldByIndexCreate(v reflect.Value, index []int) (reflect.Value, bo...
function decodingError (line 726) | func decodingError(v reflect.Value, d Decoder) error {
function overflowError (line 730) | func overflowError(x any, t reflect.Type) error {
function wrap (line 734) | func wrap(err error, code gcerr.ErrorCode) error {
function IsEmptyValue (line 745) | func IsEmptyValue(v reflect.Value) bool {
type tagOptions (line 764) | type tagOptions struct
function parseTag (line 769) | func parseTag(t reflect.StructTag) (name string, keep bool, other any, e...
FILE: docstore/driver/codec_test.go
type myString (line 31) | type myString
type te (line 33) | type te struct
method MarshalText (line 35) | func (e te) MarshalText() ([]byte, error) {
method UnmarshalText (line 39) | func (e *te) UnmarshalText(b []byte) error {
type special (line 47) | type special
method MarshalBinary (line 49) | func (special) MarshalBinary() ([]byte, error) { panic("should never b...
method UnmarshalBinary (line 50) | func (*special) UnmarshalBinary([]byte) error { panic("should never b...
type badSpecial (line 52) | type badSpecial
type Embed1 (line 54) | type Embed1 struct
type Embed2 (line 57) | type Embed2 struct
type embed3 (line 61) | type embed3 struct
type embed4 (line 65) | type embed4 struct
type MyStruct (line 69) | type MyStruct struct
function TestEncode (line 84) | func TestEncode(t *testing.T) {
type badBinaryMarshaler (line 204) | type badBinaryMarshaler struct
method MarshalBinary (line 206) | func (badBinaryMarshaler) MarshalBinary() ([]byte, error) { return nil...
method UnmarshalBinary (line 207) | func (*badBinaryMarshaler) UnmarshalBinary([]byte) error { return err...
type badTextMarshaler (line 209) | type badTextMarshaler struct
method MarshalText (line 211) | func (badTextMarshaler) MarshalText() ([]byte, error) { return nil, er...
method UnmarshalText (line 212) | func (*badTextMarshaler) UnmarshalText([]byte) error { return errors....
function TestEncodeErrors (line 214) | func TestEncodeErrors(t *testing.T) {
type testEncoder (line 237) | type testEncoder struct
method EncodeNil (line 241) | func (e *testEncoder) EncodeNil() { e.val = nil }
method EncodeBool (line 242) | func (e *testEncoder) EncodeBool(x bool) { e.val = x }
method EncodeString (line 243) | func (e *testEncoder) EncodeString(x string) { e.val = x }
method EncodeInt (line 244) | func (e *testEncoder) EncodeInt(x int64) { e.val = x }
method EncodeUint (line 245) | func (e *testEncoder) EncodeUint(x uint64) { e.val = x }
method EncodeFloat (line 246) | func (e *testEncoder) EncodeFloat(x float64) { e.val = x }
method EncodeBytes (line 247) | func (e *testEncoder) EncodeBytes(x []byte) { e.val = x }
method EncodeSpecial (line 254) | func (e *testEncoder) EncodeSpecial(v reflect.Value) (bool, error) {
method ListIndex (line 264) | func (e *testEncoder) ListIndex(int) { panic("impossible") }
method MapKey (line 265) | func (e *testEncoder) MapKey(string) { panic("impossible") }
method EncodeList (line 267) | func (e *testEncoder) EncodeList(n int) Encoder {
method EncodeMap (line 273) | func (e *testEncoder) EncodeMap(n int) Encoder {
type listEncoder (line 279) | type listEncoder struct
method ListIndex (line 284) | func (e *listEncoder) ListIndex(i int) { e.s[i] = e.val }
type mapEncoder (line 286) | type mapEncoder struct
method MapKey (line 291) | func (e *mapEncoder) MapKey(k string) { e.m[k] = e.val }
function TestDecode (line 293) | func TestDecode(t *testing.T) {
function TestDecodeErrors (line 459) | func TestDecodeErrors(t *testing.T) {
function TestDecodeFail (line 583) | func TestDecodeFail(t *testing.T) {
type testDecoder (line 597) | type testDecoder struct
method String (line 602) | func (d testDecoder) String() string {
method AsNull (line 606) | func (d testDecoder) AsNull() bool {
method AsBool (line 610) | func (d testDecoder) AsBool() (bool, bool) { x, ok := d.val.(bool)...
method AsString (line 611) | func (d testDecoder) AsString() (string, bool) { x, ok := d.val.(strin...
method AsInt (line 613) | func (d testDecoder) AsInt() (int64, bool) {
method AsUint (line 624) | func (d testDecoder) AsUint() (uint64, bool) {
method AsFloat (line 635) | func (d testDecoder) AsFloat() (float64, bool) { x, ok := d.val.(float...
method AsBytes (line 636) | func (d testDecoder) AsBytes() ([]byte, bool) { x, ok := d.val.([]byt...
method ListLen (line 638) | func (d testDecoder) ListLen() (int, bool) {
method DecodeList (line 646) | func (d testDecoder) DecodeList(f func(i int, vd Decoder) bool) {
method MapLen (line 654) | func (d testDecoder) MapLen() (int, bool) {
method DecodeMap (line 661) | func (d testDecoder) DecodeMap(f func(key string, vd Decoder, exactMat...
method AsInterface (line 669) | func (d testDecoder) AsInterface() (any, error) {
method AsSpecial (line 673) | func (d testDecoder) AsSpecial(v reflect.Value) (bool, any, error) {
type failDecoder (line 685) | type failDecoder struct
method String (line 687) | func (failDecoder) String() string { ret...
method AsNull (line 688) | func (failDecoder) AsNull() bool { ret...
method AsBool (line 689) | func (failDecoder) AsBool() (bool, bool) { ret...
method AsString (line 690) | func (failDecoder) AsString() (string, bool) { ret...
method AsInt (line 691) | func (failDecoder) AsInt() (int64, bool) { ret...
method AsUint (line 692) | func (failDecoder) AsUint() (uint64, bool) { ret...
method AsFloat (line 693) | func (failDecoder) AsFloat() (float64, bool) { ret...
method AsBytes (line 694) | func (failDecoder) AsBytes() ([]byte, bool) { ret...
method ListLen (line 695) | func (failDecoder) ListLen() (int, bool) { ret...
method DecodeList (line 696) | func (failDecoder) DecodeList(func(i int, vd Decoder) bool) { pan...
method MapLen (line 697) | func (failDecoder) MapLen() (int, bool) { ret...
method DecodeMap (line 698) | func (failDecoder) DecodeMap(func(string, Decoder, bool) bool) { pan...
method AsSpecial (line 699) | func (failDecoder) AsSpecial(v reflect.Value) (bool, any, error) { ret...
method AsInterface (line 700) | func (failDecoder) AsInterface() (any, error) { ret...
FILE: docstore/driver/compare.go
function CompareTimes (line 28) | func CompareTimes(t1, t2 time.Time) int {
function CompareNumbers (line 47) | func CompareNumbers(n1, n2 any) (int, error) {
function toBigFloat (line 67) | func toBigFloat(x reflect.Value) (*big.Float, error) {
FILE: docstore/driver/compare_test.go
function TestCompareTimes (line 23) | func TestCompareTimes(t *testing.T) {
function TestCompareNumbers (line 41) | func TestCompareNumbers(t *testing.T) {
FILE: docstore/driver/document.go
type Document (line 27) | type Document struct
method GetField (line 63) | func (d Document) GetField(field string) (any, error) {
method getDocument (line 80) | func (d Document) getDocument(fp []string, create bool) (Document, err...
method Get (line 104) | func (d Document) Get(fp []string) (any, error) {
method structField (line 112) | func (d Document) structField(name string) (reflect.Value, error) {
method Set (line 129) | func (d Document) Set(fp []string, val any) error {
method SetField (line 138) | func (d Document) SetField(field string, value any) error {
method FieldNames (line 156) | func (d Document) FieldNames() []string {
method Encode (line 171) | func (d Document) Encode(e Encoder) error {
method Decode (line 179) | func (d Document) Decode(dec Decoder) error {
method HasField (line 187) | func (d Document) HasField(field string) bool {
method HasFieldFold (line 193) | func (d Document) HasFieldFold(field string) bool {
method hasField (line 197) | func (d Document) hasField(field string, exactMatch bool) bool {
function NewDocument (line 36) | func NewDocument(doc any) (Document, error) {
FILE: docstore/driver/document_test.go
type S (line 27) | type S struct
function TestNewDocument (line 32) | func TestNewDocument(t *testing.T) {
function TestGet (line 66) | func TestGet(t *testing.T) {
function TestSet (line 103) | func TestSet(t *testing.T) {
function TestGetField (line 143) | func TestGetField(t *testing.T) {
function TestFieldNames (line 183) | func TestFieldNames(t *testing.T) {
function TestHasField (line 218) | func TestHasField(t *testing.T) {
function TestHasFieldFold (line 258) | func TestHasFieldFold(t *testing.T) {
FILE: docstore/driver/driver.go
type Collection (line 27) | type Collection interface
type DeleteQueryer (line 102) | type DeleteQueryer interface
type UpdateQueryer (line 109) | type UpdateQueryer interface
type ActionKind (line 114) | type ActionKind
constant Create (line 118) | Create ActionKind = iota
constant Replace (line 119) | Replace
constant Put (line 120) | Put
constant Get (line 121) | Get
constant Delete (line 122) | Delete
constant Update (line 123) | Update
type Action (line 128) | type Action struct
type Mod (line 142) | type Mod struct
type IncOp (line 148) | type IncOp struct
type ActionListError (line 154) | type ActionListError
function NewActionListError (line 162) | func NewActionListError(errs []error) ActionListError {
type RunActionsOptions (line 176) | type RunActionsOptions struct
type Query (line 185) | type Query struct
type Filter (line 220) | type Filter struct
type DocumentIterator (line 227) | type DocumentIterator interface
constant EqualOp (line 245) | EqualOp = "="
FILE: docstore/driver/util.go
function UniqueString (line 27) | func UniqueString() string { return uuid.New().String() }
function SplitActions (line 35) | func SplitActions(actions []*Action, split func(a, b *Action) bool) [][]...
function GroupActions (line 58) | func GroupActions(actions []*Action) (beforeGets, getList, writeList, wr...
function AsFunc (line 111) | func AsFunc(val any) func(any) bool {
function GroupByFieldPath (line 129) | func GroupByFieldPath(gets []*Action) [][]*Action {
function fpsEqual (line 150) | func fpsEqual(fps1, fps2 [][]string) bool {
function FieldPathsEqual (line 164) | func FieldPathsEqual(fp1, fp2 []string) bool {
function FieldPathEqualsField (line 178) | func FieldPathEqualsField(fp []string, s string) bool {
type Throttle (line 184) | type Throttle struct
method Acquire (line 204) | func (t *Throttle) Acquire() {
method Release (line 212) | func (t *Throttle) Release() {
method Wait (line 221) | func (t *Throttle) Wait() {
function NewThrottle (line 192) | func NewThrottle(max int) *Throttle {
FILE: docstore/driver/util_test.go
function TestSplitActions (line 25) | func TestSplitActions(t *testing.T) {
function TestGroupActions (line 75) | func TestGroupActions(t *testing.T) {
method String (line 155) | func (a *Action) String() string { // for TestGroupActions
function TestAsFunc (line 159) | func TestAsFunc(t *testing.T) {
function TestGroupByFieldPath (line 176) | func TestGroupByFieldPath(t *testing.T) {
FILE: docstore/drivertest/driverbenchmark.go
function RunBenchmarks (line 28) | func RunBenchmarks(b *testing.B, coll *docstore.Collection) {
function benchmarkSingleActionPut (line 48) | func benchmarkSingleActionPut(b *testing.B, n int, coll *docstore.Collec...
function benchmarkSingleActionGet (line 69) | func benchmarkSingleActionGet(b *testing.B, n int, coll *docstore.Collec...
function benchmarkActionListPut (line 97) | func benchmarkActionListPut(b *testing.B, n int, coll *docstore.Collecti...
function benchmarkActionListGet (line 120) | func benchmarkActionListGet(b *testing.B, n int, coll *docstore.Collecti...
FILE: docstore/drivertest/drivertest.go
type ByteArray (line 42) | type ByteArray
type CollectionKind (line 45) | type CollectionKind
constant SingleKey (line 50) | SingleKey CollectionKind = iota
constant TwoKey (line 55) | TwoKey
constant AltRev (line 59) | AltRev
constant NoRev (line 62) | NoRev
type Harness (line 67) | type Harness interface
type HarnessMaker (line 94) | type HarnessMaker
type UnsupportedType (line 101) | type UnsupportedType
constant Uint (line 108) | Uint UnsupportedType = iota
constant Arrays (line 110) | Arrays
constant NanosecondTimes (line 112) | NanosecondTimes
constant BinarySet (line 114) | BinarySet
type CodecTester (line 119) | type CodecTester interface
type AsTest (line 128) | type AsTest interface
type verifyAsFailsOnNil (line 140) | type verifyAsFailsOnNil struct
method Name (line 142) | func (verifyAsFailsOnNil) Name() string {
method CollectionCheck (line 146) | func (verifyAsFailsOnNil) CollectionCheck(coll *docstore.Collection) e...
method QueryCheck (line 153) | func (verifyAsFailsOnNil) QueryCheck(it *docstore.DocumentIterator) er...
method ErrorCheck (line 160) | func (v verifyAsFailsOnNil) ErrorCheck(c *docstore.Collection, err err...
function RunConformanceTests (line 171) | func RunConformanceTests(t *testing.T, newHarness HarnessMaker, ct Codec...
function withCollection (line 219) | func withCollection(t *testing.T, newHarness HarnessMaker, kind Collecti...
function withRevCollections (line 235) | func withRevCollections(t *testing.T, newHarness HarnessMaker, f func(*t...
function withColl (line 266) | func withColl(t *testing.T, h Harness, kind CollectionKind, f func(*test...
constant KeyField (line 281) | KeyField = "name"
constant AlternateRevisionField (line 285) | AlternateRevisionField = "Etag"
function newDoc (line 289) | func newDoc(doc any) any {
function key (line 299) | func key(doc any) any {
function setKey (line 309) | func setKey(doc, key any) {
function revision (line 318) | func revision(doc any, revField string) any {
function setRevision (line 331) | func setRevision(doc, rev any, revField string) {
type docstruct (line 344) | type docstruct struct
function nonexistentDoc (line 357) | func nonexistentDoc() docmap { return docmap{KeyField: "doesNotExist"} }
function testCreate (line 359) | func testCreate(t *testing.T, coll *docstore.Collection, revField string) {
function testPut (line 422) | func testPut(t *testing.T, coll *docstore.Collection, revField string) {
function testReplace (line 515) | func testReplace(t *testing.T, coll *docstore.Collection, revField strin...
function checkNoRevisionField (line 565) | func checkNoRevisionField(t *testing.T, doc any, revField string) {
function checkHasRevisionField (line 577) | func checkHasRevisionField(t *testing.T, doc any, revField string) {
function testGet (line 589) | func testGet(t *testing.T, coll *docstore.Collection, revField string) {
function testDelete (line 698) | func testDelete(t *testing.T, coll *docstore.Collection, revField string) {
function testUpdate (line 756) | func testUpdate(t *testing.T, coll *docstore.Collection, revField string) {
function testRevisionField (line 868) | func testRevisionField(t *testing.T, coll *docstore.Collection, revField...
function testSerializeRevision (line 913) | func testSerializeRevision(t *testing.T, h Harness, coll *docstore.Colle...
function testData (line 939) | func testData(t *testing.T, _ Harness, coll *docstore.Collection) {
function testTypeDrivenDecode (line 988) | func testTypeDrivenDecode(t *testing.T, ct CodecTester) {
function testBlindDecode (line 1122) | func testBlindDecode(t *testing.T, ct CodecTester) {
function testBlindDecode1 (line 1132) | func testBlindDecode1(t *testing.T, encode func(any) (any, error), decod...
type docstoreRoundTrip (line 1201) | type docstoreRoundTrip struct
type nativeMinimal (line 1223) | type nativeMinimal struct
function testProto (line 1243) | func testProto(t *testing.T, _ Harness, coll *docstore.Collection) {
type HighScore (line 1280) | type HighScore struct
method key (line 1304) | func (h *HighScore) key() string {
method String (line 1315) | func (h *HighScore) String() string {
function newHighScore (line 1289) | func newHighScore() any { return &HighScore{} }
function HighScoreKey (line 1293) | func HighScoreKey(doc docstore.Document) any {
function barConcat (line 1311) | func barConcat(a, b any) string { return fmt.Sprintf("%v|%v", a, b) }
function highScoreLess (line 1313) | func highScoreLess(h1, h2 *HighScore) bool { return h1.key() < h2.key() }
function date (line 1319) | func date(month, day int) time.Time {
constant game1 (line 1324) | game1 = "Praise All Monsters"
constant game2 (line 1325) | game2 = "Zombie DMV"
constant game3 (line 1326) | game3 = "Days Gone"
function addHighScores (line 1340) | func addHighScores(t *testing.T, coll *docstore.Collection) {
function testGetQueryKeyField (line 1353) | func testGetQueryKeyField(t *testing.T, coll *docstore.Collection, revFi...
function sortByKeyField (line 1393) | func sortByKeyField(d1, d2 docmap) bool { return d1[KeyField].(string) <...
function testActionsWithCompositeID (line 1397) | func testActionsWithCompositeID(t *testing.T, _ Harness, coll *docstore....
function testGetQuery (line 1429) | func testGetQuery(t *testing.T, _ Harness, coll *docstore.Collection) {
function filterHighScores (line 1710) | func filterHighScores(hs []*HighScore, f func(*HighScore) bool) []*HighS...
function ClearCollection (line 1722) | func ClearCollection(fataler interface {
function forEach (line 1748) | func forEach(ctx context.Context, iter *docstore.DocumentIterator, creat...
function mustCollect (line 1765) | func mustCollect(ctx context.Context, t *testing.T, iter *docstore.Docum...
function mustCollectHighScores (line 1777) | func mustCollectHighScores(ctx context.Context, t *testing.T, iter *docs...
function collectHighScores (line 1787) | func collectHighScores(ctx context.Context, iter *docstore.DocumentItera...
function testMultipleActions (line 1796) | func testMultipleActions(t *testing.T, coll *docstore.Collection, revFie...
function testAtomicWrites (line 1913) | func testAtomicWrites(t *testing.T, coll *docstore.Collection, revField ...
function testAtomicWritesFail (line 1996) | func testAtomicWritesFail(t *testing.T, coll *docstore.Collection, revFi...
function testActionsOnStructNoRev (line 2075) | func testActionsOnStructNoRev(t *testing.T, _ Harness, coll *docstore.Co...
function testExampleInDoc (line 2107) | func testExampleInDoc(t *testing.T, _ Harness, coll *docstore.Collection) {
function testBeforeDo (line 2176) | func testBeforeDo(t *testing.T, newHarness HarnessMaker) {
function testBeforeQuery (line 2241) | func testBeforeQuery(t *testing.T, newHarness HarnessMaker) {
function testAs (line 2283) | func testAs(t *testing.T, coll *docstore.Collection, st AsTest) {
function clone (line 2330) | func clone(m docmap) docmap {
function cmpDiff (line 2336) | func cmpDiff(a, b any, opts ...cmp.Option) string {
function checkCode (line 2341) | func checkCode(t *testing.T, err error, code gcerrors.ErrorCode) {
FILE: docstore/drivertest/util.go
function MakeUniqueStringDeterministicForTesting (line 29) | func MakeUniqueStringDeterministicForTesting(seed int64) {
type randReader (line 34) | type randReader struct
method Read (line 39) | func (r *randReader) Read(buf []byte) (int, error) {
function MustDocument (line 46) | func MustDocument(doc any) driver.Document {
FILE: docstore/example_test.go
type Player (line 33) | type Player struct
function ExampleCollection_Actions_bulkWrite (line 39) | func ExampleCollection_Actions_bulkWrite() {
function ExampleCollection_Actions_getAfterWrite (line 57) | func ExampleCollection_Actions_getAfterWrite() {
function ExampleCollection_Update (line 74) | func ExampleCollection_Update() {
function ExampleOpenCollection (line 100) | func ExampleOpenCollection() {
function ExampleCollection_As (line 114) | func ExampleCollection_As() {
function ExampleCollection_ErrorAs (line 142) | func ExampleCollection_ErrorAs() {
function ExampleQuery_Get (line 169) | func ExampleQuery_Get() {
function ExampleQuery_Get_full (line 193) | func ExampleQuery_Get_full() {
function Example_optimisticLocking (line 233) | func Example_optimisticLocking() {
FILE: docstore/gcpfirestore/codec.go
function encodeDoc (line 34) | func encodeDoc(doc driver.Document, nameField string) (*pb.Document, err...
function encodeValue (line 50) | func encodeValue(x any) (*pb.Value, error) {
type encoder (line 59) | type encoder struct
method EncodeNil (line 65) | func (e *encoder) EncodeNil() { e.pv = nullValue }
method EncodeBool (line 66) | func (e *encoder) EncodeBool(x bool) { e.pv = &pb.Value{ValueType:...
method EncodeInt (line 67) | func (e *encoder) EncodeInt(x int64) { e.pv = &pb.Value{ValueType:...
method EncodeUint (line 68) | func (e *encoder) EncodeUint(x uint64) { e.pv = &pb.Value{ValueType:...
method EncodeBytes (line 69) | func (e *encoder) EncodeBytes(x []byte) { e.pv = &pb.Value{ValueType:...
method EncodeFloat (line 70) | func (e *encoder) EncodeFloat(x float64) { e.pv = floatval(x) }
method EncodeString (line 71) | func (e *encoder) EncodeString(x string) { e.pv = &pb.Value{ValueType:...
method ListIndex (line 73) | func (e *encoder) ListIndex(int) { panic("impossible") }
method MapKey (line 74) | func (e *encoder) MapKey(string) { panic("impossible") }
method EncodeList (line 76) | func (e *encoder) EncodeList(n int) driver.Encoder {
method EncodeMap (line 82) | func (e *encoder) EncodeMap(n int) driver.Encoder {
method EncodeSpecial (line 96) | func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) {
type listEncoder (line 121) | type listEncoder struct
method ListIndex (line 126) | func (e *listEncoder) ListIndex(i int) { e.s[i] = e.pv }
type mapEncoder (line 128) | type mapEncoder struct
method MapKey (line 133) | func (e *mapEncoder) MapKey(k string) { e.m[k] = e.pv }
function floatval (line 135) | func floatval(x float64) *pb.Value { return &pb.Value{ValueType: &pb.Val...
function decodeDoc (line 140) | func decodeDoc(pdoc *pb.Document, ddoc driver.Document, nameField, revFi...
type decoder (line 158) | type decoder struct
method String (line 162) | func (d decoder) String() string { // for debugging
method AsNull (line 166) | func (d decoder) AsNull() bool {
method AsBool (line 171) | func (d decoder) AsBool() (bool, bool) {
method AsString (line 178) | func (d decoder) AsString() (string, bool) {
method AsInt (line 185) | func (d decoder) AsInt() (int64, bool) {
method AsUint (line 192) | func (d decoder) AsUint() (uint64, bool) {
method AsFloat (line 199) | func (d decoder) AsFloat() (float64, bool) {
method AsBytes (line 206) | func (d decoder) AsBytes() ([]byte, bool) {
method AsInterface (line 214) | func (d decoder) AsInterface() (any, error) {
method ListLen (line 265) | func (d decoder) ListLen() (int, bool) {
method DecodeList (line 273) | func (d decoder) DecodeList(f func(int, driver.Decoder) bool) {
method MapLen (line 281) | func (d decoder) MapLen() (int, bool) {
method DecodeMap (line 289) | func (d decoder) DecodeMap(f func(string, driver.Decoder, bool) bool) {
method AsSpecial (line 297) | func (d decoder) AsSpecial(v reflect.Value) (bool, any, error) {
function decodeValue (line 218) | func decodeValue(v *pb.Value) (any, error) {
FILE: docstore/gcpfirestore/codec_test.go
function TestCodecSpecial (line 31) | func TestCodecSpecial(t *testing.T) {
FILE: docstore/gcpfirestore/example_test.go
function ExampleOpenCollection (line 26) | func ExampleOpenCollection() {
function ExampleOpenCollectionWithNameFunc (line 47) | func ExampleOpenCollectionWithNameFunc() {
function Example_openCollectionFromURL (line 79) | func Example_openCollectionFromURL() {
FILE: docstore/gcpfirestore/fs.go
function Dial (line 97) | func Dial(ctx context.Context, ts gcp.TokenSource) (*vkit.Client, func()...
type collection (line 124) | type collection struct
method Key (line 234) | func (c *collection) Key(doc driver.Document) (any, error) {
method RevisionField (line 261) | func (c *collection) RevisionField() string {
method RunActions (line 266) | func (c *collection) RunActions(ctx context.Context, actions []*driver...
method runGets (line 300) | func (c *collection) runGets(ctx context.Context, actions []*driver.Ac...
method batchGet (line 308) | func (c *collection) batchGet(ctx context.Context, gets []*driver.Acti...
method newGetRequest (line 363) | func (c *collection) newGetRequest(gets []*driver.Action) (*pb.BatchGe...
method buildCommitCalls (line 388) | func (c *collection) buildCommitCalls(actions []*driver.Action, errs [...
method buildAtomicWritesCommitCall (line 420) | func (c *collection) buildAtomicWritesCommitCall(actions []*driver.Act...
method actionToWrites (line 437) | func (c *collection) actionToWrites(a *driver.Action) ([]*pb.Write, st...
method putWrite (line 494) | func (c *collection) putWrite(doc driver.Document, docName string, pc ...
method deleteWrite (line 506) | func (c *collection) deleteWrite(doc driver.Document, docName string) ...
method updateWrites (line 519) | func (c *collection) updateWrites(doc driver.Document, docName string,...
method doCommitCall (line 603) | func (c *collection) doCommitCall(ctx context.Context, call *commitCal...
method commit (line 650) | func (c *collection) commit(ctx context.Context, ws []*pb.Write, opts ...
method revisionPrecondition (line 744) | func (c *collection) revisionPrecondition(doc driver.Document) (*pb.Pr...
method revisionTimestamp (line 754) | func (c *collection) revisionTimestamp(doc driver.Document) (*tspb.Tim...
method ErrorCode (line 778) | func (c *collection) ErrorCode(err error) gcerrors.ErrorCode {
method RevisionToBytes (line 796) | func (c *collection) RevisionToBytes(rev any) ([]byte, error) {
method BytesToRevision (line 805) | func (c *collection) BytesToRevision(b []byte) (any, error) {
method As (line 813) | func (c *collection) As(i any) bool {
method ErrorAs (line 823) | func (c *collection) ErrorAs(err error, i any) bool {
method Close (line 837) | func (c *collection) Close() error { return nil }
type Options (line 134) | type Options struct
function CollectionResourceID (line 150) | func CollectionResourceID(projectID, collPath string) string {
function CollectionResourceIDWithDatabase (line 156) | func CollectionResourceIDWithDatabase(projectID, databaseID, collPath st...
function OpenCollection (line 170) | func OpenCollection(client *vkit.Client, collResourceID, nameField strin...
function OpenCollectionWithNameFunc (line 196) | func OpenCollectionWithNameFunc(client *vkit.Client, collResourceID stri...
function newCollection (line 206) | func newCollection(client *vkit.Client, collResourceID, nameField string...
type commitCall (line 381) | type commitCall struct
function newUpdateWrites (line 531) | func newUpdateWrites(docPath string, ts *tspb.Timestamp, fields map[stri...
function processMods (line 568) | func processMods(mods []driver.Mod) (fields map[string]*pb.Value, maskPa...
function hasFollowingTransform (line 635) | func hasFollowingTransform(writes []*pb.Write, i int) bool {
function setAtFieldPath (line 675) | func setAtFieldPath(m map[string]*pb.Value, fp []string, val *pb.Value) ...
function getParentMap (line 689) | func getParentMap(m map[string]*pb.Value, fp []string, create bool) (map...
function toServiceFieldPath (line 712) | func toServiceFieldPath(fp []string) string {
function toServiceFieldPathComponent (line 726) | func toServiceFieldPathComponent(key string) string {
function preconditionFromTimestamp (line 771) | func preconditionFromTimestamp(ts *tspb.Timestamp) *pb.Precondition {
constant resourcePrefixHeader (line 784) | resourcePrefixHeader = "google-cloud-resource-prefix"
function withResourceHeader (line 788) | func withResourceHeader(ctx context.Context, resource string) context.Co...
FILE: docstore/gcpfirestore/fs_test.go
constant projectID (line 36) | projectID = "go-cloud-test-216917"
constant collectionName1 (line 37) | collectionName1 = "docstore-test-1"
constant collectionName2 (line 38) | collectionName2 = "docstore-test-2"
constant collectionName3 (line 39) | collectionName3 = "docstore-test-3"
constant endPoint (line 40) | endPoint = "firestore.googleapis.com:443"
type harness (line 43) | type harness struct
method SupportsAtomicWrites (line 48) | func (h *harness) SupportsAtomicWrites() bool {
method MakeCollection (line 64) | func (h *harness) MakeCollection(_ context.Context, kind drivertest.Co...
method BeforeDoTypes (line 81) | func (*harness) BeforeDoTypes() []any {
method BeforeQueryTypes (line 85) | func (*harness) BeforeQueryTypes() []any {
method RevisionsEqual (line 89) | func (*harness) RevisionsEqual(rev1, rev2 any) bool {
method Close (line 93) | func (h *harness) Close() {
function newHarness (line 52) | func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, ...
type codecTester (line 99) | type codecTester struct
method UnsupportedTypes (line 103) | func (*codecTester) UnsupportedTypes() []drivertest.UnsupportedType {
method NativeEncode (line 107) | func (c *codecTester) NativeEncode(x any) (any, error) {
method NativeDecode (line 111) | func (c *codecTester) NativeDecode(value, dest any) error {
method DocstoreEncode (line 115) | func (c *codecTester) DocstoreEncode(x any) (any, error) {
method DocstoreDecode (line 126) | func (c *codecTester) DocstoreDecode(value, dest any) error {
type verifyAs (line 133) | type verifyAs struct
method Name (line 135) | func (verifyAs) Name() string {
method CollectionCheck (line 139) | func (verifyAs) CollectionCheck(coll *docstore.Collection) error {
method QueryCheck (line 147) | func (verifyAs) QueryCheck(it *docstore.DocumentIterator) error {
method ErrorCheck (line 156) | func (v verifyAs) ErrorCheck(c *docstore.Collection, err error) error {
function TestConformance (line 164) | func TestConformance(t *testing.T) {
function BenchmarkConformance (line 173) | func BenchmarkConformance(b *testing.B) {
function TestResourceIDRegexp (line 188) | func TestResourceIDRegexp(t *testing.T) {
FILE: docstore/gcpfirestore/native_codec_test.go
type nativeCodec (line 37) | type nativeCodec struct
method interceptUnary (line 76) | func (c *nativeCodec) interceptUnary(_ context.Context, method string,...
method interceptStream (line 85) | func (c *nativeCodec) interceptStream(ctx context.Context, desc *grpc....
method Encode (line 113) | func (c *nativeCodec) Encode(x any) (*pb.Document, error) {
method Decode (line 122) | func (c *nativeCodec) Decode(value *pb.Document, dest any) error {
function newNativeCodec (line 42) | func newNativeCodec() (*nativeCodec, error) {
type clientStream (line 90) | type clientStream struct
method RecvMsg (line 95) | func (cs *clientStream) RecvMsg(m any) error {
method Context (line 106) | func (cs *clientStream) Context() context.Context { return cs.ctx }
method SendMsg (line 107) | func (cs *clientStream) SendMsg(m any) error { return nil }
method Header (line 108) | func (cs *clientStream) Header() (metadata.MD, error) { return nil, nil }
method Trailer (line 109) | func (cs *clientStream) Trailer() metadata.MD { return nil }
method CloseSend (line 110) | func (cs *clientStream) CloseSend() error { return nil }
function TestNativeCodec (line 131) | func TestNativeCodec(t *testing.T) {
FILE: docstore/gcpfirestore/query.go
method RunGetQuery (line 35) | func (c *collection) RunGetQuery(ctx context.Context, q *driver.Query) (...
method newDocIterator (line 39) | func (c *collection) newDocIterator(ctx context.Context, q *driver.Query...
type docIterator (line 71) | type docIterator struct
method Next (line 81) | func (it *docIterator) Next(ctx context.Context, doc driver.Document) ...
method nextResponse (line 89) | func (it *docIterator) nextResponse(ctx context.Context) (*pb.RunQuery...
method evaluateLocalFilters (line 110) | func (it *docIterator) evaluateLocalFilters(pdoc *pb.Document) (bool, ...
method Stop (line 190) | func (it *docIterator) Stop() { it.cancel() }
method As (line 192) | func (it *docIterator) As(i any) bool {
function evaluateFilter (line 131) | func evaluateFilter(f driver.Filter, doc driver.Document) bool {
function applyComparison (line 173) | func applyComparison(op string, c int) bool {
method queryToProto (line 203) | func (c *collection) queryToProto(q *driver.Query) (*pb.StructuredQuery,...
function splitFilters (line 273) | func splitFilters(fs []driver.Filter) (sendToFirestore, evaluateLocally ...
method filterToProto (line 292) | func (c *collection) filterToProto(f driver.Filter) (*pb.StructuredQuery...
function unaryOpFor (line 326) | func unaryOpFor(value any) (pb.StructuredQuery_UnaryFilter_Operator, boo...
function isNaN (line 337) | func isNaN(x any) bool {
function fieldRef (line 348) | func fieldRef(fp []string) *pb.StructuredQuery_FieldReference {
function newFieldFilter (line 352) | func newFieldFilter(fp []string, op string, val *pb.Value) (*pb.Structur...
method QueryPlan (line 386) | func (c *collection) QueryPlan(q *driver.Query) (string, error) {
FILE: docstore/gcpfirestore/query_test.go
function TestFilterToProto (line 29) | func TestFilterToProto(t *testing.T) {
function TestSplitFilters (line 88) | func TestSplitFilters(t *testing.T) {
function TestEvaluateFilter (line 145) | func TestEvaluateFilter(t *testing.T) {
FILE: docstore/gcpfirestore/urls.go
function init (line 31) | func init() {
type lazyCredsOpener (line 35) | type lazyCredsOpener struct
method OpenCollectionURL (line 41) | func (o *lazyCredsOpener) OpenCollectionURL(ctx context.Context, u *ur...
constant Scheme (line 68) | Scheme = "firestore"
type URLOpener (line 82) | type URLOpener struct
method OpenCollectionURL (line 89) | func (o *URLOpener) OpenCollectionURL(ctx context.Context, u *url.URL)...
FILE: docstore/gcpfirestore/urls_test.go
function TestOpenCollectionFromURL (line 25) | func TestOpenCollectionFromURL(t *testing.T) {
FILE: docstore/internal/fields/fields.go
type Field (line 75) | type Field struct
type ParseTagFunc (line 89) | type ParseTagFunc
type ValidateFunc (line 93) | type ValidateFunc
type LeafTypesFunc (line 97) | type LeafTypesFunc
type Cache (line 102) | type Cache struct
method Fields (line 171) | func (c *Cache) Fields(t reflect.Type) (List, error) {
method cachedTypeFields (line 228) | func (c *Cache) cachedTypeFields(t reflect.Type) (List, error) {
method typeFields (line 245) | func (c *Cache) typeFields(t reflect.Type) ([]Field, error) {
method listFields (line 277) | func (c *Cache) listFields(t reflect.Type) ([]Field, error) {
function NewCache (line 121) | func NewCache(parseTag ParseTagFunc, validate ValidateFunc, leafTypes Le...
type fieldScan (line 146) | type fieldScan struct
type List (line 179) | type List
method MatchExact (line 183) | func (l List) MatchExact(name string) *Field {
method MatchExactBytes (line 188) | func (l List) MatchExactBytes(name []byte) *Field {
method MatchFold (line 201) | func (l List) MatchFold(name string) *Field {
method MatchFoldBytes (line 206) | func (l List) MatchFoldBytes(name []byte) *Field {
type cacheValue (line 220) | type cacheValue struct
function newField (line 396) | func newField(f reflect.StructField, tagName string, other any, index []...
type byName (line 419) | type byName
method Len (line 421) | func (x byName) Len() int { return len(x) }
method Swap (line 423) | func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
method Less (line 425) | func (x byName) Less(i, j int) bool {
type byIndex (line 439) | type byIndex
method Len (line 441) | func (x byIndex) Len() int { return len(x) }
method Swap (line 443) | func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
method Less (line 445) | func (x byIndex) Less(i, j int) bool {
function dominantField (line 465) | func dominantField(fs []Field) (Field, bool) {
function ParseStandardTag (line 484) | func ParseStandardTag(key string, t reflect.StructTag) (name string, kee...
FILE: docstore/internal/fields/fields_test.go
type embed1 (line 28) | type embed1 struct
type embed2 (line 35) | type embed2 struct
type embed3 (line 41) | type embed3 struct
type embed4 (line 46) | type embed4 struct
type embed5 (line 52) | type embed5 struct
type Anonymous (line 56) | type Anonymous
type S1 (line 58) | type S1 struct
type Time (line 67) | type Time struct
function field (line 73) | func field(name string, tval any, index ...int) *Field {
function tfield (line 82) | func tfield(name string, tval any, index ...int) *Field {
function TestFieldsNoTags (line 92) | func TestFieldsNoTags(t *testing.T) {
function TestAgainstJSONEncodingNoTags (line 113) | func TestAgainstJSONEncodingNoTags(t *testing.T) {
function TestAgainstJSONEncodingEmbeddedTime (line 159) | func TestAgainstJSONEncodingEmbeddedTime(t *testing.T) {
type S2 (line 182) | type S2 struct
type Embed (line 195) | type Embed struct
type tEmbed1 (line 199) | type tEmbed1 struct
type tEmbed2 (line 204) | type tEmbed2 struct
function jsonTagParser (line 209) | func jsonTagParser(t reflect.StructTag) (name string, keep bool, other a...
function validateFunc (line 214) | func validateFunc(t reflect.Type) (err error) {
function TestFieldsWithTags (line 228) | func TestFieldsWithTags(t *testing.T) {
function TestAgainstJSONEncodingWithTags (line 247) | func TestAgainstJSONEncodingWithTags(t *testing.T) {
function TestUnexportedAnonymousNonStruct (line 278) | func TestUnexportedAnonymousNonStruct(t *testing.T) {
function TestUnexportedAnonymousStruct (line 301) | func TestUnexportedAnonymousStruct(t *testing.T) {
function TestDominantField (line 320) | func TestDominantField(t *testing.T) {
function TestIgnore (line 349) | func TestIgnore(t *testing.T) {
function TestParsedTag (line 363) | func TestParsedTag(t *testing.T) {
function TestValidateFunc (line 382) | func TestValidateFunc(t *testing.T) {
function compareFields (line 403) | func compareFields(got []Field, want []*Field) (msg string, ok bool) {
function fieldsEqual (line 417) | func fieldsEqual(f1, f2 *Field) bool {
function setFields (line 430) | func setFields(fields []Field, dst, src any) {
function jsonRoundTrip (line 440) | func jsonRoundTrip(t *testing.T, in, out any) {
type S3 (line 452) | type S3 struct
type S4 (line 461) | type S4 struct
function TestMatchExact (line 466) | func TestMatchExact(t *testing.T) {
function TestMatchFold (line 494) | func TestMatchFold(t *testing.T) {
function TestAgainstJSONMatchingField (line 525) | func TestAgainstJSONMatchingField(t *testing.T) {
function TestTagErrors (line 562) | func TestTagErrors(t *testing.T) {
FILE: docstore/internal/fields/fold.go
constant caseMask (line 26) | caseMask = ^byte(0x20)
constant kelvin (line 27) | kelvin = '\u212a'
constant smallLongEss (line 28) | smallLongEss = '\u017f'
function foldFunc (line 47) | func foldFunc(s []byte) func(s, t []byte) bool {
function equalFoldRight (line 75) | func equalFoldRight(s, t []byte) bool {
function asciiEqualFold (line 120) | func asciiEqualFold(s, t []byte) bool {
function simpleLetterEqualFold (line 144) | func simpleLetterEqualFold(s, t []byte) bool {
FILE: docstore/internal/fields/fold_test.go
function TestFold (line 55) | func TestFold(t *testing.T) {
function TestFoldAgainstUnicode (line 67) | func TestFoldAgainstUnicode(t *testing.T) {
function isASCIILetter (line 127) | func isASCIILetter(b byte) bool {
FILE: docstore/memdocstore/codec.go
function encodeDoc (line 28) | func encodeDoc(doc driver.Document) (storedDoc, error) {
function encodeValue (line 36) | func encodeValue(v any) (any, error) {
type encoder (line 44) | type encoder struct
method EncodeNil (line 48) | func (e *encoder) EncodeNil() { e.val = nil }
method EncodeBool (line 49) | func (e *encoder) EncodeBool(x bool) { e.val = x }
method EncodeInt (line 50) | func (e *encoder) EncodeInt(x int64) { e.val = x }
method EncodeUint (line 51) | func (e *encoder) EncodeUint(x uint64) { e.val = int64(x) }
method EncodeBytes (line 52) | func (e *encoder) EncodeBytes(x []byte) { e.val = x }
method EncodeFloat (line 53) | func (e *encoder) EncodeFloat(x float64) { e.val = x }
method EncodeString (line 54) | func (e *encoder) EncodeString(x string) { e.val = x }
method ListIndex (line 55) | func (e *encoder) ListIndex(int) { panic("impossible") }
method MapKey (line 56) | func (e *encoder) MapKey(string) { panic("impossible") }
method EncodeSpecial (line 60) | func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) {
method EncodeList (line 68) | func (e *encoder) EncodeList(n int) driver.Encoder {
method EncodeMap (line 87) | func (e *encoder) EncodeMap(n int) driver.Encoder {
type listEncoder (line 75) | type listEncoder struct
method ListIndex (line 80) | func (e *listEncoder) ListIndex(i int) { e.s[i] = e.val }
type mapEncoder (line 82) | type mapEncoder struct
method MapKey (line 93) | func (e *mapEncoder) MapKey(k string) { e.m[k] = e.val }
function decodeDoc (line 98) | func decodeDoc(m storedDoc, ddoc driver.Document, fps [][]string) error {
type decoder (line 122) | type decoder struct
method String (line 126) | func (d decoder) String() string {
method AsNull (line 130) | func (d decoder) AsNull() bool {
method AsBool (line 134) | func (d decoder) AsBool() (bool, bool) {
method AsString (line 139) | func (d decoder) AsString() (string, bool) {
method AsInt (line 144) | func (d decoder) AsInt() (int64, bool) {
method AsUint (line 149) | func (d decoder) AsUint() (uint64, bool) {
method AsFloat (line 154) | func (d decoder) AsFloat() (float64, bool) {
method AsBytes (line 159) | func (d decoder) AsBytes() ([]byte, bool) {
method AsInterface (line 164) | func (d decoder) AsInterface() (any, error) {
method ListLen (line 168) | func (d decoder) ListLen() (int, bool) {
method DecodeList (line 175) | func (d decoder) DecodeList(f func(i int, d2 driver.Decoder) bool) {
method MapLen (line 183) | func (d decoder) MapLen() (int, bool) {
method DecodeMap (line 190) | func (d decoder) DecodeMap(f func(key string, d2 driver.Decoder, _ boo...
method AsSpecial (line 198) | func (d decoder) AsSpecial(v reflect.Value) (bool, any, error) {
FILE: docstore/memdocstore/codec_test.go
type aStruct (line 25) | type aStruct struct
type embed (line 36) | type embed struct
function TestEncodeDoc (line 40) | func TestEncodeDoc(t *testing.T) {
function TestDecodeDoc (line 99) | func TestDecodeDoc(t *testing.T) {
FILE: docstore/memdocstore/example_test.go
function ExampleOpenCollection (line 25) | func ExampleOpenCollection() {
function ExampleOpenCollectionWithKeyFunc (line 37) | func ExampleOpenCollectionWithKeyFunc() {
function Example_openCollectionFromURL (line 60) | func Example_openCollectionFromURL() {
FILE: docstore/memdocstore/mem.go
type Options (line 59) | type Options struct
function OpenCollection (line 90) | func OpenCollection(keyField string, opts *Options) (*docstore.Collectio...
function OpenCollectionWithKeyFunc (line 106) | func OpenCollectionWithKeyFunc(keyFunc func(docstore.Document) any, opts...
function newCollection (line 114) | func newCollection(keyField string, keyFunc func(docstore.Document) any,...
type storedDoc (line 145) | type storedDoc
type collection (line 147) | type collection struct
method Key (line 156) | func (c *collection) Key(doc driver.Document) (any, error) {
method RevisionField (line 168) | func (c *collection) RevisionField() string {
method ErrorCode (line 173) | func (c *collection) ErrorCode(err error) gcerrors.ErrorCode {
method RunActions (line 178) | func (c *collection) RunActions(ctx context.Context, actions []*driver...
method runAtomicWrites (line 219) | func (c *collection) runAtomicWrites(ctx context.Context, actions []*d...
method runAction (line 277) | func (c *collection) runAction(ctx context.Context, a *driver.Action) ...
method executeAction (line 318) | func (c *collection) executeAction(a *driver.Action, current storedDoc...
method update (line 370) | func (c *collection) update(doc storedDoc, mods []driver.Mod) error {
method changeRevision (line 453) | func (c *collection) changeRevision(doc storedDoc) {
method checkRevision (line 458) | func (c *collection) checkRevision(arg driver.Document, current stored...
method RevisionToBytes (line 555) | func (c *collection) RevisionToBytes(rev any) ([]byte, error) {
method BytesToRevision (line 564) | func (c *collection) BytesToRevision(b []byte) (any, error) {
method As (line 569) | func (c *collection) As(i any) bool { return false }
method ErrorAs (line 572) | func (c *collection) ErrorAs(err error, i any) bool { return false }
method Close (line 577) | func (c *collection) Close() error {
function add (line 422) | func add(x, y any) (any, error) {
function getAtFieldPath (line 484) | func getAtFieldPath(m map[string]any, fp []string, nested bool) (result ...
function setAtFieldPath (line 523) | func setAtFieldPath(m map[string]any, fp []string, val any) error {
function getParentMap (line 537) | func getParentMap(m map[string]any, fp []string, create bool) (map[strin...
function loadDocs (line 588) | func loadDocs(filename string) (mapOfDocs, error) {
function saveDocs (line 609) | func saveDocs(filename string, m mapOfDocs) error {
FILE: docstore/memdocstore/mem_test.go
type harness (line 31) | type harness struct
method MakeCollection (line 39) | func (h *harness) MakeCollection(_ context.Context, kind drivertest.Co...
method BeforeDoTypes (line 52) | func (*harness) BeforeDoTypes() []any { return nil }
method BeforeQueryTypes (line 53) | func (*harness) BeforeQueryTypes() []any { return nil }
method RevisionsEqual (line 55) | func (*harness) RevisionsEqual(rev1, rev2 any) bool { return rev1 == r...
method SupportsAtomicWrites (line 57) | func (*harness) SupportsAtomicWrites() bool { return true }
method Close (line 59) | func (*harness) Close() {}
function newHarness (line 33) | func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, ...
function TestConformance (line 61) | func TestConformance(t *testing.T) {
function TestUpdateEncodesValues (line 72) | func TestUpdateEncodesValues(t *testing.T) {
function TestUpdateAtomic (line 103) | func TestUpdateAtomic(t *testing.T) {
function TestQueryNested (line 136) | func TestQueryNested(t *testing.T) {
function TestSortDocs (line 272) | func TestSortDocs(t *testing.T) {
function TestSaveAndLoad (line 307) | func TestSaveAndLoad(t *testing.T) {
FILE: docstore/memdocstore/query.go
method RunGetQuery (line 28) | func (c *collection) RunGetQuery(_ context.Context, q *driver.Query) (dr...
function filtersMatch (line 77) | func filtersMatch(fs []driver.Filter, doc storedDoc, nested bool) bool {
function filterMatches (line 86) | func filterMatches(f driver.Filter, doc storedDoc, nested bool) bool {
function applyComparison (line 102) | func applyComparison(op string, c int) bool {
function compare (line 123) | func compare(x1, x2 any, op string) (int, bool) {
function sortDocs (line 183) | func sortDocs(docs []storedDoc, field string, asc bool) {
type docIterator (line 196) | type docIterator struct
method Next (line 203) | func (it *docIterator) Next(ctx context.Context, doc driver.Document) ...
method Stop (line 219) | func (it *docIterator) Stop() { it.err = io.EOF }
method As (line 221) | func (it *docIterator) As(i any) bool { return false }
method QueryPlan (line 223) | func (c *collection) QueryPlan(q *driver.Query) (string, error) {
FILE: docstore/memdocstore/urls.go
function init (line 27) | func init() {
constant Scheme (line 33) | Scheme = "mem"
type URLOpener (line 44) | type URLOpener struct
method OpenCollectionURL (line 55) | func (o *URLOpener) OpenCollectionURL(ctx context.Context, u *url.URL)...
type urlColl (line 49) | type urlColl struct
FILE: docstore/memdocstore/urls_test.go
function TestOpenCollectionFromURL (line 24) | func TestOpenCollectionFromURL(t *testing.T) {
FILE: docstore/mongodocstore/codec.go
function encodeDoc (line 34) | func encodeDoc(doc driver.Document, lowercaseFields bool) (map[string]in...
function encodeValue (line 42) | func encodeValue(x interface{}) (interface{}, error) {
type encoder (line 50) | type encoder struct
method EncodeNil (line 55) | func (e *encoder) EncodeNil() { e.val = nil }
method EncodeBool (line 56) | func (e *encoder) EncodeBool(x bool) { e.val = x }
method EncodeInt (line 57) | func (e *encoder) EncodeInt(x int64) { e.val = x }
method EncodeUint (line 58) | func (e *encoder) EncodeUint(x uint64) { e.val = int64(x) }
method EncodeBytes (line 59) | func (e *encoder) EncodeBytes(x []byte) { e.val = x }
method EncodeFloat (line 60) | func (e *encoder) EncodeFloat(x float64) { e.val = x }
method EncodeString (line 61) | func (e *encoder) EncodeString(x string) { e.val = x }
method ListIndex (line 62) | func (e *encoder) ListIndex(int) { panic("impossible") }
method MapKey (line 63) | func (e *encoder) MapKey(string) { panic("impossible") }
method EncodeSpecial (line 70) | func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) {
method EncodeList (line 80) | func (e *encoder) EncodeList(n int) driver.Encoder {
method EncodeMap (line 100) | func (e *encoder) EncodeMap(n int) driver.Encoder {
type listEncoder (line 87) | type listEncoder struct
method ListIndex (line 92) | func (e *listEncoder) ListIndex(i int) { e.s[i] = e.val }
type mapEncoder (line 94) | type mapEncoder struct
method MapKey (line 106) | func (e *mapEncoder) MapKey(k string) {
function decodeDoc (line 116) | func decodeDoc(m map[string]interface{}, ddoc driver.Document, idField s...
type decoder (line 128) | type decoder struct
method String (line 133) | func (d decoder) String() string {
method AsNull (line 137) | func (d decoder) AsNull() bool {
method AsBool (line 141) | func (d decoder) AsBool() (bool, bool) {
method AsString (line 146) | func (d decoder) AsString() (string, bool) {
method AsInt (line 151) | func (d decoder) AsInt() (int64, bool) {
method AsUint (line 162) | func (d decoder) AsUint() (uint64, bool) {
method AsFloat (line 167) | func (d decoder) AsFloat() (float64, bool) {
method AsBytes (line 172) | func (d decoder) AsBytes() ([]byte, bool) {
method AsInterface (line 183) | func (d decoder) AsInterface() (interface{}, error) {
method ListLen (line 218) | func (d decoder) ListLen() (int, bool) {
method DecodeList (line 225) | func (d decoder) DecodeList(f func(i int, d2 driver.Decoder) bool) {
method MapLen (line 233) | func (d decoder) MapLen() (int, bool) {
method DecodeMap (line 240) | func (d decoder) DecodeMap(f func(key string, d2 driver.Decoder, exact...
method AsSpecial (line 248) | func (d decoder) AsSpecial(v reflect.Value) (bool, interface{}, error) {
function toGoValue (line 187) | func toGoValue(v interface{}) (interface{}, error) {
function bsonDateTimeToTime (line 258) | func bsonDateTimeToTime(dt primitive.DateTime) time.Time {
FILE: docstore/mongodocstore/cosmos_test.go
function TestConformanceCosmos (line 32) | func TestConformanceCosmos(t *testing.T) {
FILE: docstore/mongodocstore/docdb_test.go
constant connectionStringTemplate (line 15) | connectionStringTemplate = "mongodb://%s:%s@%s/?connect=direct&connectTi...
function TestConformanceDocDB (line 29) | func TestConformanceDocDB(t *testing.T) {
function newDocDBTestClient (line 46) | func newDocDBTestClient(t *testing.T) *mongo.Client {
FILE: docstore/mongodocstore/example_test.go
function ExampleOpenCollection (line 25) | func ExampleOpenCollection() {
function ExampleOpenCollectionWithIDFunc (line 42) | func ExampleOpenCollectionWithIDFunc() {
function Example_openCollectionFromURL (line 70) | func Example_openCollectionFromURL() {
FILE: docstore/mongodocstore/mongo.go
function Dial (line 80) | func Dial(ctx context.Context, uri string) (*mongo.Client, error) {
type collection (line 101) | type collection struct
method Key (line 184) | func (c *collection) Key(doc driver.Document) (interface{}, error) {
method RevisionField (line 196) | func (c *collection) RevisionField() string {
method RunActions (line 205) | func (c *collection) RunActions(ctx context.Context, actions []*driver...
method runGets (line 229) | func (c *collection) runGets(ctx context.Context, gets []*driver.Actio...
method bulkFind (line 238) | func (c *collection) bulkFind(ctx context.Context, gets []*driver.Acti...
method projectionDoc (line 295) | func (c *collection) projectionDoc(fps [][]string) bson.D {
method toMongoFieldPath (line 306) | func (c *collection) toMongoFieldPath(fp []string) string {
method prepareCreate (line 319) | func (c *collection) prepareCreate(a *driver.Action) (mdoc, createdID ...
method prepareReplace (line 339) | func (c *collection) prepareReplace(a *driver.Action) (filter bson.D, ...
method encodeDoc (line 357) | func (c *collection) encodeDoc(doc driver.Document, id interface{}) (m...
method prepareUpdate (line 376) | func (c *collection) prepareUpdate(a *driver.Action) (filter bson.D, u...
method newUpdateDoc (line 392) | func (c *collection) newUpdateDoc(mods []driver.Mod, writeRevision boo...
method makeFilter (line 435) | func (c *collection) makeFilter(id interface{}, doc driver.Document) (...
method bulkWrite (line 454) | func (c *collection) bulkWrite(ctx context.Context, actions []*driver....
method txWrite (line 566) | func (c *collection) txWrite(ctx context.Context, actions []*driver.Ac...
method determineDeleteErrors (line 693) | func (c *collection) determineDeleteErrors(ctx context.Context, models...
method newCreateModel (line 722) | func (c *collection) newCreateModel(a *driver.Action) (*mongo.InsertOn...
method newDeleteModel (line 730) | func (c *collection) newDeleteModel(a *driver.Action) (*mongo.DeleteOn...
method newReplaceModel (line 742) | func (c *collection) newReplaceModel(a *driver.Action, upsert bool) (*...
method newUpdateModel (line 754) | func (c *collection) newUpdateModel(a *driver.Action) (*mongo.UpdateOn...
method RevisionToBytes (line 766) | func (c *collection) RevisionToBytes(rev interface{}) ([]byte, error) {
method hasField (line 774) | func (c *collection) hasField(doc driver.Document, field string) bool {
method BytesToRevision (line 782) | func (c *collection) BytesToRevision(b []byte) (interface{}, error) {
method As (line 787) | func (c *collection) As(i interface{}) bool {
method ErrorAs (line 797) | func (c *collection) ErrorAs(err error, i interface{}) bool {
method ErrorCode (line 819) | func (c *collection) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 833) | func (c *collection) Close() error { return nil }
type Options (line 110) | type Options struct
function OpenCollection (line 138) | func OpenCollection(mcoll *mongo.Collection, idField string, opts *Optio...
function OpenCollectionWithIDFunc (line 151) | func OpenCollectionWithIDFunc(mcoll *mongo.Collection, idFunc func(docst...
function newCollection (line 159) | func newCollection(mcoll *mongo.Collection, idField string, idFunc func(...
constant mongoIDField (line 203) | mongoIDField = "_id"
function sliceToLower (line 313) | func sliceToLower(s []string) {
constant mongoDupKeyCode (line 837) | mongoDupKeyCode = 11000
function translateMongoCode (line 839) | func translateMongoCode(code int) gcerrors.ErrorCode {
FILE: docstore/mongodocstore/mongo_test.go
constant serverURIV3 (line 39) | serverURIV3 = "mongodb://localhost:27020"
constant serverURIV4 (line 40) | serverURIV4 = "mongodb://localhost:27017/?directConnection=true"
constant dbName (line 41) | dbName = "docstore-test"
constant collectionName1 (line 42) | collectionName1 = "docstore-test-1"
constant collectionName2 (line 43) | collectionName2 = "docstore-test-2"
constant collectionName3 (line 44) | collectionName3 = "docstore-test-3"
type harness (line 47) | type harness struct
method MakeCollection (line 52) | func (h *harness) MakeCollection(ctx context.Context, kind drivertest....
method SupportsAtomicWrites (line 82) | func (h *harness) SupportsAtomicWrites() bool { return h.supportAtomic...
method BeforeDoTypes (line 84) | func (*harness) BeforeDoTypes() []interface{} {
method BeforeQueryTypes (line 91) | func (*harness) BeforeQueryTypes() []interface{} {
method RevisionsEqual (line 95) | func (*harness) RevisionsEqual(rev1, rev2 interface{}) bool {
method Close (line 99) | func (*harness) Close() {}
type codecTester (line 101) | type codecTester struct
method UnsupportedTypes (line 103) | func (codecTester) UnsupportedTypes() []drivertest.UnsupportedType {
method DocstoreEncode (line 107) | func (codecTester) DocstoreEncode(x interface{}) (interface{}, error) {
method DocstoreDecode (line 115) | func (codecTester) DocstoreDecode(value, dest interface{}) error {
method NativeEncode (line 123) | func (codecTester) NativeEncode(x interface{}) (interface{}, error) {
method NativeDecode (line 127) | func (codecTester) NativeDecode(value, dest interface{}) error {
type verifyAs (line 131) | type verifyAs struct
method Name (line 133) | func (verifyAs) Name() string {
method CollectionCheck (line 137) | func (verifyAs) CollectionCheck(coll *docstore.Collection) error {
method QueryCheck (line 145) | func (verifyAs) QueryCheck(it *docstore.DocumentIterator) error {
method ErrorCheck (line 153) | func (verifyAs) ErrorCheck(c *docstore.Collection, err error) error {
function TestConformance (line 166) | func TestConformance(t *testing.T) {
function testConformance (line 172) | func testConformance(t *testing.T, serverURI string, supportsAtomicWrite...
function newTestClient (line 182) | func newTestClient(t *testing.T, serverURI string) *mongo.Client {
function BenchmarkConformance (line 198) | func BenchmarkConformance(b *testing.B) {
function TestLowercaseFields (line 224) | func TestLowercaseFields(t *testing.T) {
FILE: docstore/mongodocstore/query.go
method RunGetQuery (line 29) | func (c *collection) RunGetQuery(ctx context.Context, q *driver.Query) (...
method filtersToBSON (line 88) | func (c *collection) filtersToBSON(fs []driver.Filter) (bson.D, error) {
method filterToBSON (line 107) | func (c *collection) filterToBSON(f driver.Filter) (bson.E, error) {
type docIterator (line 123) | type docIterator struct
method Next (line 130) | func (it *docIterator) Next(ctx context.Context, doc driver.Document) ...
method nextMap (line 138) | func (it *docIterator) nextMap(ctx context.Context) (map[string]interf...
method Stop (line 152) | func (it *docIterator) Stop() {
method As (line 157) | func (it *docIterator) As(i interface{}) bool {
method QueryPlan (line 166) | func (c *collection) QueryPlan(q *driver.Query) (string, error) {
method RunDeleteQuery (line 170) | func (c *collection) RunDeleteQuery(ctx context.Context, q *driver.Query...
method RunUpdateQuery (line 184) | func (c *collection) RunUpdateQuery(ctx context.Context, q *driver.Query...
FILE: docstore/mongodocstore/urls.go
function init (line 30) | func init() {
type defaultDialer (line 36) | type defaultDialer struct
method OpenCollectionURL (line 43) | func (o *defaultDialer) OpenCollectionURL(ctx context.Context, u *url....
constant Scheme (line 68) | Scheme = "mongo"
type URLOpener (line 80) | type URLOpener struct
method OpenCollectionURL (line 90) | func (o *URLOpener) OpenCollectionURL(ctx context.Context, u *url.URL)...
FILE: docstore/mongodocstore/urls_test.go
function fakeConnectionStringInEnv (line 26) | func fakeConnectionStringInEnv() func() {
function TestOpenCollectionURL (line 34) | func TestOpenCollectionURL(t *testing.T) {
function TestDefaultDialerOpenCollectionURL (line 68) | func TestDefaultDialerOpenCollectionURL(t *testing.T) {
FILE: docstore/otel_test.go
function TestOpenTelemetry (line 26) | func TestOpenTelemetry(t *testing.T) {
FILE: docstore/query.go
type Query (line 29) | type Query struct
method Where (line 43) | func (q *Query) Where(fp FieldPath, op string, value any) *Query {
method Offset (line 128) | func (q *Query) Offset(n int) *Query {
method Limit (line 146) | func (q *Query) Limit(n int) *Query {
method OrderBy (line 173) | func (q *Query) OrderBy(field, direction string) *Query {
method BeforeQuery (line 195) | func (q *Query) BeforeQuery(f func(asFunc func(any) bool) error) *Query {
method Get (line 204) | func (q *Query) Get(ctx context.Context, fps ...FieldPath) *DocumentIt...
method get (line 209) | func (q *Query) get(ctx context.Context, withTracing bool, fps ...Fiel...
method initGet (line 228) | func (q *Query) initGet(fps []FieldPath) error {
method invalidf (line 256) | func (q *Query) invalidf(format string, args ...any) *Query {
method Plan (line 314) | func (q *Query) Plan(fps ...FieldPath) (string, error) {
method Query (line 36) | func (c *Collection) Query() *Query {
type valueValidator (line 67) | type valueValidator
function validEqualValue (line 79) | func validEqualValue(v any) bool {
function validFilterValue (line 89) | func validFilterValue(v any) bool {
function validFilterSlice (line 110) | func validFilterSlice(v any) bool {
constant Ascending (line 162) | Ascending = "asc"
constant Descending (line 163) | Descending = "desc"
type DocumentIterator (line 264) | type DocumentIterator struct
method Next (line 273) | func (it *DocumentIterator) Next(ctx context.Context, dst Document) er...
method Stop (line 292) | func (it *DocumentIterator) Stop() {
method As (line 304) | func (it *DocumentIterator) As(i any) bool {
FILE: docstore/query_test.go
function TestQueryValidFilter (line 26) | func TestQueryValidFilter(t *testing.T) {
function TestInvalidQuery (line 50) | func TestInvalidQuery(t *testing.T) {
FILE: docstore/urls.go
type CollectionURLOpener (line 29) | type CollectionURLOpener interface
type URLMux (line 38) | type URLMux struct
method CollectionSchemes (line 43) | func (mux *URLMux) CollectionSchemes() []string { return mux.schemes.S...
method ValidCollectionScheme (line 46) | func (mux *URLMux) ValidCollectionScheme(scheme string) bool { return ...
method RegisterCollection (line 50) | func (mux *URLMux) RegisterCollection(scheme string, opener Collection...
method OpenCollection (line 56) | func (mux *URLMux) OpenCollection(ctx context.Context, urlstr string) ...
method OpenCollectionURL (line 66) | func (mux *URLMux) OpenCollectionURL(ctx context.Context, u *url.URL) ...
function DefaultURLMux (line 79) | func DefaultURLMux() *URLMux {
function OpenCollection (line 87) | func OpenCollection(ctx context.Context, urlstr string) (*Collection, er...
FILE: docstore/urls_test.go
function TestURLMux (line 26) | func TestURLMux(t *testing.T) {
type fakeOpener (line 117) | type fakeOpener struct
method OpenCollectionURL (line 121) | func (o *fakeOpener) OpenCollectionURL(ctx context.Context, u *url.URL...
FILE: gcerrors/errors.go
constant OK (line 33) | OK ErrorCode = gcerr.OK
constant Unknown (line 36) | Unknown ErrorCode = gcerr.Unknown
constant NotFound (line 39) | NotFound ErrorCode = gcerr.NotFound
constant AlreadyExists (line 42) | AlreadyExists ErrorCode = gcerr.AlreadyExists
constant InvalidArgument (line 45) | InvalidArgument ErrorCode = gcerr.InvalidArgument
constant Internal (line 49) | Internal ErrorCode = gcerr.Internal
constant Unimplemented (line 52) | Unimplemented ErrorCode = gcerr.Unimplemented
constant FailedPrecondition (line 55) | FailedPrecondition ErrorCode = gcerr.FailedPrecondition
constant PermissionDenied (line 58) | PermissionDenied ErrorCode = gcerr.PermissionDenied
constant ResourceExhausted (line 62) | ResourceExhausted ErrorCode = gcerr.ResourceExhausted
constant Canceled (line 65) | Canceled ErrorCode = gcerr.Canceled
constant DeadlineExceeded (line 68) | DeadlineExceeded ErrorCode = gcerr.DeadlineExceeded
function Code (line 76) | func Code(err error) ErrorCode {
FILE: gcerrors/errors_test.go
type wrappedErr (line 25) | type wrappedErr struct
method Error (line 29) | func (w wrappedErr) Error() string { return "wrapped" }
method Unwrap (line 31) | func (w wrappedErr) Unwrap() error { return w.err }
function TestCode (line 33) | func TestCode(t *testing.T) {
FILE: gcp/cloudsql/cloudsql.go
function NewCertSource (line 35) | func NewCertSource(c *gcp.HTTPClient) *certs.RemoteCertSource {
function NewCertSourceWithIAM (line 41) | func NewCertSourceWithIAM(c *gcp.HTTPClient, t oauth2.TokenSource) *cert...
FILE: gcp/gcp.go
type ProjectID (line 36) | type ProjectID
type TokenSource (line 40) | type TokenSource
type HTTPClient (line 44) | type HTTPClient struct
function NewAnonymousHTTPClient (line 49) | func NewAnonymousHTTPClient(transport http.RoundTripper) *HTTPClient {
function NewHTTPClient (line 58) | func NewHTTPClient(transport http.RoundTripper, ts TokenSource) (*HTTPCl...
function DefaultTransport (line 73) | func DefaultTransport() http.RoundTripper {
function DefaultCredentials (line 79) | func DefaultCredentials(ctx context.Context) (*google.Credentials, error) {
function DefaultCredentialsWithParams (line 90) | func DefaultCredentialsWithParams(ctx context.Context, params google.Cre...
function CredentialsTokenSource (line 102) | func CredentialsTokenSource(creds *google.Credentials) TokenSource {
function DefaultProjectID (line 110) | func DefaultProjectID(creds *google.Credentials) (ProjectID, error) {
FILE: gcp/gcp_test.go
function TestNewHTTPClient (line 26) | func TestNewHTTPClient(t *testing.T) {
function TestCredentialsTokenSource (line 42) | func TestCredentialsTokenSource(t *testing.T) {
function TestDefaultProjectID (line 57) | func TestDefaultProjectID(t *testing.T) {
function TestDefaultCredentialsWithParams (line 72) | func TestDefaultCredentialsWithParams(t *testing.T) {
FILE: gcp/gcpcloud/example_test.go
function Example (line 33) | func Example() {
function setup (line 59) | func setup(ctx context.Context) (*server.Server, func(), error) {
function greet (line 74) | func greet(w http.ResponseWriter, req *http.Request) {
FILE: internal/escape/escape.go
constant NonUTF8String (line 26) | NonUTF8String = "\xbd\xb2"
function IsASCIIAlphanumeric (line 29) | func IsASCIIAlphanumeric(r rune) bool {
function HexEscape (line 56) | func HexEscape(s string, shouldEscape func(s []rune, i int) bool) string {
function unescape (line 94) | func unescape(r []rune, i int) (bool, rune, int) {
function HexUnescape (line 134) | func HexUnescape(s string) string {
function URLEscape (line 161) | func URLEscape(s string) string {
function URLUnescape (line 167) | func URLUnescape(s string) string {
function makeASCIIString (line 174) | func makeASCIIString(start, end int) string {
FILE: internal/escape/escape_test.go
function TestHexEscape (line 21) | func TestHexEscape(t *testing.T) {
function TestHexEscapeUnescapeWeirdStrings (line 70) | func TestHexEscapeUnescapeWeirdStrings(t *testing.T) {
function TestHexUnescapeOnInvalid (line 80) | func TestHexUnescapeOnInvalid(t *testing.T) {
FILE: internal/gcerr/errorcode_string.go
constant _ErrorCode_name (line 7) | _ErrorCode_name = "OKUnknownNotFoundAlreadyExistsInvalidArgumentInternal...
method String (line 11) | func (i ErrorCode) String() string {
FILE: internal/gcerr/gcerr.go
type ErrorCode (line 32) | type ErrorCode
constant OK (line 37) | OK ErrorCode = 0
constant Unknown (line 40) | Unknown ErrorCode = 1
constant NotFound (line 43) | NotFound ErrorCode = 2
constant AlreadyExists (line 46) | AlreadyExists ErrorCode = 3
constant InvalidArgument (line 49) | InvalidArgument ErrorCode = 4
constant Internal (line 53) | Internal ErrorCode = 5
constant Unimplemented (line 56) | Unimplemented ErrorCode = 6
constant FailedPrecondition (line 59) | FailedPrecondition ErrorCode = 7
constant PermissionDenied (line 62) | PermissionDenied ErrorCode = 8
constant ResourceExhausted (line 66) | ResourceExhausted ErrorCode = 9
constant Canceled (line 69) | Canceled ErrorCode = 10
constant DeadlineExceeded (line 72) | DeadlineExceeded ErrorCode = 11
type Error (line 87) | type Error struct
method Error (line 96) | func (e *Error) Error() string {
method Format (line 101) | func (e *Error) Format(s fmt.State, c rune) {
method FormatError (line 106) | func (e *Error) FormatError(p xerrors.Printer) (next error) {
method Unwrap (line 117) | func (e *Error) Unwrap() error {
function New (line 125) | func New(c ErrorCode, err error, callDepth int, msg string) *Error {
function Newf (line 135) | func Newf(c ErrorCode, err error, format string, args ...any) *Error {
function DoNotWrap (line 143) | func DoNotWrap(err error) bool {
function GRPCCode (line 159) | func GRPCCode(err error) ErrorCode {
function ErrorAs (line 190) | func ErrorAs(err error, target any, errorAs func(error, any) bool) bool {
FILE: internal/gcerr/gcerr_test.go
function TestNewf (line 26) | func TestNewf(t *testing.T) {
function TestFormatting (line 35) | func TestFormatting(t *testing.T) {
function TestError (line 105) | func TestError(t *testing.T) {
FILE: internal/openurl/openurl.go
type SchemeMap (line 27) | type SchemeMap struct
method Register (line 38) | func (m *SchemeMap) Register(api, typ, scheme string, value any) {
method FromString (line 58) | func (m *SchemeMap) FromString(typ, urlstr string) (any, *url.URL, err...
method FromURL (line 71) | func (m *SchemeMap) FromURL(typ string, u *url.URL) (any, error) {
method Schemes (line 90) | func (m *SchemeMap) Schemes() []string {
method ValidScheme (line 100) | func (m *SchemeMap) ValidScheme(scheme string) bool {
FILE: internal/openurl/openurl_test.go
function TestSchemeMap (line 23) | func TestSchemeMap(t *testing.T) {
FILE: internal/otel/metrics.go
constant unitDimensionless (line 30) | unitDimensionless = "1"
constant unitMilliseconds (line 31) | unitMilliseconds = "ms"
constant unitBytes (line 32) | unitBytes = "By"
function Views (line 46) | func Views(pkg string) []sdkmetric.View {
function CounterView (line 90) | func CounterView(pkg string, meterName string, description string) []sdk...
function LatencyMeasure (line 109) | func LatencyMeasure(pkg string, provider string) metric.Float64Histogram {
function DimensionlessMeasure (line 134) | func DimensionlessMeasure(pkg string, provider string, meterName string,...
function BytesMeasure (line 154) | func BytesMeasure(pkg string, provider string, meterName string, descrip...
FILE: internal/otel/trace.go
constant startTimeContextKey (line 40) | startTimeContextKey = "spanStartTimeCtxKey"
constant methodNameContextKey (line 41) | methodNameContextKey = "methodNameCtxKey"
type Tracer (line 45) | type Tracer struct
method Start (line 86) | func (t *Tracer) Start(ctx context.Context, methodName string) (contex...
method End (line 95) | func (t *Tracer) End(ctx context.Context, span trace.Span, err error) {
function ProviderName (line 55) | func ProviderName(driver any) string {
function NewTracer (line 68) | func NewTracer(pkg string, provider string) *Tracer {
FILE: internal/otel/trace_test.go
type testDriver (line 21) | type testDriver struct
function TestProviderName (line 23) | func TestProviderName(t *testing.T) {
FILE: internal/releasehelper/releasehelper.go
function printHelp (line 62) | func printHelp() {
function cmdCheck (line 71) | func cmdCheck(s string) []byte {
type GoMod (line 88) | type GoMod struct
type Module (line 97) | type Module struct
type Require (line 103) | type Require struct
type Replace (line 110) | type Replace struct
function parseModuleInfo (line 116) | func parseModuleInfo(path string) GoMod {
function runOnGomod (line 134) | func runOnGomod(path string, reqHandler func(gomodPath, mod, modPath str...
function gomodAddReplace (line 166) | func gomodAddReplace(path string) {
function gomodDropReplace (line 172) | func gomodDropReplace(path string) {
function gomodSetVersion (line 178) | func gomodSetVersion(path, v string) {
function gomodTag (line 184) | func gomodTag(path, v string) {
function validSemanticVersion (line 194) | func validSemanticVersion(v string) bool {
function main (line 202) | func main() {
FILE: internal/releasehelper/releasehelper_test.go
function createFilesForTest (line 50) | func createFilesForTest(root string) error {
function Test (line 69) | func Test(t *testing.T) {
FILE: internal/retry/retry.go
function Call (line 39) | func Call(ctx context.Context, bo gax.Backoff, isRetryable func(error) b...
function call (line 44) | func call(ctx context.Context, bo gax.Backoff, isRetryable func(error) b...
type ContextError (line 68) | type ContextError struct
method Error (line 73) | func (e *ContextError) Error() string {
method Is (line 78) | func (e *ContextError) Is(target error) bool {
FILE: internal/retry/retry_test.go
function retryable (line 33) | func retryable(err error) bool {
function TestCall (line 37) | func TestCall(t *testing.T) {
function TestCallCancel (line 94) | func TestCallCancel(t *testing.T) {
function equalContextError (line 126) | func equalContextError(got error, want *ContextError) bool {
function TestErrorsIs (line 134) | func TestErrorsIs(t *testing.T) {
FILE: internal/testing/oteltest/diff.go
type Call (line 36) | type Call struct
function formatSpanData (line 42) | func formatSpanData(s sdktrace.ReadOnlySpan) string {
function formatCall (line 50) | func formatCall(c *Call) string {
function Diff (line 69) | func Diff(gotSpans []sdktrace.ReadOnlySpan, gotMetrics []metricdata.Scop...
function mapStatusCode (line 81) | func mapStatusCode(code gcerrors.ErrorCode) codes.Code {
function diffSpans (line 89) | func diffSpans(got []sdktrace.ReadOnlySpan, prefix string, want []Call) ...
function DiffMetrics (line 120) | func DiffMetrics(got []metricdata.ScopeMetrics, prefix, provider string,...
FILE: internal/testing/oteltest/exporter.go
type TestExporter (line 35) | type TestExporter struct
method GetSpans (line 153) | func (te *TestExporter) GetSpans() tracetest.SpanStubs {
method GetMetrics (line 158) | func (te *TestExporter) GetMetrics(ctx context.Context) []metricdata.S...
method ForceFlush (line 166) | func (te *TestExporter) ForceFlush(ctx context.Context) error {
method Shutdown (line 171) | func (te *TestExporter) Shutdown(ctx context.Context) error {
type metricExporter (line 44) | type metricExporter struct
method Temporality (line 68) | func (e *metricExporter) Temporality(kind sdkmetric.InstrumentKind) me...
method Aggregation (line 73) | func (e *metricExporter) Aggregation(kind sdkmetric.InstrumentKind) sd...
method Export (line 78) | func (e *metricExporter) Export(ctx context.Context, data *metricdata....
method GetMetrics (line 84) | func (e *metricExporter) GetMetrics() []metricdata.ScopeMetrics {
method ForceFlush (line 91) | func (e *metricExporter) ForceFlush(ctx context.Context) error {
method Reset (line 101) | func (e *metricExporter) Reset() {
method Shutdown (line 108) | func (e *metricExporter) Shutdown(ctx context.Context) error {
function newMetricExporter (line 55) | func newMetricExporter() *metricExporter {
function NewTestExporter (line 117) | func NewTestExporter(t *testing.T, views []sdkmetric.View) *TestExporter {
FILE: internal/testing/oteltest/init.go
function configureTraceProvider (line 29) | func configureTraceProvider(serviceName string, exporter sdktrace.SpanEx...
function configureMeterProvider (line 75) | func configureMeterProvider(serviceName string, reader sdkmetric.Reader,...
FILE: internal/testing/setup/setup.go
function FakeGCPCredentials (line 47) | func FakeGCPCredentials(ctx context.Context) (*google.Credentials, error) {
function awsV2Config (line 51) | func awsV2Config(ctx context.Context, region string, client *http.Client...
function NewRecordReplayClient (line 73) | func NewRecordReplayClient(ctx context.Context, t *testing.T, rf func(r ...
function NewAWSv2Config (line 120) | func NewAWSv2Config(ctx context.Context, t *testing.T, region string, sc...
function NewGCPClient (line 151) | func NewGCPClient(ctx context.Context, t *testing.T) (client *gcp.HTTPCl...
function NewGCPgRPCConn (line 182) | func NewGCPgRPCConn(ctx context.Context, t *testing.T, endPoint, api str...
function NewAzureTestBlobClient (line 211) | func NewAzureTestBlobClient(ctx context.Context, t *testing.T) (*http.Cl...
function NewAzureKeyVaultTestClient (line 230) | func NewAzureKeyVaultTestClient(ctx context.Context, t *testing.T) (*htt...
function FakeGCPDefaultCredentials (line 244) | func FakeGCPDefaultCredentials(t *testing.T) func() {
function newGCPRecordDialOptions (line 267) | func newGCPRecordDialOptions(t *testing.T, filename string) (opts []grpc...
function newGCPReplayer (line 288) | func newGCPReplayer(t *testing.T, filename string) (*grpcreplay.Replayer...
function HasDockerTestEnvironment (line 308) | func HasDockerTestEnvironment() bool {
FILE: internal/testing/terraform/terraform.go
function ReadOutput (line 26) | func ReadOutput(dir string) (map[string]Output, error) {
type Output (line 41) | type Output struct
FILE: internal/testing/test-summary/test-summary.go
type TestEvent (line 40) | type TestEvent struct
function main (line 49) | func main() {
function run (line 61) | func run(r io.Reader) (msg string, failures bool, err error) {
FILE: internal/testing/test-summary/test-summary_test.go
function Test (line 24) | func Test(t *testing.T) {
constant testOutput (line 41) | testOutput = `{"Time":"2019-05-09T16:39:56.83133991-04:00","Action":"run...
FILE: internal/useragent/useragent.go
constant prefix (line 29) | prefix = "go-cloud"
constant version (line 30) | version = "0.45.0"
function ClientOption (line 34) | func ClientOption(api string) option.ClientOption {
function GRPCDialOption (line 39) | func GRPCDialOption(api string) grpc.DialOption {
function AzureUserAgentPrefix (line 44) | func AzureUserAgentPrefix(api string) string {
function userAgentString (line 48) | func userAgentString(api string) string {
type userAgentTransport (line 54) | type userAgentTransport struct
method RoundTrip (line 59) | func (t *userAgentTransport) RoundTrip(req *http.Request) (*http.Respo...
function HTTPClient (line 71) | func HTTPClient(client *http.Client, api string) *http.Client {
FILE: internal/website/gatherexamples/gatherexamples.go
function main (line 59) | func main() {
constant gatherLoadMode (line 111) | gatherLoadMode packages.LoadMode = packages.NeedName |
constant pragmaPrefix (line 124) | pragmaPrefix = "// PRAGMA: "
constant inclusionComment (line 128) | inclusionComment = pragmaPrefix + "This example is used on gocloud.dev; ...
type example (line 130) | type example struct
function gather (line 137) | func gather(pkgs []*packages.Package) (map[string]example, error) {
function rewriteBlock (line 207) | func rewriteBlock(block string) (_ string, blankImports []string) {
function nextLine (line 269) | func nextLine(s string) (line, tail string) {
function formatImports (line 279) | func formatImports(usedPackages map[string]string) string {
FILE: internal/website/gatherexamples/gatherexamples_test.go
function TestGather (line 26) | func TestGather(t *testing.T) {
function TestFormatImports (line 296) | func TestFormatImports(t *testing.T) {
FILE: mysql/awsmysql/awsmysql.go
type URLOpener (line 68) | type URLOpener struct
method OpenMySQLURL (line 88) | func (uo *URLOpener) OpenMySQLURL(ctx context.Context, u *url.URL) (*s...
constant Scheme (line 81) | Scheme = "awsmysql"
function init (line 83) | func init() {
type connector (line 143) | type connector struct
method Connect (line 152) | func (c *connector) Connect(ctx context.Context) (driver.Conn, error) {
method Driver (line 182) | func (c *connector) Driver() driver.Driver {
FILE: mysql/awsmysql/awsmysql_test.go
function TestOpen (line 26) | func TestOpen(t *testing.T) {
function TestOpenIAM (line 60) | func TestOpenIAM(t *testing.T) {
FILE: mysql/awsmysql/example_test.go
function Example (line 25) | func Example() {
FILE: mysql/awsmysql/otel_test.go
function TestOpenTelemetry (line 31) | func TestOpenTelemetry(t *testing.T) {
FILE: mysql/azuremysql/azuremysql.go
type URLOpener (line 44) | type URLOpener struct
method OpenMySQLURL (line 61) | func (uo *URLOpener) OpenMySQLURL(ctx context.Context, u *url.URL) (*s...
constant Scheme (line 54) | Scheme = "azuremysql"
function init (line 56) | func init() {
type connector (line 88) | type connector struct
method Connect (line 95) | func (c *connector) Connect(ctx context.Context) (driver.Conn, error) {
method Driver (line 118) | func (c *connector) Driver() driver.Driver {
FILE: mysql/azuremysql/azuremysql_test.go
function TestURLOpener (line 31) | func TestURLOpener(t *testing.T) {
FILE: mysql/azuremysql/example_test.go
function Example (line 25) | func Example() {
FILE: mysql/example_test.go
function ExampleOpen (line 24) | func ExampleOpen() {
FILE: mysql/gcpmysql/example_test.go
function Example (line 25) | func Example() {
FILE: mysql/gcpmysql/gcpmysql.go
constant Scheme (line 50) | Scheme = "gcpmysql"
function init (line 52) | func init() {
type lazyCredsOpener (line 58) | type lazyCredsOpener struct
method OpenMySQLURL (line 64) | func (o *lazyCredsOpener) OpenMySQLURL(ctx context.Context, u *url.URL...
type URLOpener (line 87) | type URLOpener struct
method OpenMySQLURL (line 97) | func (uo *URLOpener) OpenMySQLURL(ctx context.Context, u *url.URL) (*s...
function configFromURL (line 124) | func configFromURL(u *url.URL) (*mysql.Config, error) {
function instanceFromURL (line 153) | func instanceFromURL(u *url.URL) (instance, db string, _ error) {
FILE: mysql/gcpmysql/gcpmysql_test.go
function TestOpen (line 29) | func TestOpen(t *testing.T) {
function TestInstanceFromURL (line 65) | func TestInstanceFromURL(t *testing.T) {
function Test_configFromURL (line 136) | func Test_configFromURL(t *testing.T) {
FILE: mysql/mysql.go
constant Scheme (line 33) | Scheme = "mysql"
function init (line 35) | func init() {
type URLOpener (line 41) | type URLOpener struct
method OpenMySQLURL (line 46) | func (uo *URLOpener) OpenMySQLURL(_ context.Context, u *url.URL) (*sql...
function ConfigFromURL (line 61) | func ConfigFromURL(u *url.URL) (cfg *mysql.Config, err error) {
type MySQLURLOpener (line 91) | type MySQLURLOpener interface
type URLMux (line 100) | type URLMux struct
method RegisterMySQL (line 106) | func (mux *URLMux) RegisterMySQL(scheme string, opener MySQLURLOpener) {
method OpenMySQL (line 112) | func (mux *URLMux) OpenMySQL(ctx context.Context, urlstr string) (*sql...
method OpenMySQLURL (line 122) | func (mux *URLMux) OpenMySQLURL(ctx context.Context, u *url.URL) (*sql...
function DefaultURLMux (line 135) | func DefaultURLMux() *URLMux {
function Open (line 145) | func Open(ctx context.Context, urlstr string) (*sql.DB, error) {
FILE: mysql/mysql_test.go
function TestOpen (line 26) | func TestOpen(t *testing.T) {
function TestConfigFromURL (line 60) | func TestConfigFromURL(t *testing.T) {
FILE: postgres/awspostgres/awspostgres.go
type URLOpener (line 48) | type URLOpener struct
method OpenPostgresURL (line 65) | func (uo *URLOpener) OpenPostgresURL(ctx context.Context, u *url.URL) ...
constant Scheme (line 58) | Scheme = "awspostgres"
function init (line 60) | func init() {
type pqDriver (line 93) | type pqDriver struct
method Open (line 98) | func (d pqDriver) Open(name string) (driver.Conn, error) {
method OpenConnector (line 103) | func (d pqDriver) OpenConnector(name string) (driver.Connector, error) {
type connector (line 107) | type connector struct
method Connect (line 113) | func (c connector) Connect(context.Context) (driver.Conn, error) {
method Driver (line 121) | func (c connector) Driver() driver.Driver {
type dialer (line 125) | type dialer struct
method dial (line 129) | func (d dialer) dial(ctx context.Context, network, address string) (ne...
method Dial (line 177) | func (d dialer) Dial(network, address string) (net.Conn, error) {
method DialTimeout (line 181) | func (d dialer) DialTimeout(network, address string, timeout time.Dura...
FILE: postgres/awspostgres/awspostgres_test.go
function TestURLOpener (line 26) | func TestURLOpener(t *testing.T) {
FILE: postgres/awspostgres/example_test.go
function Example (line 25) | func Example() {
FILE: postgres/example_test.go
function ExampleOpen (line 24) | func ExampleOpen() {
FILE: postgres/gcppostgres/example_test.go
function Example (line 25) | func Example() {
FILE: postgres/gcppostgres/gcppostgres.go
constant Scheme (line 53) | Scheme = "gcppostgres"
function init (line 55) | func init() {
type lazyCredsOpener (line 61) | type lazyCredsOpener struct
method OpenPostgresURL (line 67) | func (o *lazyCredsOpener) OpenPostgresURL(ctx context.Context, u *url....
type URLOpener (line 90) | type URLOpener struct
method OpenPostgresURL (line 100) | func (uo *URLOpener) OpenPostgresURL(ctx context.Context, u *url.URL) ...
function instanceFromURL (line 136) | func instanceFromURL(u *url.URL) (instance, db string, _ error) {
type pqDriver (line 148) | type pqDriver struct
method Open (line 154) | func (d pqDriver) Open(name string) (driver.Conn, error) {
method OpenConnector (line 159) | func (d pqDriver) OpenConnector(name string) (driver.Connector, error) {
type connector (line 163) | type connector struct
method Connect (line 170) | func (c connector) Connect(context.Context) (driver.Conn, error) {
method Driver (line 178) | func (c connector) Driver() driver.Driver {
type dialer (line 182) | type dialer struct
method Dial (line 187) | func (d dialer) Dial(network, address string) (net.Conn, error) {
method DialTimeout (line 191) | func (d dialer) DialTimeout(network, address string, timeout time.Dura...
FILE: postgres/gcppostgres/gcppostgres_test.go
function TestURLOpener (line 27) | func TestURLOpener(t *testing.T) {
function TestInstanceFromURL (line 93) | func TestInstanceFromURL(t *testing.T) {
FILE: postgres/postgres.go
constant Scheme (line 31) | Scheme = "postgres"
function init (line 33) | func init() {
type URLOpener (line 39) | type URLOpener struct
method OpenPostgresURL (line 44) | func (uo *URLOpener) OpenPostgresURL(ctx context.Context, u *url.URL) ...
type connector (line 51) | type connector struct
method Connect (line 56) | func (c connector) Connect(ctx context.Context) (driver.Conn, error) {
method Driver (line 60) | func (c connector) Driver() driver.Driver {
type PostgresURLOpener (line 69) | type PostgresURLOpener interface
type URLMux (line 79) | type URLMux struct
method RegisterPostgres (line 85) | func (mux *URLMux) RegisterPostgres(scheme string, opener PostgresURLO...
method OpenPostgres (line 91) | func (mux *URLMux) OpenPostgres(ctx context.Context, urlstr string) (*...
method OpenPostgresURL (line 101) | func (mux *URLMux) OpenPostgresURL(ctx context.Context, u *url.URL) (*...
function DefaultURLMux (line 114) | func DefaultURLMux() *URLMux {
function Open (line 124) | func Open(ctx context.Context, urlstr string) (*sql.DB, error) {
FILE: postgres/postgres_test.go
function TestOpen (line 31) | func TestOpen(t *testing.T) {
FILE: pubsub/acks_test.go
type ackingDriverSub (line 30) | type ackingDriverSub struct
method ReceiveBatch (line 36) | func (s *ackingDriverSub) ReceiveBatch(ctx context.Context, maxMessage...
method SendAcks (line 47) | func (s *ackingDriverSub) SendAcks(ctx context.Context, ackIDs []drive...
method IsRetryable (line 51) | func (*ackingDriverSub) IsRetryable(error) bool { return f...
method ErrorCode (line 52) | func (*ackingDriverSub) ErrorCode(error) gcerrors.ErrorCode { return g...
method CanNack (line 53) | func (*ackingDriverSub) CanNack() bool { return f...
method Close (line 54) | func (*ackingDriverSub) Close() error { return n...
function TestAckTriggersDriverSendAcksForOneMessage (line 56) | func TestAckTriggersDriverSendAcksForOneMessage(t *testing.T) {
function TestMultipleAcksCanGoIntoASingleBatch (line 89) | func TestMultipleAcksCanGoIntoASingleBatch(t *testing.T) {
function TestTooManyAcksForASingleBatchGoIntoMultipleBatches (line 134) | func TestTooManyAcksForASingleBatchGoIntoMultipleBatches(t *testing.T) {
function TestAckDoesNotBlock (line 188) | func TestAckDoesNotBlock(t *testing.T) {
function TestDoubleAckCausesPanic (line 212) | func TestDoubleAckCausesPanic(t *testing.T) {
function TestConcurrentDoubleAckCausesPanic (line 239) | func TestConcurrentDoubleAckCausesPanic(t *testing.T) {
function TestSubShutdownCanBeCanceledEvenWithHangingSendAcks (line 281) | func TestSubShutdownCanBeCanceledEvenWithHangingSendAcks(t *testing.T) {
function TestReceiveReturnsErrorFromSendAcks (line 313) | func TestReceiveReturnsErrorFromSendAcks(t *testing.T) {
type callbackDriverSub (line 356) | type callbackDriverSub struct
method ReceiveBatch (line 363) | func (s *callbackDriverSub) ReceiveBatch(ctx context.Context, maxMessa...
method SendAcks (line 367) | func (s *callbackDriverSub) SendAcks(ctx context.Context, acks []drive...
method IsRetryable (line 371) | func (*callbackDriverSub) IsRetryable(error) bool { return...
method ErrorCode (line 372) | func (*callbackDriverSub) ErrorCode(error) gcerrors.ErrorCode { return...
method CanNack (line 373) | func (*callbackDriverSub) CanNack() bool { return...
method Close (line 374) | func (*callbackDriverSub) Close() error { return...
function TestReceiveReturnsAckErrorOnNoMoreMessages (line 383) | func TestReceiveReturnsAckErrorOnNoMoreMessages(t *testing.T) {
FILE: pubsub/awssnssqs/awssnssqs.go
constant base64EncodedKey (line 98) | base64EncodedKey = "base64encoded"
constant noMessagesPollDuration (line 101) | noMessagesPollDuration = 250 * time.Millisecond
function init (line 129) | func init() {
function DialSNS (line 143) | func DialSNS(cfg aws.Config) *sns.Client {
function DialSQS (line 148) | func DialSQS(cfg aws.Config) *sqs.Client {
type lazySessionOpener (line 154) | type lazySessionOpener struct
method defaultOpener (line 160) | func (o *lazySessionOpener) defaultOpener(u *url.URL) (*URLOpener, err...
method OpenTopicURL (line 164) | func (o *lazySessionOpener) OpenTopicURL(ctx context.Context, u *url.U...
method OpenSubscriptionURL (line 172) | func (o *lazySessionOpener) OpenSubscriptionURL(ctx context.Context, u...
constant SNSScheme (line 182) | SNSScheme = "awssns"
constant SQSScheme (line 187) | SQSScheme = "awssqs"
type URLOpener (line 209) | type URLOpener struct
method OpenTopicURL (line 217) | func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pu...
method OpenSubscriptionURL (line 238) | func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.UR...
type snsTopic (line 274) | type snsTopic struct
method SendBatch (line 415) | func (t *snsTopic) SendBatch(ctx context.Context, dms []*driver.Messag...
method IsRetryable (line 517) | func (t *snsTopic) IsRetryable(error) bool {
method As (line 523) | func (t *snsTopic) As(i any) bool {
method ErrorAs (line 533) | func (t *snsTopic) ErrorAs(err error, i any) bool {
method ErrorCode (line 538) | func (t *snsTopic) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 543) | func (*snsTopic) Close() error { return nil }
type BodyBase64Encoding (line 282) | type BodyBase64Encoding
method wantEncode (line 301) | func (e BodyBase64Encoding) wantEncode(b []byte) bool {
constant NonUTF8Only (line 290) | NonUTF8Only BodyBase64Encoding = 0
constant Always (line 295) | Always BodyBase64Encoding = 1
constant Never (line 298) | Never BodyBase64Encoding = 2
type TopicOptions (line 314) | type TopicOptions struct
function OpenSNSTopic (line 325) | func OpenSNSTopic(ctx context.Context, client *sns.Client, topicARN stri...
function openSNSTopic (line 337) | func openSNSTopic(ctx context.Context, client *sns.Client, topicARN stri...
function encodeMetadata (line 348) | func encodeMetadata(md map[string]string) map[string]string {
function maybeEncodeBody (line 373) | func maybeEncodeBody(body []byte, opt BodyBase64Encoding) (string, bool) {
constant MetadataKeyDeduplicationID (line 400) | MetadataKeyDeduplicationID = "DeduplicationId"
constant MetadataKeyMessageGroupID (line 401) | MetadataKeyMessageGroupID = "MessageGroupId"
function reviseSnsEntryAttributes (line 405) | func reviseSnsEntryAttributes(dm *driver.Message, entry *snstypes.Publis...
type sqsTopic (line 545) | type sqsTopic struct
method SendBatch (line 584) | func (t *sqsTopic) SendBatch(ctx context.Context, dms []*driver.Messag...
method IsRetryable (line 654) | func (t *sqsTopic) IsRetryable(error) bool {
method As (line 660) | func (t *sqsTopic) As(i any) bool {
method ErrorAs (line 670) | func (t *sqsTopic) ErrorAs(err error, i any) bool {
method ErrorCode (line 675) | func (t *sqsTopic) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 680) | func (*sqsTopic) Close() error { return nil }
function OpenSQSTopic (line 553) | func OpenSQSTopic(ctx context.Context, client *sqs.Client, qURL string, ...
function openSQSTopic (line 565) | func openSQSTopic(ctx context.Context, client *sqs.Client, qURL string, ...
function reviseSqsEntryAttributes (line 574) | func reviseSqsEntryAttributes(dm *driver.Message, entry *sqstypes.SendMe...
function errorCode (line 682) | func errorCode(err error) gcerrors.ErrorCode {
type subscription (line 736) | type subscription struct
method ReceiveBatch (line 805) | func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages i...
method SendAcks (line 917) | func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckI...
method CanNack (line 939) | func (s *subscription) CanNack() bool { return true }
method SendNacks (line 942) | func (s *subscription) SendNacks(ctx context.Context, ids []driver.Ack...
method IsRetryable (line 978) | func (*subscription) IsRetryable(error) bool {
method As (line 984) | func (s *subscription) As(i any) bool {
method ErrorAs (line 994) | func (s *subscription) ErrorAs(err error, i any) bool {
method ErrorCode (line 999) | func (s *subscription) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 1008) | func (*subscription) Close() error { return nil }
type SubscriptionOptions (line 743) | type SubscriptionOptions struct
function OpenSubscription (line 784) | func OpenSubscription(ctx context.Context, client *sqs.Client, qURL stri...
function openSubscription (line 796) | func openSubscription(ctx context.Context, client *sqs.Client, qURL stri...
function extractBody (line 878) | func extractBody(bodyStr string, rawAttrs map[string]string, raw bool) (...
function errorAs (line 1003) | func errorAs(err error, i any) bool {
FILE: pubsub/awssnssqs/awssnssqs_test.go
constant region (line 43) | region = "us-east-2"
constant accountNumber (line 44) | accountNumber = "456752665576"
type topicKind (line 49) | type topicKind
constant topicKindSNS (line 52) | topicKindSNS = topicKind("SNS")
constant topicKindSNSRaw (line 53) | topicKindSNSRaw = topicKind("SNSRaw")
constant topicKindSQS (line 54) | topicKindSQS = topicKind("SQS")
type harness (line 57) | type harness struct
method CreateTopic (line 78) | func (h *harness) CreateTopic(ctx context.Context, testName string) (d...
method MakeNonexistentTopic (line 127) | func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.To...
method CreateSubscription (line 140) | func (h *harness) CreateSubscription(ctx context.Context, dt driver.To...
method MakeNonexistentSubscription (line 226) | func (h *harness) MakeNonexistentSubscription(ctx context.Context) (dr...
method Close (line 231) | func (h *harness) Close() {
method MaxBatchSizes (line 235) | func (h *harness) MaxBatchSizes() (int, int) {
method SupportsMultipleSubscriptions (line 242) | func (h *harness) SupportsMultipleSubscriptions() bool {
type harnessOption (line 69) | type harnessOption
function newHarness (line 71) | func newHarness(ctx context.Context, t *testing.T, topicKind topicKind) ...
function convertStringToPtrMap (line 86) | func convertStringToPtrMap(m map[string]string) map[string]*string {
function createTopic (line 97) | func createTopic(ctx context.Context, topicName string, snsClient *sns.C...
function createSubscription (line 145) | func createSubscription(ctx context.Context, dt driver.Topic, subName st...
function createSQSQueue (line 185) | func createSQSQueue(ctx context.Context, sqsClient *sqs.Client, topicNam...
function TestConformanceSNSTopic (line 248) | func TestConformanceSNSTopic(t *testing.T) {
function TestConformanceSNSTopicRaw (line 258) | func TestConformanceSNSTopicRaw(t *testing.T) {
function TestConformanceSQSTopic (line 268) | func TestConformanceSQSTopic(t *testing.T) {
type awsAsTest (line 278) | type awsAsTest struct
method Name (line 282) | func (awsAsTest) Name() string {
method TopicCheck (line 286) | func (t awsAsTest) TopicCheck(topic *pubsub.Topic) error {
method SubscriptionCheck (line 304) | func (t awsAsTest) SubscriptionCheck(sub *pubsub.Subscription) error {
method TopicErrorCheck (line 312) | func (t awsAsTest) TopicErrorCheck(topic *pubsub.Topic, err error) err...
method SubscriptionErrorCheck (line 332) | func (t awsAsTest) SubscriptionErrorCheck(s *pubsub.Subscription, err ...
method MessageCheck (line 343) | func (t awsAsTest) MessageCheck(m *pubsub.Message) error {
method BeforeSend (line 351) | func (t awsAsTest) BeforeSend(as func(any) bool) error {
method AfterSend (line 373) | func (t awsAsTest) AfterSend(as func(any) bool) error {
function sanitize (line 395) | func sanitize(s string) string {
function BenchmarkSNSSQS (line 409) | func BenchmarkSNSSQS(b *testing.B) {
function BenchmarkSQS (line 413) | func BenchmarkSQS(b *testing.B) {
function benchmark (line 417) | func benchmark(b *testing.B, topicKind topicKind) {
function TestOpenTopicFromURL (line 450) | func TestOpenTopicFromURL(t *testing.T) {
function TestOpenSubscriptionFromURL (line 485) | func TestOpenSubscriptionFromURL(t *testing.T) {
function TestFIFO (line 524) | func TestFIFO(t *testing.T) {
function testFIFOTopic (line 562) | func testFIFOTopic(t *testing.T, kind topicKind) {
FILE: pubsub/awssnssqs/example_test.go
function ExampleOpenSNSTopic (line 28) | func ExampleOpenSNSTopic() {
function ExampleOpenSQSTopic (line 47) | func ExampleOpenSQSTopic() {
function Example_openSNSTopicFromURL (line 66) | func Example_openSNSTopicFromURL() {
function Example_openSQSTopicFromURL (line 82) | func Example_openSQSTopicFromURL() {
function ExampleOpenSubscription (line 97) | func ExampleOpenSubscription() {
function Example_openSubscriptionFromURL (line 117) | func Example_openSubscriptionFromURL() {
FILE: pubsub/azuresb/azuresb.go
constant defaultListenerTimeout (line 80) | defaultListenerTimeout = 2 * time.Second
function init (line 98) | func init() {
type defaultOpener (line 107) | type defaultOpener struct
method defaultOpener (line 113) | func (o *defaultOpener) defaultOpener() (*URLOpener, error) {
method OpenTopicURL (line 126) | func (o *defaultOpener) OpenTopicURL(ctx context.Context, u *url.URL) ...
method OpenSubscriptionURL (line 134) | func (o *defaultOpener) OpenSubscriptionURL(ctx context.Context, u *ur...
constant Scheme (line 143) | Scheme = "azuresb"
type URLOpener (line 154) | type URLOpener struct
method sbClient (line 176) | func (o *URLOpener) sbClient(kind string, u *url.URL) (*servicebus.Cli...
method OpenTopicURL (line 199) | func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pu...
method OpenSubscriptionURL (line 216) | func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.UR...
type topic (line 255) | type topic struct
method SendBatch (line 319) | func (t *topic) SendBatch(ctx context.Context, dms []*driver.Message) ...
method IsRetryable (line 356) | func (t *topic) IsRetryable(err error) bool {
method As (line 361) | func (t *topic) As(i any) bool {
method ErrorAs (line 371) | func (*topic) ErrorAs(err error, i any) bool {
method ErrorCode (line 396) | func (*topic) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 402) | func (*topic) Close() error { return nil }
type TopicOptions (line 260) | type TopicOptions struct
function NewClientFromConnectionString (line 267) | func NewClientFromConnectionString(connectionString string, opts *servic...
function NewClientFromServiceBusHostname (line 274) | func NewClientFromServiceBusHostname(serviceBusHostname string, opts *se...
function NewSender (line 287) | func NewSender(sbClient *servicebus.Client, topicName string, opts *serv...
function NewReceiver (line 292) | func NewReceiver(sbClient *servicebus.Client, topicName, subscriptionNam...
function OpenTopic (line 297) | func OpenTopic(ctx context.Context, sbSender *servicebus.Sender, opts *T...
function openTopic (line 311) | func openTopic(ctx context.Context, sbSender *servicebus.Sender, _ *Topi...
function errorAs (line 375) | func errorAs(err error, i any) bool {
type subscription (line 404) | type subscription struct
method IsRetryable (line 463) | func (s *subscription) IsRetryable(err error) bool {
method As (line 469) | func (s *subscription) As(i any) bool {
method ErrorAs (line 479) | func (s *subscription) ErrorAs(err error, i any) bool {
method ErrorCode (line 483) | func (s *subscription) ErrorCode(err error) gcerrors.ErrorCode {
method ReceiveBatch (line 489) | func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages i...
method SendAcks (line 532) | func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckI...
method CanNack (line 548) | func (s *subscription) CanNack() bool {
method SendNacks (line 556) | func (s *subscription) SendNacks(ctx context.Context, ids []driver.Ack...
method Close (line 618) | func (*subscription) Close() error { return nil }
type SubscriptionOptions (line 410) | type SubscriptionOptions struct
function OpenSubscription (line 432) | func OpenSubscription(ctx context.Context, sbClient *servicebus.Client, ...
function openSubscription (line 446) | func openSubscription(ctx context.Context, sbClient *servicebus.Client, ...
function messageAsFunc (line 520) | func messageAsFunc(sbmsg *servicebus.ReceivedMessage) func(any) bool {
function errorCode (line 571) | func errorCode(err error) (gcerrors.ErrorCode, bool) {
FILE: pubsub/azuresb/azuresb_test.go
constant nonexistentTopicName (line 42) | nonexistentTopicName = "nonexistent-topic"
constant maxNameLen (line 47) | maxNameLen = 40
type harness (line 50) | type harness struct
method CreateTopic (line 93) | func (h *harness) CreateTopic(ctx context.Context, testName string) (d...
method MakeNonexistentTopic (line 112) | func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.To...
method CreateSubscription (line 125) | func (h *harness) CreateSubscription(ctx context.Context, dt driver.To...
method MakeNonexistentSubscription (line 158) | func (h *harness) MakeNonexistentSubscription(ctx context.Context) (dr...
method Close (line 172) | func (h *harness) Close() {
method MaxBatchSizes (line 176) | func (h *harness) MaxBatchSizes() (int, int) { return sendBatcherOpts....
method SupportsMultipleSubscriptions (line 178) | func (h *harness) SupportsMultipleSubscriptions() bool { return true }
function newHarness (line 60) | func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, ...
function newHarnessUsingAutodelete (line 83) | func newHarnessUsingAutodelete(ctx context.Context, t *testing.T) (drive...
function TestConformance (line 182) | func TestConformance(t *testing.T) {
function TestConformanceWithAutodelete (line 190) | func TestConformanceWithAutodelete(t *testing.T) {
type sbAsTest (line 198) | type sbAsTest struct
method Name (line 200) | func (sbAsTest) Name() string {
method TopicCheck (line 204) | func (sbAsTest) TopicCheck(topic *pubsub.Topic) error {
method SubscriptionCheck (line 216) | func (sbAsTest) SubscriptionCheck(sub *pubsub.Subscription) error {
method TopicErrorCheck (line 228) | func (sbAsTest) TopicErrorCheck(t *pubsub.Topic, err error) error {
method SubscriptionErrorCheck (line 232) | func (sbAsTest) SubscriptionErrorCheck(s *pubsub.Subscription, err err...
method MessageCheck (line 236) | func (sbAsTest) MessageCheck(m *pubsub.Message) error {
method BeforeSend (line 248) | func (sbAsTest) BeforeSend(as func(any) bool) error {
method AfterSend (line 256) | func (sbAsTest) AfterSend(as func(any) bool) error {
function sanitize (line 260) | func sanitize(s string) string {
function createTopic (line 274) | func createTopic(ctx context.Context, topicName string, adminClient *adm...
function deleteTopic (line 287) | func deleteTopic(ctx context.Context, topicName string, adminClient *adm...
function createSubscription (line 297) | func createSubscription(ctx context.Context, topicName, subscriptionName...
function deleteSubscription (line 310) | func deleteSubscription(ctx context.Context, topicName, subscriptionName...
function BenchmarkAzureServiceBusPubSub (line 326) | func BenchmarkAzureServiceBusPubSub(b *testing.B) {
function fakeConnectionStringInEnv (line 399) | func fakeConnectionStringInEnv() func() {
function TestOpenTopicFromURL (line 407) | func TestOpenTopicFromURL(t *testing.T) {
function TestOpenSubscriptionFromURL (line 433) | func TestOpenSubscriptionFromURL(t *testing.T) {
FILE: pubsub/azuresb/example_test.go
function ExampleOpenTopic (line 27) | func ExampleOpenTopic() {
function Example_openTopicFromURL (line 59) | func Example_openTopicFromURL() {
function ExampleOpenSubscription (line 75) | func ExampleOpenSubscription() {
function Example_openSubscriptionFromURL (line 104) | func Example_openSubscriptionFromURL() {
function ExampleOpenSubscription_inReceiveAndDeleteMode (line 122) | func ExampleOpenSubscription_inReceiveAndDeleteMode() {
FILE: pubsub/batcher/batcher.go
function Split (line 38) | func Split(n int, opts *Options) []int {
type Batcher (line 62) | type Batcher struct
method Add (line 162) | func (b *Batcher) Add(ctx context.Context, item any) error {
method AddNoWait (line 176) | func (b *Batcher) AddNoWait(item any) <-chan error {
method handleBatch (line 208) | func (b *Batcher) handleBatch(batch []waiter) {
method nextBatch (line 223) | func (b *Batcher) nextBatch() []waiter {
method callHandler (line 258) | func (b *Batcher) callHandler(batch []waiter) {
method Shutdown (line 287) | func (b *Batcher) Shutdown() {
type sizableItem (line 77) | type sizableItem interface
type waiter (line 81) | type waiter struct
type Options (line 87) | type Options struct
method NewMergedOptions (line 116) | func (o *Options) NewMergedOptions(opts *Options) *Options {
function newOptionsWithDefaults (line 101) | func newOptionsWithDefaults(opts *Options) Options {
function New (line 151) | func New(itemType reflect.Type, opts *Options, handler func(any) error) ...
FILE: pubsub/batcher/batcher_test.go
function TestSplit (line 32) | func TestSplit(t *testing.T) {
function TestSequential (line 69) | func TestSequential(t *testing.T) {
type sizableItem (line 91) | type sizableItem struct
method ByteSize (line 95) | func (i *sizableItem) ByteSize() int {
function TestPreventsAddingItemsLargerThanBatchMaxByteSize (line 99) | func TestPreventsAddingItemsLargerThanBatchMaxByteSize(t *testing.T) {
function TestBatchingConsidersMaxSizeAndMaxByteSize (line 118) | func TestBatchingConsidersMaxSizeAndMaxByteSize(t *testing.T) {
function TestMinBatchSize (line 157) | func TestMinBatchSize(t *testing.T) {
function TestSaturation (line 174) | func TestSaturation(t *testing.T) {
function TestShutdown (line 238) | func TestShutdown(t *testing.T) {
function TestMinBatchSizeFlushesOnShutdown (line 275) | func TestMinBatchSizeFlushesOnShutdown(t *testing.T) {
function TestItemCanBeInterface (line 300) | func TestItemCanBeInterface(t *testing.T) {
FILE: pubsub/benchmark_test.go
constant runFor (line 32) | runFor = 25 * time.Second
constant reportWarmup (line 34) | reportWarmup = 500 * time.Millisecond
constant reportPeriodWarmup (line 36) | reportPeriodWarmup = 50 * time.Millisecond
constant reportPeriod (line 37) | reportPeriod = 1 * time.Second
constant numLinesPerTest (line 41) | numLinesPerTest = 50
constant smoothing (line 43) | smoothing = 5
type fakeSub (line 46) | type fakeSub struct
method SendAcks (line 53) | func (*fakeSub) SendAcks(ctx context.Context, ackIDs []driver.AckID) e...
method CanNack (line 54) | func (*fakeSub) CanNack() bool ...
method Close (line 55) | func (*fakeSub) Close() error ...
method ReceiveBatch (line 57) | func (s *fakeSub) ReceiveBatch(ctx context.Context, maxMessages int) (...
method inMiddleThird (line 67) | func (s *fakeSub) inMiddleThird() bool {
function TestReceivePerformance (line 74) | func TestReceivePerformance(t *testing.T) {
function runBenchmark (line 187) | func runBenchmark(t *testing.T, description string, numGoRoutines int, r...
FILE: pubsub/driver/driver.go
type AckID (line 27) | type AckID
type AckInfo (line 30) | type AckInfo struct
type Message (line 39) | type Message struct
method ByteSize (line 82) | func (m *Message) ByteSize() int {
type Topic (line 89) | type Topic interface
type Subscription (line 139) | type Subscription interface
FILE: pubsub/drivertest/drivertest.go
type Harness (line 42) | type Harness interface
type HarnessMaker (line 77) | type HarnessMaker
type AsTest (line 90) | type AsTest interface
type verifyAsFailsOnNil (line 119) | type verifyAsFailsOnNil struct
method Name (line 121) | func (verifyAsFailsOnNil) Name() string {
method TopicCheck (line 125) | func (verifyAsFailsOnNil) TopicCheck(t *pubsub.Topic) error {
method SubscriptionCheck (line 132) | func (verifyAsFailsOnNil) SubscriptionCheck(s *pubsub.Subscription) er...
method TopicErrorCheck (line 139) | func (verifyAsFailsOnNil) TopicErrorCheck(t *pubsub.Topic, err error) ...
method SubscriptionErrorCheck (line 149) | func (verifyAsFailsOnNil) SubscriptionErrorCheck(s *pubsub.Subscriptio...
method MessageCheck (line 159) | func (verifyAsFailsOnNil) MessageCheck(m *pubsub.Message) error {
method BeforeSend (line 166) | func (verifyAsFailsOnNil) BeforeSend(as func(any) bool) error {
method AfterSend (line 173) | func (verifyAsFailsOnNil) AfterSend(as func(any) bool) error {
function RunConformanceTests (line 181) | func RunConformanceTests(t *testing.T, newHarness HarnessMaker, asTests ...
function RunBenchmarks (line 215) | func RunBenchmarks(b *testing.B, topic *pubsub.Topic, sub *pubsub.Subscr...
function testNonExistentTopicSucceedsOnOpenButFailsOnSend (line 226) | func testNonExistentTopicSucceedsOnOpenButFailsOnSend(t *testing.T, newH...
function testNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive (line 257) | func testNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive(t *testi...
function testSendReceive (line 289) | func testSendReceive(t *testing.T, newHarness HarnessMaker) {
function testSendReceiveTwo (line 323) | func testSendReceiveTwo(t *testing.T, newHarness HarnessMaker) {
function testSendReceiveJSON (line 373) | func testSendReceiveJSON(t *testing.T, newHarness HarnessMaker) {
function testNack (line 406) | func testNack(t *testing.T, newHarness HarnessMaker) {
function testBatching (line 485) | func testBatching(t *testing.T, newHarness HarnessMaker) {
function testDoubleAck (line 568) | func testDoubleAck(t *testing.T, newHarness HarnessMaker) {
function publishN (line 661) | func publishN(ctx context.Context, t *testing.T, topic *pubsub.Topic, n ...
function receiveN (line 679) | func receiveN(ctx context.Context, t *testing.T, sub *pubsub.Subscriptio...
function diffMessageSets (line 698) | func diffMessageSets(got, want []*pubsub.Message) string {
function testErrorOnSendToClosedTopic (line 706) | func testErrorOnSendToClosedTopic(t *testing.T, newHarness HarnessMaker) {
function testErrorOnReceiveFromClosedSubscription (line 738) | func testErrorOnReceiveFromClosedSubscription(t *testing.T, newHarness H...
function testCancelSendReceive (line 772) | func testCancelSendReceive(t *testing.T, newHarness HarnessMaker) {
function testMetadata (line 805) | func testMetadata(t *testing.T, newHarness HarnessMaker) {
function testNonUTF8MessageBody (line 879) | func testNonUTF8MessageBody(t *testing.T, newHarness HarnessMaker) {
function isCanceled (line 928) | func isCanceled(err error) bool {
function makePair (line 938) | func makePair(ctx context.Context, t *testing.T, h Harness) (*pubsub.Top...
function testAs (line 966) | func testAs(t *testing.T, newHarness HarnessMaker, st AsTest) {
function benchmark (line 1059) | func benchmark(b *testing.B, topic *pubsub.Topic, sub *pubsub.Subscripti...
function publishNConcurrently (line 1101) | func publishNConcurrently(topic *pubsub.Topic, nMessages, nGoroutines in...
function receiveNConcurrently (line 1107) | func receiveNConcurrently(sub *pubsub.Subscription, nMessages, nGoroutin...
function runConcurrently (line 1120) | func runConcurrently(n, g int, f func(context.Context) error) error {
FILE: pubsub/example_test.go
function ExampleTopic_Send (line 29) | func ExampleTopic_Send() {
function ExampleSubscription_Receive (line 50) | func ExampleSubscription_Receive() {
function ExampleSubscription_Receive_concurrent (line 71) | func ExampleSubscription_Receive_concurrent() {
function ExampleMessage_As (line 117) | func ExampleMessage_As() {
function ExampleSubscription_As (line 141) | func ExampleSubscription_As() {
function ExampleSubscription_ErrorAs (line 160) | func ExampleSubscription_ErrorAs() {
function ExampleTopic_As (line 184) | func ExampleTopic_As() {
function ExampleTopic_ErrorAs (line 203) | func ExampleTopic_ErrorAs() {
FILE: pubsub/gcppubsub/example_test.go
function ExampleOpenTopic (line 29) | func ExampleOpenTopic() {
function Example_openTopicFromURL (line 63) | func Example_openTopicFromURL() {
function ExampleOpenSubscription (line 76) | func ExampleOpenSubscription() {
function Example_extendingAckDeadline (line 112) | func Example_extendingAckDeadline() {
function Example_openSubscriptionFromURL (line 156) | func Example_openSubscriptionFromURL() {
FILE: pubsub/gcppubsub/gcppubsub.go
function init (line 107) | func init() {
type lazyCredsOpener (line 125) | type lazyCredsOpener struct
method defaultConn (line 131) | func (o *lazyCredsOpener) defaultConn(ctx context.Context) (*URLOpener...
method OpenTopicURL (line 163) | func (o *lazyCredsOpener) OpenTopicURL(ctx context.Context, u *url.URL...
method OpenSubscriptionURL (line 171) | func (o *lazyCredsOpener) OpenSubscriptionURL(ctx context.Context, u *...
constant Scheme (line 180) | Scheme = "gcppubsub"
type URLOpener (line 195) | type URLOpener struct
method OpenTopicURL (line 207) | func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pu...
method OpenSubscriptionURL (line 241) | func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.UR...
type topic (line 282) | type topic struct
method SendBatch (line 372) | func (t *topic) SendBatch(ctx context.Context, dms []*driver.Message) ...
method IsRetryable (line 415) | func (t *topic) IsRetryable(error) bool {
method As (line 421) | func (t *topic) As(i any) bool {
method ErrorAs (line 431) | func (*topic) ErrorAs(err error, i any) bool {
method ErrorCode (line 448) | func (*topic) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 453) | func (*topic) Close() error { return nil }
function Dial (line 291) | func Dial(ctx context.Context, ts gcp.TokenSource) (*grpc.ClientConn, fu...
function dialEmulator (line 310) | func dialEmulator(ctx context.Context, e string) (*grpc.ClientConn, erro...
function PublisherClient (line 321) | func PublisherClient(ctx context.Context, conn *grpc.ClientConn) (*raw.P...
function SubscriberClient (line 326) | func SubscriberClient(ctx context.Context, conn *grpc.ClientConn) (*raw....
type TopicOptions (line 331) | type TopicOptions struct
function OpenTopic (line 340) | func OpenTopic(client *raw.PublisherClient, projectID gcp.ProjectID, top...
function OpenTopicByPath (line 354) | func OpenTopicByPath(client *raw.PublisherClient, topicPath string, opts...
function openTopic (line 367) | func openTopic(client *raw.PublisherClient, topicPath string) driver.Top...
function errorAs (line 435) | func errorAs(err error, i any) bool {
type subscription (line 455) | type subscription struct
method ReceiveBatch (line 527) | func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages i...
method SendAcks (line 585) | func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckI...
method CanNack (line 594) | func (s *subscription) CanNack() bool { return true }
method SendNacks (line 597) | func (s *subscription) SendNacks(ctx context.Context, ids []driver.Ack...
method IsRetryable (line 613) | func (s *subscription) IsRetryable(err error) bool {
method As (line 620) | func (s *subscription) As(i any) bool {
method ErrorAs (line 630) | func (*subscription) ErrorAs(err error, i any) bool {
method ErrorCode (line 634) | func (*subscription) ErrorCode(err error) gcerrors.ErrorCode {
method Close (line 639) | func (*subscription) Close() error { return nil }
type SubscriptionOptions (line 462) | type SubscriptionOptions struct
function OpenSubscription (line 485) | func OpenSubscription(client *raw.SubscriberClient, projectID gcp.Projec...
function OpenSubscriptionByPath (line 502) |
Copy disabled (too large)
Download .json
Condensed preview — 1056 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (13,657K chars).
[
{
"path": ".codecov.yml",
"chars": 504,
"preview": "codecov:\n # Removed hardcoded token for security reasons.\n # The token should be set via CI/CD secrets instead.\n # Ex"
},
{
"path": ".gitattributes",
"chars": 234,
"preview": "* text eol=lf\n*.png -text\nsamples/order/testdata/* -text\n/internal/website/data/examples.json linguist-generated=true\n*"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 733,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\n\n---\n\nPlease use a title starting with the name of the af"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 773,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\n\n---\n\nPlease use a title starting with the name of the"
},
{
"path": ".github/pull_request_template.md",
"chars": 403,
"preview": "Please use a title starting with the name of the affected package, or \\\"all\\\",\nfollowed by a colon, followed by a short "
},
{
"path": ".github/workflows/tests.yml",
"chars": 1655,
"preview": "# Copyright 2021 The Go Cloud Development Kit Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": ".gitignore",
"chars": 1464,
"preview": "# Binaries for programs and plugins\n*.exe\n*.dll\n*.so\n*.dylib\n/internal/contributebot/contributebot\n/internal/cmd/gocdk/g"
},
{
"path": "AUTHORS",
"chars": 977,
"preview": "# This is the official list of Go Cloud Development Kit authors for copyright\n# purposes.\n# This file is distinct from t"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 333,
"preview": "# Code of Conduct\n\nThis project is covered under the [Go Code of Conduct][]. In summary:\n\n- Treat everyone with respec"
},
{
"path": "CONTRIBUTING.md",
"chars": 11219,
"preview": "# How to Contribute\n\nWe would love to accept your patches and contributions to this project. Here is\nhow you can help.\n\n"
},
{
"path": "CONTRIBUTORS",
"chars": 2208,
"preview": "# This is the official list of people who can contribute\n# (and typically have contributed) code to the Go CDK repositor"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 5889,
"preview": "# The Go Cloud Development Kit (Go CDK)\n\n_Write once, run on any cloud ☁️_\n\n[is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay",
"chars": 17399,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCnNM6o9QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestAttributes.replay",
"chars": 16526,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB3AyjflwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay",
"chars": 8404,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCiBLAKEwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay",
"chars": 4159,
"preview": "{\n \"Initial\": \"AQAAAA7dVMChNFKfDgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay",
"chars": 4159,
"preview": "{\n \"Initial\": \"AQAAAA7dVMChOjAhtgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay",
"chars": 327295,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCiDd39qwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay",
"chars": 2732,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjNq/IsgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestCopy/Works.replay",
"chars": 22129,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjO5aflwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestDelete/NonExistentFails.replay",
"chars": 2532,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCkEG+1GAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestDelete/Works.replay",
"chars": 7603,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCkFXB3sQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay",
"chars": 73998,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB1FLqo7gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestIfNotExist.replay",
"chars": 6532,
"preview": "{\n \"Initial\": \"AQAAAA7go60lHj5a+AA8\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-1.replay",
"chars": 16740,
"preview": "{\n \"Initial\": \"AQAAAA7dviK+Le0BggAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-2.replay",
"chars": 16900,
"preview": "{\n \"Initial\": \"AQAAAA7dviK/AFHY1wAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-3.replay",
"chars": 16235,
"preview": "{\n \"Initial\": \"AQAAAA7dviK/Deb0YQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-4.replay",
"chars": 15810,
"preview": "{\n \"Initial\": \"AQAAAA7dviK9AyqergAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-5.replay",
"chars": 15630,
"preview": "{\n \"Initial\": \"AQAAAA7dviK7N03TdwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-6.replay",
"chars": 15800,
"preview": "{\n \"Initial\": \"AQAAAA7dviK8ChDYvAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-7.replay",
"chars": 15650,
"preview": "{\n \"Initial\": \"AQAAAA7dviK/GnzE5wAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/ascii-8.replay",
"chars": 15800,
"preview": "{\n \"Initial\": \"AQAAAA7dviK+E9kiZAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/backslashes.replay",
"chars": 15870,
"preview": "{\n \"Initial\": \"AQAAAA7dviK9M7fq/gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay",
"chars": 16370,
"preview": "{\n \"Initial\": \"AQAAAA7dviK7KFi4+gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/dotdotslash.replay",
"chars": 16270,
"preview": "{\n \"Initial\": \"AQAAAA7dviK9Jqg6XQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/fwdslashes.replay",
"chars": 15770,
"preview": "{\n \"Initial\": \"AQAAAA7dviK9EGi/5AAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay",
"chars": 917,
"preview": "{\n \"Initial\": \"AQAAAA7dviK7HVicvwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/quote.replay",
"chars": 15870,
"preview": "{\n \"Initial\": \"AQAAAA7dviK8JH3r7QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay",
"chars": 16210,
"preview": "{\n \"Initial\": \"AQAAAA7dviK8F1g/5QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay",
"chars": 10346,
"preview": "{\n \"Initial\": \"AQAAAA7dviK9HbCbqAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/spaces.replay",
"chars": 15770,
"preview": "{\n \"Initial\": \"AQAAAA7dviK8Mav5UAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/startwithdigit.replay",
"chars": 15670,
"preview": "{\n \"Initial\": \"AQAAAA7dviK+ICt8wwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestKeys/unicode.replay",
"chars": 15890,
"preview": "{\n \"Initial\": \"AQAAAA7dviK+BlkmUgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay",
"chars": 15027,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB0ADiWHgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay",
"chars": 15029,
"preview": "{\n \"Initial\": \"AQAAAA7dVMBzMJ5dNgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/by_1.replay",
"chars": 13568,
"preview": "{\n \"Initial\": \"AQAAAA7dVMBzF4U6aQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/by_2.replay",
"chars": 11580,
"preview": "{\n \"Initial\": \"AQAAAA7dVMBzIMxpsAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/by_3.replay",
"chars": 9592,
"preview": "{\n \"Initial\": \"AQAAAA7dVMBzKMlpcgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay",
"chars": 7797,
"preview": "{\n \"Initial\": \"AQAAAA7dVMBzCJGs0gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/no_objects.replay",
"chars": 6913,
"preview": "{\n \"Initial\": \"AQAAAA7dVMBzASrIPwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestList/no_pagination.replay",
"chars": 9599,
"preview": "{\n \"Initial\": \"AQAAAA7dVMBzD7tYAAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestListDelimiters/abc.replay",
"chars": 41361,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB0OxI7mwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestListDelimiters/backslash.replay",
"chars": 42080,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB0JvQpPAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay",
"chars": 41129,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB0EzovHQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestListWeirdKeys.replay",
"chars": 38251,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB0C0xodwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMD5.replay",
"chars": 15368,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjKbU2hQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay",
"chars": 917,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjCuQd1QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/empty.replay",
"chars": 6423,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjA0D66gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay",
"chars": 917,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjCtuhkQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay",
"chars": 917,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjKaZQTQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay",
"chars": 917,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjKa5f2wAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata.replay",
"chars": 6819,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjCusDiQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay",
"chars": 6513,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjGv36sAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay",
"chars": 6543,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjEj8FlAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay",
"chars": 11301,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCjIkG4AgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestNonexistentBucket.replay",
"chars": 5354,
"preview": "{\n \"Initial\": \"AQAAAA7dVMByLQxiIwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestRead/length_0_read.replay",
"chars": 8436,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB2BGw6ZQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestRead/negative_offset_fails.replay",
"chars": 917,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB2BGHBpwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay",
"chars": 15081,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB2GgYGrAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay",
"chars": 15126,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB2Da12yQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestRead/read_in_full.replay",
"chars": 14876,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB2JaSYeAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay",
"chars": 14876,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB2MhiqOgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay",
"chars": 6004,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB1OCLMbQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestSignedURL.replay",
"chars": 17797,
"preview": "{\n \"Initial\": \"AQAAAA7dviK2JCzi3QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestUploadDownload.replay",
"chars": 9712,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCiN511SAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay",
"chars": 25260,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCMCZBfVAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay",
"chars": 23173,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCMEqb1XQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay",
"chars": 6388,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCMMXnlVgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay",
"chars": 2531,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCMLJf7xgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_match.replay",
"chars": 6372,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCMJOHbOAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay",
"chars": 163458,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCNBoKDvwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay",
"chars": 110757,
"preview": "{\n \"Initial\": \"AQAAAA7dVMChKbuqXgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay",
"chars": 8369,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCMOTi7MAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay",
"chars": 3484,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB3KKpGPgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay",
"chars": 6251,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB3H4AeBAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay",
"chars": 6251,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB3F9/72QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay",
"chars": 4754,
"preview": "{\n \"Initial\": \"AQAAAA7dVMB3Ee6ItAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/azureblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay",
"chars": 25236,
"preview": "{\n \"Initial\": \"AQAAAA7dVMCMHDzHRAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": [\n \"\\u003cBlock(l|L)is"
},
{
"path": "blob/blob.go",
"chars": 56459,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/blob_fs.go",
"chars": 7101,
"preview": "// Copyright 2023 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/blob_fs_test.go",
"chars": 3407,
"preview": "// Copyright 2023 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/blob_iter_test.go",
"chars": 1107,
"preview": "package blob_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"gocloud.dev/blob/me"
},
{
"path": "blob/blob_reader_test.go",
"chars": 1833,
"preview": "// Copyright 2022 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/blob_test.go",
"chars": 16231,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/blob_writer_test.go",
"chars": 5320,
"preview": "// Copyright 2019 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/driver/driver.go",
"chars": 20193,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/drivertest/bindata.go",
"chars": 145384,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/drivertest/drivertest.go",
"chars": 77659,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/example_openbucket_test.go",
"chars": 2814,
"preview": "// Copyright 2019 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/example_test.go",
"chars": 15958,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/fileblob/attrs.go",
"chars": 2364,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/fileblob/example_test.go",
"chars": 2123,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/fileblob/fileblob.go",
"chars": 32484,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/fileblob/fileblob_test.go",
"chars": 15597,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/gcsblob/example_test.go",
"chars": 2138,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/gcsblob/gcsblob.go",
"chars": 24733,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/gcsblob/gcsblob_test.go",
"chars": 22696,
"preview": "// Copyright 2018 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/gcsblob/iam.go",
"chars": 2503,
"preview": "// Copyright 2020 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/gcsblob/iam_test.go",
"chars": 2874,
"preview": "// Copyright 2020 The Go Cloud Development Kit Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "blob/gcsblob/testdata/TestBeforeReadNonExistentKey.replay",
"chars": 2308,
"preview": "{\n \"Initial\": \"AQAAAA7hTghqKSvfJgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay",
"chars": 19662,
"preview": "{\n \"Initial\": \"AQAAAA7hTghpMUu+lAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay",
"chars": 19884,
"preview": "{\n \"Initial\": \"AQAAAA7hTghoOHWaZgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestAttributes.replay",
"chars": 20921,
"preview": "{\n \"Initial\": \"AQAAAA7hTghOFJqIEAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay",
"chars": 9046,
"preview": "{\n \"Initial\": \"AQAAAA7hTghTBPw1KAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay",
"chars": 3851,
"preview": "{\n \"Initial\": \"AQAAAA7hTghSIyUnkAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay",
"chars": 3851,
"preview": "{\n \"Initial\": \"AQAAAA7hTghSMlZIWgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay",
"chars": 340751,
"preview": "{\n \"Initial\": \"AQAAAA7hTghTJJwHGQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay",
"chars": 2694,
"preview": "{\n \"Initial\": \"AQAAAA7hTghYLo0cawAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestCopy/Works.replay",
"chars": 25384,
"preview": "{\n \"Initial\": \"AQAAAA7hTghYNgZ+lgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestDelete/NonExistentFails.replay",
"chars": 2534,
"preview": "{\n \"Initial\": \"AQAAAA7hTghZLfCE1AAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestDelete/Works.replay",
"chars": 8311,
"preview": "{\n \"Initial\": \"AQAAAA7hTghZNal7twAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay",
"chars": 73143,
"preview": "{\n \"Initial\": \"AQAAAA7hTghJH31MvQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestIfNotExist.replay",
"chars": 7196,
"preview": "{\n \"Initial\": \"AQAAAA7hTghoJE6RkwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-1.replay",
"chars": 19332,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxhDFoUVAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-2.replay",
"chars": 19288,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxbBKKKagAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-3.replay",
"chars": 18348,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxhOVwHqgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-4.replay",
"chars": 17965,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxiLbOM6gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-5.replay",
"chars": 17614,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxbNBYNbgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-6.replay",
"chars": 17850,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxVNwcghgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-7.replay",
"chars": 17632,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxcKvYtswAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/ascii-8.replay",
"chars": 17886,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxdG7hGoQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/backslashes.replay",
"chars": 17948,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxeCWh1ZwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay",
"chars": 18562,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxeLnemqgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/dotdotslash.replay",
"chars": 19245,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxXFFauKwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/fwdslashes.replay",
"chars": 17932,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxYCbnzuAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay",
"chars": 805,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxVL6elsQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/quote.replay",
"chars": 17948,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxfIPTJ6wAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay",
"chars": 18282,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxYNlt9agAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay",
"chars": 18107,
"preview": "{\n \"Initial\": \"AQAAAA7hTgyVI6JD0AAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/spaces.replay",
"chars": 17932,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxZG6hySAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/startwithdigit.replay",
"chars": 17706,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxgFAQh9wAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestKeys/unicode.replay",
"chars": 18116,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxaEiN1HgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay",
"chars": 16421,
"preview": "{\n \"Initial\": \"AQAAAA7hTghFHJ+LWgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay",
"chars": 16427,
"preview": "{\n \"Initial\": \"AQAAAA7hTghEOcoBcAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/by_1.replay",
"chars": 13929,
"preview": "{\n \"Initial\": \"AQAAAA7hTghDOw3KHwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/by_2.replay",
"chars": 12185,
"preview": "{\n \"Initial\": \"AQAAAA7hTghEGtFxMAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/by_3.replay",
"chars": 10440,
"preview": "{\n \"Initial\": \"AQAAAA7hTghEK3GZygAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay",
"chars": 8340,
"preview": "{\n \"Initial\": \"AQAAAA7hTghDG6UvLQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/no_objects.replay",
"chars": 7287,
"preview": "{\n \"Initial\": \"AQAAAA7hTghDCxD6YgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestList/no_pagination.replay",
"chars": 10443,
"preview": "{\n \"Initial\": \"AQAAAA7hTghDKkRCeAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestListDelimiters/abc.replay",
"chars": 45863,
"preview": "{\n \"Initial\": \"AQAAAA7hTghIG+IdYAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestListDelimiters/backslash.replay",
"chars": 45711,
"preview": "{\n \"Initial\": \"AQAAAA7hTghHGCu0OAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay",
"chars": 45583,
"preview": "{\n \"Initial\": \"AQAAAA7hTghGEsfdXwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestListWeirdKeys.replay",
"chars": 46545,
"preview": "{\n \"Initial\": \"AQAAAA7hTghGAy8FYAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMD5.replay",
"chars": 18126,
"preview": "{\n \"Initial\": \"AQAAAA7hTghYBz0Y8QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay",
"chars": 805,
"preview": "{\n \"Initial\": \"AQAAAA7hTghWJcpb1gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/empty.replay",
"chars": 7593,
"preview": "{\n \"Initial\": \"AQAAAA7hTghWEdlkVwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay",
"chars": 805,
"preview": "{\n \"Initial\": \"AQAAAA7hTghWJbsargAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay",
"chars": 805,
"preview": "{\n \"Initial\": \"AQAAAA7hTghYBx7x6gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay",
"chars": 805,
"preview": "{\n \"Initial\": \"AQAAAA7hTghYBy/rxwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata.replay",
"chars": 7861,
"preview": "{\n \"Initial\": \"AQAAAA7hTghWJdbAzgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay",
"chars": 7633,
"preview": "{\n \"Initial\": \"AQAAAA7hTghXGlDr8QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay",
"chars": 7693,
"preview": "{\n \"Initial\": \"AQAAAA7hTghXBSEr5AAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay",
"chars": 11127,
"preview": "{\n \"Initial\": \"AQAAAA7hTghXLs0K1gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestNonexistentBucket.replay",
"chars": 6009,
"preview": "{\n \"Initial\": \"AQAAAA7hTghCHqCu0wAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestRead/length_0_read.replay",
"chars": 8838,
"preview": "{\n \"Initial\": \"AQAAAA7hTghLKCIm8wAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestRead/negative_offset_fails.replay",
"chars": 805,
"preview": "{\n \"Initial\": \"AQAAAA7hTghLKBMCswAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay",
"chars": 15154,
"preview": "{\n \"Initial\": \"AQAAAA7hTghML9IPRQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay",
"chars": 15199,
"preview": "{\n \"Initial\": \"AQAAAA7hTghMBkIhXgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestRead/read_in_full.replay",
"chars": 15862,
"preview": "{\n \"Initial\": \"AQAAAA7hTghNHoK5+QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay",
"chars": 15105,
"preview": "{\n \"Initial\": \"AQAAAA7hTgiZJ8TNWAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay",
"chars": 6586,
"preview": "{\n \"Initial\": \"AQAAAA7hTghLEiQshAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestSignedURL.replay",
"chars": 28421,
"preview": "{\n \"Initial\": \"AQAAAA7hTgxuOM9ZiwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestUploadDownload.replay",
"chars": 11550,
"preview": "{\n \"Initial\": \"AQAAAA7hTghVMEB7WAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay",
"chars": 26412,
"preview": "{\n \"Initial\": \"AQAAAA7hTgizCuh+cAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay",
"chars": 23770,
"preview": "{\n \"Initial\": \"AQAAAA7hTgizJKDzewAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay",
"chars": 7052,
"preview": "{\n \"Initial\": \"AQAAAA7hTgjaDYYI8QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay",
"chars": 2316,
"preview": "{\n \"Initial\": \"AQAAAA7hTgjZIK5pKgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_match.replay",
"chars": 7015,
"preview": "{\n \"Initial\": \"AQAAAA7hTgi0GJ5A8gAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay",
"chars": 111888,
"preview": "{\n \"Initial\": \"AQAAAA7hTgi1GeLAGwAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay",
"chars": 111895,
"preview": "{\n \"Initial\": \"AQAAAA7hTgjkOY5JngAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay",
"chars": 10282,
"preview": "{\n \"Initial\": \"AQAAAA7hTgi1AJ9BNQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay",
"chars": 2309,
"preview": "{\n \"Initial\": \"AQAAAA7hTgizAiNHZgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay",
"chars": 6929,
"preview": "{\n \"Initial\": \"AQAAAA7hTgiyKoGwOQAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay",
"chars": 6929,
"preview": "{\n \"Initial\": \"AQAAAA7hTgiyFmX6HgAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay",
"chars": 2551,
"preview": "{\n \"Initial\": \"AQAAAA7hTgiyCvSrTAAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
},
{
"path": "blob/gcsblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay",
"chars": 26372,
"preview": "{\n \"Initial\": \"AQAAAA7hTgizOLBA/QAA\",\n \"Version\": \"0.2\",\n \"Converter\": {\n \"ScrubBody\": null,\n \"ClearHeaders\": ["
}
]
// ... and 856 more files (download for full content)
About this extraction
This page contains the full source code of the google/go-cloud GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1056 files (12.1 MB), approximately 3.2M tokens, and a symbol index with 3929 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.