├── .gitignore ├── .godoc_config ├── .pre-commit-config.yaml ├── .secrets.baseline ├── .whitesource ├── .yardopts ├── CHANGELOG.md ├── Gemfile ├── LICENSE.txt ├── Makefile ├── NOTICE.txt ├── README.md ├── aws ├── arn │ ├── arn.go │ └── arn_test.go ├── auth │ └── bearer │ │ └── token.go ├── awserr │ ├── error.go │ └── types.go ├── awsutil │ ├── copy.go │ ├── copy_test.go │ ├── equal.go │ ├── equal_test.go │ ├── path_value.go │ ├── path_value_test.go │ ├── prettify.go │ ├── prettify_test.go │ ├── string_value.go │ └── string_value_test.go ├── client │ ├── client.go │ ├── client_test.go │ ├── default_retryer.go │ ├── default_retryer_test.go │ ├── logger.go │ ├── logger_test.go │ ├── metadata │ │ └── client_info.go │ ├── no_op_retryer.go │ └── no_op_retryer_test.go ├── config.go ├── config_test.go ├── context_1_5.go ├── context_1_9.go ├── context_background_1_7.go ├── context_sleep.go ├── context_test.go ├── convert_types.go ├── convert_types_test.go ├── corehandlers │ ├── handlers.go │ ├── handlers_test.go │ ├── param_validator.go │ ├── param_validator_test.go │ ├── user_agent.go │ └── user_agent_test.go ├── credentials │ ├── chain_provider.go │ ├── chain_provider_test.go │ ├── context_background_go1.7.go │ ├── context_go1.9.go │ ├── credentials.go │ ├── credentials_bench_test.go │ ├── credentials_test.go │ ├── endpointcreds │ │ ├── provider.go │ │ └── provider_test.go │ ├── env_provider.go │ ├── env_provider_test.go │ ├── example.ini │ ├── ibmiam │ │ ├── common.go │ │ ├── common_ini_provider.go │ │ ├── custom_init_func_provider.go │ │ ├── env_provider.go │ │ ├── env_provider_trusted_profile.go │ │ ├── iamcreds_file_utils.go │ │ ├── providers_test.go │ │ ├── shared_config_provider.go │ │ ├── shared_credentials_provider.go │ │ ├── static_provider.go │ │ ├── token │ │ │ └── token.go │ │ ├── tokenmanager │ │ │ ├── client.go │ │ │ ├── client_test.go │ │ │ ├── helper.go │ │ │ ├── token_manager.go │ │ │ ├── token_manager_interface.go │ │ │ └── token_manager_test.go │ │ ├── trusted_profile.go │ │ └── trusted_profile_provider.go │ ├── plugincreds │ │ ├── provider.go │ │ └── provider_test.go │ ├── processcreds │ │ ├── provider.go │ │ ├── provider_test.go │ │ └── testdata │ │ │ ├── expired.json │ │ │ ├── longsessiontoken.json │ │ │ ├── malformed.json │ │ │ ├── missingkey.json │ │ │ ├── missingsecret.json │ │ │ ├── nonexpire.json │ │ │ ├── shconfig.ini │ │ │ ├── shconfig_win.ini │ │ │ ├── shcred.ini │ │ │ ├── shcred_win.ini │ │ │ ├── static.json │ │ │ ├── verybad.json │ │ │ └── wrongversion.json │ ├── shared_credentials_provider.go │ ├── shared_credentials_provider_test.go │ ├── static_provider.go │ └── static_provider_test.go ├── defaults │ ├── defaults.go │ └── shared_config.go ├── doc.go ├── ec2metadata │ ├── api.go │ ├── api_test.go │ ├── service.go │ ├── service_test.go │ └── token_provider.go ├── endpoints │ ├── decode.go │ ├── decode_test.go │ ├── defaults.go │ ├── dep_service_ids.go │ ├── doc.go │ ├── endpoints.go │ ├── endpoints_test.go │ ├── example_test.go │ ├── legacy_regions.go │ ├── v3model.go │ ├── v3model_codegen.go │ ├── v3model_legacy_region_test.go │ ├── v3model_shared_test.go │ └── v3model_test.go ├── errors.go ├── jsonvalue.go ├── logger.go ├── request │ ├── connection_reset_error.go │ ├── connection_reset_error_test.go │ ├── handlers.go │ ├── handlers_test.go │ ├── http_request.go │ ├── http_request_copy_test.go │ ├── http_request_retry_test.go │ ├── offset_reader.go │ ├── offset_reader_test.go │ ├── request.go │ ├── request_1_11_test.go │ ├── request_1_6_test.go │ ├── request_1_8.go │ ├── request_context.go │ ├── request_context_test.go │ ├── request_internal_test.go │ ├── request_pagination.go │ ├── request_pagination_test.go │ ├── request_resetbody_test.go │ ├── request_retry_test.go │ ├── request_test.go │ ├── retryer.go │ ├── retryer_test.go │ ├── timeout_read_closer.go │ ├── timeout_read_closer_benchmark_test.go │ ├── timeout_read_closer_test.go │ ├── validation.go │ ├── waiter.go │ └── waiter_test.go ├── session │ ├── client_tls_cert_test.go │ ├── credentials.go │ ├── custom_ca_bundle_test.go │ ├── custom_transport.go │ ├── custom_transport_go1.12.go │ ├── custom_transport_go1.5.go │ ├── custom_transport_go1.6.go │ ├── doc.go │ ├── env_config.go │ ├── env_config_test.go │ ├── session.go │ ├── session_test.go │ ├── shared_config.go │ ├── shared_config_test.go │ ├── shared_test.go │ └── testdata │ │ ├── credential_source_config │ │ ├── credential_source_config_for_windows │ │ ├── shared_config │ │ ├── shared_config_invalid_ini │ │ ├── shared_config_other │ │ └── test_json.json ├── signer │ ├── ibmiam │ │ ├── common.go │ │ ├── ibmiam.go │ │ └── oauth_signer_test.go │ ├── signer_router.go │ ├── signer_router_test.go │ └── v4 │ │ ├── functional_1_5_test.go │ │ ├── functional_test.go │ │ ├── header_rules.go │ │ ├── header_rules_test.go │ │ ├── options.go │ │ ├── request_context_go1.7.go │ │ ├── stream.go │ │ ├── stream_test.go │ │ ├── uri_path.go │ │ ├── v4.go │ │ └── v4_test.go ├── types.go ├── types_test.go ├── url.go └── version.go ├── awstesting ├── README.md ├── assert.go ├── assert_test.go ├── client.go ├── client_tls_cert.go ├── cmd │ └── bucket_cleanup │ │ └── main.go ├── custom_ca_bundle.go ├── discard.go ├── endless_reader.go ├── integration │ ├── integration.go │ ├── performance │ │ ├── s3DownloadManager │ │ │ ├── client.go │ │ │ ├── config.go │ │ │ ├── main.go │ │ │ ├── main_test.go │ │ │ └── metric.go │ │ ├── s3GetObject │ │ │ ├── client.go │ │ │ ├── config.go │ │ │ ├── logger.go │ │ │ ├── main.go │ │ │ └── trace.go │ │ └── s3UploadManager │ │ │ ├── client.go │ │ │ ├── config.go │ │ │ ├── main.go │ │ │ ├── main_test.go │ │ │ └── metric.go │ └── s3integ │ │ └── shared.go ├── mock │ └── mock.go ├── sandbox │ ├── Dockerfile.golang-tip │ ├── Dockerfile.test.go1.10 │ ├── Dockerfile.test.go1.11 │ ├── Dockerfile.test.go1.12 │ ├── Dockerfile.test.go1.13 │ ├── Dockerfile.test.go1.14 │ ├── Dockerfile.test.go1.15 │ ├── Dockerfile.test.go1.16 │ ├── Dockerfile.test.go1.17 │ ├── Dockerfile.test.go1.18 │ ├── Dockerfile.test.go1.19 │ ├── Dockerfile.test.go1.5 │ ├── Dockerfile.test.go1.5-novendorexp │ ├── Dockerfile.test.go1.6 │ ├── Dockerfile.test.go1.7 │ ├── Dockerfile.test.go1.8 │ ├── Dockerfile.test.go1.9 │ └── Dockerfile.test.gotip ├── unit │ └── unit.go ├── util.go └── util_test.go ├── doc-src ├── aws-godoc │ └── templates │ │ ├── callgraph.html │ │ ├── codewalk.html │ │ ├── codewalkdir.html │ │ ├── dirlist.html │ │ ├── error.html │ │ ├── example.html │ │ ├── godoc.html │ │ ├── godocs.js │ │ ├── implements.html │ │ ├── jquery.js │ │ ├── jquery.treeview.css │ │ ├── jquery.treeview.edit.js │ │ ├── jquery.treeview.js │ │ ├── methodset.html │ │ ├── opensearch.xml │ │ ├── package.txt │ │ ├── package_default.html │ │ ├── package_service.html │ │ ├── pkglist.html │ │ ├── search.html │ │ ├── search.txt │ │ ├── searchcode.html │ │ ├── searchdoc.html │ │ ├── searchtxt.html │ │ ├── style.css │ │ └── user_guide_example.html └── plugin │ ├── plugin.rb │ └── templates │ └── default │ ├── layout │ └── html │ │ └── footer.erb │ ├── module │ └── html │ │ ├── client.erb │ │ ├── item_summary.erb │ │ └── setup.rb │ ├── package │ └── html │ │ └── setup.rb │ └── struct │ └── html │ ├── paginators.erb │ ├── request_methods.erb │ └── setup.rb ├── doc.go ├── example ├── aws │ ├── credentials │ │ └── plugincreds │ │ │ ├── README.md │ │ │ ├── main.go │ │ │ └── plugin │ │ │ └── plugin.go │ └── request │ │ ├── customRetryer │ │ └── custom_retryer.go │ │ ├── handleServiceErrorCodes │ │ └── handleServiceErrorCodes.go │ │ ├── httptrace │ │ ├── client.go │ │ ├── config.go │ │ ├── main.go │ │ └── trace.go │ │ └── withContext │ │ └── withContext.go └── service │ └── s3 │ ├── concatObjects │ ├── README.md │ └── concatObjects.go │ ├── getObjectWithProgress │ ├── README.md │ └── getObjectWithProgress.go │ ├── listObjects │ ├── README.md │ └── listObjects.go │ ├── listObjectsConcurrently │ ├── README.md │ └── listObjectsConcurrently.go │ ├── loggingUploadObjectReadBehavior │ ├── README.md │ └── main.go │ ├── presignURL │ ├── README.md │ ├── client │ │ └── client.go │ └── server │ │ └── server.go │ ├── putObjectAcl │ ├── README.md │ └── putObjectAcl.go │ ├── putObjectWithProcess │ ├── README.md │ └── putObjWithProcess.go │ └── sync │ ├── README.md │ └── sync.go ├── go.mod ├── go.sum ├── internal ├── ini │ ├── ast.go │ ├── bench_test.go │ ├── comma_token.go │ ├── comment_token.go │ ├── doc.go │ ├── empty_token.go │ ├── expression.go │ ├── fuzz.go │ ├── fuzz_test.go │ ├── ini.go │ ├── ini_lexer.go │ ├── ini_lexer_test.go │ ├── ini_parser.go │ ├── ini_parser_test.go │ ├── literal_tokens.go │ ├── literal_tokens_test.go │ ├── newline_token.go │ ├── number_helper.go │ ├── number_helper_test.go │ ├── op_tokens.go │ ├── op_tokens_test.go │ ├── parse_error.go │ ├── parse_stack.go │ ├── parse_stack_test.go │ ├── sep_tokens.go │ ├── sep_tokens_test.go │ ├── skipper.go │ ├── skipper_test.go │ ├── statement.go │ ├── testdata │ │ ├── invalid │ │ │ ├── bad_section_name │ │ │ ├── bad_syntax_1 │ │ │ ├── bad_syntax_2 │ │ │ ├── incomplete_section_profile │ │ │ ├── invalid_keys │ │ │ └── syntax_error_comment │ │ └── valid │ │ │ ├── arn_profile │ │ │ ├── arn_profile_expected │ │ │ ├── array_profile │ │ │ ├── array_profile_expected │ │ │ ├── base_numbers_profile │ │ │ ├── base_numbers_profile_expected │ │ │ ├── commented_profile │ │ │ ├── commented_profile_expected │ │ │ ├── empty_profile │ │ │ ├── empty_profile_expected │ │ │ ├── escaped_profile │ │ │ ├── escaped_profile_expected │ │ │ ├── exponent_profile │ │ │ ├── exponent_profile_expected │ │ │ ├── global_values_profile │ │ │ ├── global_values_profile_expected │ │ │ ├── issue_2253 │ │ │ ├── issue_2253_expected │ │ │ ├── issue_2281 │ │ │ ├── issue_2281_expected │ │ │ ├── issue_2800 │ │ │ ├── issue_2800_expected │ │ │ ├── nested_fields │ │ │ ├── nested_fields_expected │ │ │ ├── number_lhs_expr │ │ │ ├── number_lhs_expr_expected │ │ │ ├── op_sep_in_values │ │ │ ├── op_sep_in_values_expected │ │ │ ├── profile_name │ │ │ ├── profile_name_expected │ │ │ ├── sections_profile │ │ │ ├── sections_profile_expected │ │ │ ├── simple_profile │ │ │ ├── simple_profile_expected │ │ │ ├── space_lhs │ │ │ ├── space_lhs_expected │ │ │ ├── utf_8_profile │ │ │ └── utf_8_profile_expected │ ├── trim_spaces_test.go │ ├── value_util.go │ ├── value_util_test.go │ ├── visitor.go │ ├── walker.go │ ├── walker_test.go │ └── ws_token.go ├── s3shared │ ├── arn │ │ ├── accesspoint_arn.go │ │ ├── accesspoint_arn_test.go │ │ ├── arn.go │ │ ├── arn_test.go │ │ ├── outpost_arn.go │ │ ├── outpost_arn_test.go │ │ └── s3_object_lambda_arn.go │ ├── endpoint_errors.go │ ├── resource_request.go │ └── s3err │ │ └── error.go ├── sdkio │ ├── byte.go │ └── io_go1.7.go ├── sdkmath │ ├── floor.go │ └── floor_go1.9.go ├── sdkrand │ ├── locked_source.go │ └── read.go ├── sdktesting │ └── env.go ├── sdkuri │ ├── path.go │ └── path_test.go ├── shareddefaults │ ├── ecs_container.go │ ├── shared_config.go │ ├── shared_config_other_test.go │ ├── shared_config_resolve_home.go │ ├── shared_config_resolve_home_go1.12.go │ └── shared_config_windows_test.go ├── smithytesting │ ├── document.go │ ├── document_test.go │ └── xml │ │ ├── doc.go │ │ ├── sort.go │ │ ├── sort_test.go │ │ └── xmlToStruct.go ├── strings │ ├── strings.go │ └── strings_test.go └── sync │ └── singleflight │ ├── LICENSE │ ├── singleflight.go │ └── singleflight_test.go ├── models ├── apis │ ├── check_collisions_test.go │ ├── kms │ │ └── 2014-11-01 │ │ │ ├── api-2.json │ │ │ ├── docs-2.json │ │ │ ├── examples-1.json │ │ │ ├── paginators-1.json │ │ │ └── smoke.json │ ├── s3 │ │ └── 2006-03-01 │ │ │ ├── api-2.json │ │ │ ├── docs-2.json │ │ │ ├── examples-1.json │ │ │ ├── paginators-1.json │ │ │ ├── smoke.json │ │ │ └── waiters-2.json │ └── stub.go ├── endpoints │ ├── endpoints.json │ └── generate.go └── protocol_tests │ ├── input │ ├── ec2.json │ ├── json.json │ ├── query.json │ ├── rest-json.json │ └── rest-xml.json │ └── output │ ├── ec2.json │ ├── json.json │ ├── query.json │ ├── rest-json.json │ └── rest-xml.json ├── private ├── README.md ├── checksum │ └── content_md5.go ├── model │ ├── api │ │ ├── api.go │ │ ├── api_test.go │ │ ├── codegentest │ │ │ ├── models │ │ │ │ ├── jsonrpc │ │ │ │ │ └── 0000-00-00 │ │ │ │ │ │ ├── api-2.json │ │ │ │ │ │ └── docs-2.json │ │ │ │ ├── restjson │ │ │ │ │ └── 0000-00-00 │ │ │ │ │ │ ├── api-2.json │ │ │ │ │ │ └── docs-2.json │ │ │ │ └── restxml │ │ │ │ │ └── 0000-00-00 │ │ │ │ │ ├── api-2.json │ │ │ │ │ └── docs-2.json │ │ │ └── service │ │ │ │ ├── generate.go │ │ │ │ ├── restjsonservice │ │ │ │ ├── api.go │ │ │ │ ├── doc.go │ │ │ │ ├── errors.go │ │ │ │ ├── eventstream_test.go │ │ │ │ ├── restjsonserviceiface │ │ │ │ │ └── interface.go │ │ │ │ └── service.go │ │ │ │ ├── restxmlservice │ │ │ │ ├── api.go │ │ │ │ ├── doc.go │ │ │ │ ├── errors.go │ │ │ │ ├── eventstream_test.go │ │ │ │ ├── restxmlserviceiface │ │ │ │ │ └── interface.go │ │ │ │ └── service.go │ │ │ │ └── rpcservice │ │ │ │ ├── api.go │ │ │ │ ├── doc.go │ │ │ │ ├── errors.go │ │ │ │ ├── eventstream_test.go │ │ │ │ ├── rpcserviceiface │ │ │ │ └── interface.go │ │ │ │ └── service.go │ │ ├── customization_passes.go │ │ ├── docstring.go │ │ ├── docstring_test.go │ │ ├── endpoint_arn.go │ │ ├── endpoint_trait.go │ │ ├── eventstream.go │ │ ├── eventstream_tmpl.go │ │ ├── eventstream_tmpl_reader.go │ │ ├── eventstream_tmpl_readertests.go │ │ ├── eventstream_tmpl_tests.go │ │ ├── eventstream_tmpl_writer.go │ │ ├── eventstream_tmpl_writertests.go │ │ ├── example.go │ │ ├── example_test.go │ │ ├── examples_builder.go │ │ ├── examples_builder_customizations.go │ │ ├── exportable_name.go │ │ ├── legacy_io_suffix.go │ │ ├── legacy_jsonvalue.go │ │ ├── legacy_struct_names.go │ │ ├── legacy_stutter.go │ │ ├── list_of_shame.go │ │ ├── load.go │ │ ├── load_test.go │ │ ├── logger.go │ │ ├── operation.go │ │ ├── pagination.go │ │ ├── param_filler.go │ │ ├── passes.go │ │ ├── passes_test.go │ │ ├── s3manger_input.go │ │ ├── service_name.go │ │ ├── shape.go │ │ ├── shape_alias.go │ │ ├── shape_validation.go │ │ ├── shape_value_builder.go │ │ ├── shapetag_test.go │ │ ├── smoke.go │ │ └── waiters.go │ └── cli │ │ ├── api-info │ │ └── api-info.go │ │ ├── cleanup-models │ │ └── main.go │ │ ├── gen-api │ │ └── main.go │ │ ├── gen-endpoints │ │ └── main.go │ │ └── gen-protocol-tests │ │ └── main.go ├── protocol │ ├── eventstream │ │ ├── debug.go │ │ ├── decode.go │ │ ├── decode_test.go │ │ ├── encode.go │ │ ├── encode_test.go │ │ ├── error.go │ │ ├── eventstreamapi │ │ │ ├── error.go │ │ │ ├── reader.go │ │ │ ├── reader_test.go │ │ │ ├── shared.go │ │ │ ├── shared_test.go │ │ │ ├── signer.go │ │ │ ├── signer_test.go │ │ │ ├── stream_writer.go │ │ │ ├── transport.go │ │ │ ├── transport_go1.17.go │ │ │ ├── writer.go │ │ │ └── writer_test.go │ │ ├── eventstreamtest │ │ │ ├── setup_server.go │ │ │ ├── setup_server_1_10.go │ │ │ ├── stub_go1.9.go │ │ │ ├── stub_old.go │ │ │ ├── testing.go │ │ │ └── testing_1_7.go │ │ ├── header.go │ │ ├── header_test.go │ │ ├── header_value.go │ │ ├── header_value_test.go │ │ ├── message.go │ │ ├── shared_test.go │ │ └── testdata │ │ │ ├── decoded │ │ │ ├── negative │ │ │ │ ├── corrupted_header_len │ │ │ │ ├── corrupted_headers │ │ │ │ ├── corrupted_length │ │ │ │ └── corrupted_payload │ │ │ └── positive │ │ │ │ ├── all_headers │ │ │ │ ├── empty_message │ │ │ │ ├── int32_header │ │ │ │ ├── payload_no_headers │ │ │ │ └── payload_one_str_header │ │ │ └── encoded │ │ │ ├── negative │ │ │ ├── corrupted_header_len │ │ │ ├── corrupted_headers │ │ │ ├── corrupted_length │ │ │ └── corrupted_payload │ │ │ └── positive │ │ │ ├── all_headers │ │ │ ├── empty_message │ │ │ ├── int32_header │ │ │ ├── payload_no_headers │ │ │ └── payload_one_str_header │ ├── host.go │ ├── host_prefix.go │ ├── host_prefix_test.go │ ├── host_test.go │ ├── idempotency.go │ ├── idempotency_test.go │ ├── json │ │ └── jsonutil │ │ │ ├── build.go │ │ │ ├── build_test.go │ │ │ ├── unmarshal.go │ │ │ └── unmarshal_test.go │ ├── jsonrpc │ │ ├── build_test.go │ │ ├── jsonrpc.go │ │ ├── unmarshal_err_test.go │ │ ├── unmarshal_error.go │ │ └── unmarshal_test.go │ ├── jsonvalue.go │ ├── jsonvalue_test.go │ ├── payload.go │ ├── protocol.go │ ├── protocol_test.go │ ├── query │ │ ├── build.go │ │ ├── build_test.go │ │ ├── queryutil │ │ │ └── queryutil.go │ │ ├── unmarshal.go │ │ ├── unmarshal_error.go │ │ ├── unmarshal_error_test.go │ │ └── unmarshal_test.go │ ├── rest │ │ ├── build.go │ │ ├── build_test.go │ │ ├── payload.go │ │ ├── rest_test.go │ │ └── unmarshal.go │ ├── restjson │ │ ├── build_test.go │ │ ├── restjson.go │ │ ├── unmarshal_error.go │ │ └── unmarshal_test.go │ ├── restxml │ │ ├── build_test.go │ │ ├── restxml.go │ │ └── unmarshal_test.go │ ├── timestamp.go │ ├── timestamp_test.go │ ├── unmarshal.go │ ├── unmarshal_error.go │ ├── unmarshal_test.go │ └── xml │ │ └── xmlutil │ │ ├── build.go │ │ ├── build_test.go │ │ ├── sort.go │ │ ├── sort_test.go │ │ ├── unmarshal.go │ │ ├── unmarshal_test.go │ │ └── xml_to_struct.go ├── signer │ └── v2 │ │ ├── v2.go │ │ └── v2_test.go └── util │ ├── sort_keys.go │ └── util.go └── service ├── generate.go ├── kms ├── api.go ├── doc.go ├── errors.go ├── examples_test.go ├── integ_test.go ├── kmsiface │ └── interface.go └── service.go └── s3 ├── api.go ├── bench_test.go ├── body_hash.go ├── body_hash_test.go ├── bucket_location.go ├── bucket_location_test.go ├── content_md5_test.go ├── customizations.go ├── customizations_test.go ├── doc.go ├── doc_custom.go ├── endpoint.go ├── endpoint_builder.go ├── errors.go ├── examples_test.go ├── host_style_bucket.go ├── host_style_bucket_test.go ├── ibm_service_instance_id_test.go ├── integ_test.go ├── internal └── s3testing │ └── s3testing.go ├── platform_handlers.go ├── platform_handlers_go1.6.go ├── platform_handlers_go1.6_test.go ├── s3crypto ├── aes_cbc.go ├── aes_cbc_content_cipher.go ├── aes_cbc_content_cipher_test.go ├── aes_cbc_padder.go ├── aes_cbc_padder_test.go ├── aes_cbc_test.go ├── aes_gcm.go ├── aes_gcm_content_cipher.go ├── aes_gcm_content_cipher_test.go ├── aes_gcm_test.go ├── cipher.go ├── cipher_builder.go ├── cipher_test.go ├── cipher_util.go ├── cipher_util_test.go ├── crypto_registry.go ├── crypto_registry_test.go ├── decryption_client.go ├── decryption_client_test.go ├── decryption_client_v2.go ├── decryption_client_v2_test.go ├── doc.go ├── encryption_client.go ├── encryption_client_test.go ├── encryption_client_v2.go ├── encryption_client_v2_test.go ├── envelope.go ├── envelope_test.go ├── errors.go ├── fixture.go ├── hash_io.go ├── hash_io_test.go ├── helper.go ├── helper_test.go ├── integ_test.go ├── integration │ └── main_test.go ├── key_handler.go ├── key_handler_test.go ├── kms_context_key_handler.go ├── kms_context_key_handler_test.go ├── kms_key_handler.go ├── kms_key_handler_test.go ├── mat_desc.go ├── mat_desc_test.go ├── migrations_test.go ├── mock_test.go ├── padder.go ├── pkcs7_padder.go ├── pkcs7_padder_test.go ├── shared_client.go ├── strategy.go ├── strategy_test.go └── testdata │ └── aes_gcm.json ├── s3iface └── interface.go ├── s3manager ├── arn.go ├── batch.go ├── batch_1_7_test.go ├── batch_test.go ├── bucket_region.go ├── bucket_region_test.go ├── buffered_read_seeker.go ├── buffered_read_seeker_test.go ├── default_read_seeker_write_to.go ├── default_read_seeker_write_to_windows.go ├── default_writer_read_from.go ├── default_writer_read_from_windows.go ├── doc.go ├── download.go ├── download_test.go ├── examples_test.go ├── integ_bucket_region_test.go ├── integ_shared_test.go ├── integ_upload_test.go ├── pool.go ├── pool_test.go ├── read_seeker_write_to.go ├── s3manageriface │ └── interface.go ├── shared_test.go ├── upload.go ├── upload_input.go ├── upload_test.go ├── writer_read_from.go └── writer_read_from_test.go ├── service.go ├── sse.go ├── sse_test.go ├── statusok_error.go ├── statusok_error_test.go ├── testdata ├── positive_select.csv └── virtual_host.json ├── unmarshal_error.go ├── unmarshal_error_leak_test.go ├── unmarshal_error_test.go └── waiters.go /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | /doc 3 | /doc-staging 4 | .yardoc 5 | Gemfile.lock 6 | awstesting/integration/smoke/**/importmarker__.go 7 | awstesting/integration/smoke/_test/ 8 | /vendor/** 9 | /private/model/cli/gen-api/gen-api 10 | 11 | .idea 12 | ./.idea/** 13 | 14 | .code 15 | ./.code/** 16 | 17 | .project 18 | -------------------------------------------------------------------------------- /.godoc_config: -------------------------------------------------------------------------------- 1 | { 2 | "PkgHandler": { 3 | "Pattern": "/sdk-for-go/api/", 4 | "StripPrefix": "/sdk-for-go/api", 5 | "Include": ["/src/github.com/IBM/ibm-cos-sdk-go/aws", "/src/github.com/IBM/ibm-cos-sdk-go/service"], 6 | "Exclude": ["/src/cmd", "/src/github.com/IBM/ibm-cos-sdk-go/awstesting", "/src/github.com/IBM/ibm-cos-sdk-go/awsmigrate", "/src/github.com/IBM/ibm-cos-sdk-go/private"], 7 | "IgnoredSuffixes": ["iface"] 8 | }, 9 | "Github": { 10 | "Tag": "master", 11 | "Repo": "/aws/aws-sdk-go", 12 | "UseGithub": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # This is an example configuration to enable detect-secrets in the pre-commit hook. 2 | # Add this file to the root folder of your repository. 3 | # 4 | # Read pre-commit hook framework https://pre-commit.com/ for more details about the structure of config yaml file and how git pre-commit would invoke each hook. 5 | # 6 | # This line indicates we will use the hook from ibm/detect-secrets to run scan during committing phase. 7 | repos: 8 | - repo: https://github.com/ibm/detect-secrets 9 | # If you desire to use a specific version of detect-secrets, you can replace `master` with other git revisions such as branch, tag or commit sha. 10 | # You are encouraged to use static refs such as tags, instead of branch name 11 | # 12 | # Running "pre-commit autoupdate" automatically updates rev to latest tag 13 | rev: 0.13.1+ibm.61.dss 14 | hooks: 15 | - id: detect-secrets # pragma: whitelist secret 16 | # Add options for detect-secrets-hook binary. You can run `detect-secrets-hook --help` to list out all possible options. 17 | # You may also run `pre-commit run detect-secrets` to preview the scan result. 18 | # when "--baseline" without "--use-all-plugins", pre-commit scan with just plugins in baseline file 19 | # when "--baseline" with "--use-all-plugins", pre-commit scan with all available plugins 20 | # add "--fail-on-unaudited" to fail pre-commit for unaudited potential secrets 21 | args: [--baseline, .secrets.baseline, --use-all-plugins] 22 | -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "settingsInheritedFrom": "whitesource-config/whitesource-config@master" 3 | } -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --plugin go 2 | -e doc-src/plugin/plugin.rb 3 | -m markdown 4 | -o doc/api 5 | --title "IBM COS SDK for Go" 6 | aws/**/*.go 7 | service/**/*.go 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'yard', git: 'https://github.com/lsegal/yard.git', branch: 'main' 3 | gem 'yard-go', git: 'https://github.com/lsegal/yard-go.git', branch: 'master' 4 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | AWS SDK for Go 2 | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | Copyright 2014-2015 Stripe, Inc. 4 | -------------------------------------------------------------------------------- /aws/auth/bearer/token.go: -------------------------------------------------------------------------------- 1 | package bearer 2 | 3 | import ( 4 | "github.com/IBM/ibm-cos-sdk-go/aws" 5 | "time" 6 | ) 7 | 8 | // Token provides a type wrapping a bearer token and expiration metadata. 9 | type Token struct { 10 | Value string 11 | 12 | CanExpire bool 13 | Expires time.Time 14 | } 15 | 16 | // Expired returns if the token's Expires time is before or equal to the time 17 | // provided. If CanExpire is false, Expired will always return false. 18 | func (t Token) Expired(now time.Time) bool { 19 | if !t.CanExpire { 20 | return false 21 | } 22 | now = now.Round(0) 23 | return now.Equal(t.Expires) || now.After(t.Expires) 24 | } 25 | 26 | // TokenProvider provides interface for retrieving bearer tokens. 27 | type TokenProvider interface { 28 | RetrieveBearerToken(aws.Context) (Token, error) 29 | } 30 | 31 | // TokenProviderFunc provides a helper utility to wrap a function as a type 32 | // that implements the TokenProvider interface. 33 | type TokenProviderFunc func(aws.Context) (Token, error) 34 | 35 | // RetrieveBearerToken calls the wrapped function, returning the Token or 36 | // error. 37 | func (fn TokenProviderFunc) RetrieveBearerToken(ctx aws.Context) (Token, error) { 38 | return fn(ctx) 39 | } 40 | 41 | // StaticTokenProvider provides a utility for wrapping a static bearer token 42 | // value within an implementation of a token provider. 43 | type StaticTokenProvider struct { 44 | Token Token 45 | } 46 | 47 | // RetrieveBearerToken returns the static token specified. 48 | func (s StaticTokenProvider) RetrieveBearerToken(aws.Context) (Token, error) { 49 | return s.Token, nil 50 | } 51 | -------------------------------------------------------------------------------- /aws/awsutil/equal.go: -------------------------------------------------------------------------------- 1 | package awsutil 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | // DeepEqual returns if the two values are deeply equal like reflect.DeepEqual. 8 | // In addition to this, this method will also dereference the input values if 9 | // possible so the DeepEqual performed will not fail if one parameter is a 10 | // pointer and the other is not. 11 | // 12 | // DeepEqual will not perform indirection of nested values of the input parameters. 13 | func DeepEqual(a, b interface{}) bool { 14 | ra := reflect.Indirect(reflect.ValueOf(a)) 15 | rb := reflect.Indirect(reflect.ValueOf(b)) 16 | 17 | if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid { 18 | // If the elements are both nil, and of the same type they are equal 19 | // If they are of different types they are not equal 20 | return reflect.TypeOf(a) == reflect.TypeOf(b) 21 | } else if raValid != rbValid { 22 | // Both values must be valid to be equal 23 | return false 24 | } 25 | 26 | return reflect.DeepEqual(ra.Interface(), rb.Interface()) 27 | } 28 | -------------------------------------------------------------------------------- /aws/awsutil/equal_test.go: -------------------------------------------------------------------------------- 1 | package awsutil_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/aws" 7 | "github.com/IBM/ibm-cos-sdk-go/aws/awsutil" 8 | ) 9 | 10 | func TestDeepEqual(t *testing.T) { 11 | cases := []struct { 12 | a, b interface{} 13 | equal bool 14 | }{ 15 | {"a", "a", true}, 16 | {"a", "b", false}, 17 | {"a", aws.String(""), false}, 18 | {"a", nil, false}, 19 | {"a", aws.String("a"), true}, 20 | {(*bool)(nil), (*bool)(nil), true}, 21 | {(*bool)(nil), (*string)(nil), false}, 22 | {nil, nil, true}, 23 | } 24 | 25 | for i, c := range cases { 26 | if awsutil.DeepEqual(c.a, c.b) != c.equal { 27 | t.Errorf("%d, a:%v b:%v, %t", i, c.a, c.b, c.equal) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /aws/awsutil/prettify_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package awsutil 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/aws" 10 | ) 11 | 12 | type testPrettifyStruct struct { 13 | Field1 string 14 | Field2 *string 15 | Field3 []byte `sensitive:"true"` 16 | Value []*string 17 | } 18 | 19 | func TestPrettify(t *testing.T) { 20 | cases := map[string]struct { 21 | Value interface{} 22 | Expect string 23 | }{ 24 | "general": { 25 | Value: testPrettifyStruct{ 26 | Field1: "abc123", 27 | Field2: aws.String("abc123"), 28 | Field3: []byte("don't show me"), 29 | Value: []*string{ 30 | aws.String("first"), 31 | aws.String("second"), 32 | }, 33 | }, 34 | Expect: `{ 35 | Field1: "abc123", 36 | Field2: "abc123", 37 | Field3: , 38 | Value: ["first","second"], 39 | 40 | }`, 41 | }, 42 | } 43 | 44 | for d, c := range cases { 45 | t.Run(d, func(t *testing.T) { 46 | actual := StringValue(c.Value) 47 | if e, a := c.Expect, actual; e != a { 48 | t.Errorf("expect:\n%v\nactual:\n%v\n", e, a) 49 | } 50 | }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /aws/awsutil/string_value_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package awsutil 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/aws" 10 | ) 11 | 12 | type testStruct struct { 13 | Field1 string 14 | Field2 *string 15 | Field3 []byte `sensitive:"true"` 16 | Value []*string 17 | } 18 | 19 | func TestStringValue(t *testing.T) { 20 | cases := map[string]struct { 21 | Value interface{} 22 | Expect string 23 | }{ 24 | "general": { 25 | Value: testStruct{ 26 | Field1: "abc123", 27 | Field2: aws.String("abc123"), 28 | Field3: []byte("don't show me"), 29 | Value: []*string{ 30 | aws.String("first"), 31 | aws.String("second"), 32 | }, 33 | }, 34 | Expect: `{ 35 | Field1: "abc123", 36 | Field2: "abc123", 37 | Field3: , 38 | Value: ["first","second"], 39 | 40 | }`, 41 | }, 42 | } 43 | 44 | for d, c := range cases { 45 | t.Run(d, func(t *testing.T) { 46 | actual := StringValue(c.Value) 47 | if e, a := c.Expect, actual; e != a { 48 | t.Errorf("expect:\n%v\nactual:\n%v\n", e, a) 49 | } 50 | }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /aws/client/metadata/client_info.go: -------------------------------------------------------------------------------- 1 | package metadata 2 | 3 | // ClientInfo wraps immutable data from the client.Client structure. 4 | type ClientInfo struct { 5 | ServiceName string 6 | ServiceID string 7 | APIVersion string 8 | PartitionID string 9 | Endpoint string 10 | SigningName string 11 | SigningRegion string 12 | JSONVersion string 13 | TargetPrefix string 14 | ResolvedRegion string 15 | } 16 | -------------------------------------------------------------------------------- /aws/client/no_op_retryer.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 7 | ) 8 | 9 | // NoOpRetryer provides a retryer that performs no retries. 10 | // It should be used when we do not want retries to be performed. 11 | type NoOpRetryer struct{} 12 | 13 | // MaxRetries returns the number of maximum returns the service will use to make 14 | // an individual API; For NoOpRetryer the MaxRetries will always be zero. 15 | func (d NoOpRetryer) MaxRetries() int { 16 | return 0 17 | } 18 | 19 | // ShouldRetry will always return false for NoOpRetryer, as it should never retry. 20 | func (d NoOpRetryer) ShouldRetry(_ *request.Request) bool { 21 | return false 22 | } 23 | 24 | // RetryRules returns the delay duration before retrying this request again; 25 | // since NoOpRetryer does not retry, RetryRules always returns 0. 26 | func (d NoOpRetryer) RetryRules(_ *request.Request) time.Duration { 27 | return 0 28 | } 29 | -------------------------------------------------------------------------------- /aws/client/no_op_retryer_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | "time" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 9 | ) 10 | 11 | func TestNoOpRetryer(t *testing.T) { 12 | cases := []struct { 13 | r request.Request 14 | expectMaxRetries int 15 | expectRetryDelay time.Duration 16 | expectRetry bool 17 | }{ 18 | { 19 | r: request.Request{ 20 | HTTPResponse: &http.Response{StatusCode: 200}, 21 | }, 22 | expectMaxRetries: 0, 23 | expectRetryDelay: 0, 24 | expectRetry: false, 25 | }, 26 | } 27 | 28 | d := NoOpRetryer{} 29 | for i, c := range cases { 30 | maxRetries := d.MaxRetries() 31 | retry := d.ShouldRetry(&c.r) 32 | retryDelay := d.RetryRules(&c.r) 33 | 34 | if e, a := c.expectMaxRetries, maxRetries; e != a { 35 | t.Errorf("%d: expected %v, but received %v for number of max retries", i, e, a) 36 | } 37 | 38 | if e, a := c.expectRetry, retry; e != a { 39 | t.Errorf("%d: expected %v, but received %v for should retry", i, e, a) 40 | } 41 | 42 | if e, a := c.expectRetryDelay, retryDelay; e != a { 43 | t.Errorf("%d: expected %v, but received %v as retry delay", i, e, a) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /aws/context_1_9.go: -------------------------------------------------------------------------------- 1 | //go:build go1.9 2 | // +build go1.9 3 | 4 | package aws 5 | 6 | import "context" 7 | 8 | // Context is an alias of the Go stdlib's context.Context interface. 9 | // It can be used within the SDK's API operation "WithContext" methods. 10 | // 11 | // See https://golang.org/pkg/context on how to use contexts. 12 | type Context = context.Context 13 | -------------------------------------------------------------------------------- /aws/context_background_1_7.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package aws 5 | 6 | import "context" 7 | 8 | // BackgroundContext returns a context that will never be canceled, has no 9 | // values, and no deadline. This context is used by the SDK to provide 10 | // backwards compatibility with non-context API operations and functionality. 11 | // 12 | // Go 1.6 and before: 13 | // This context function is equivalent to context.Background in the Go stdlib. 14 | // 15 | // Go 1.7 and later: 16 | // The context returned will be the value returned by context.Background() 17 | // 18 | // See https://golang.org/pkg/context for more information on Contexts. 19 | func BackgroundContext() Context { 20 | return context.Background() 21 | } 22 | -------------------------------------------------------------------------------- /aws/context_sleep.go: -------------------------------------------------------------------------------- 1 | package aws 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // SleepWithContext will wait for the timer duration to expire, or the context 8 | // is canceled. Which ever happens first. If the context is canceled the Context's 9 | // error will be returned. 10 | // 11 | // Expects Context to always return a non-nil error if the Done channel is closed. 12 | func SleepWithContext(ctx Context, dur time.Duration) error { 13 | t := time.NewTimer(dur) 14 | defer t.Stop() 15 | 16 | select { 17 | case <-t.C: 18 | break 19 | case <-ctx.Done(): 20 | return ctx.Err() 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /aws/context_test.go: -------------------------------------------------------------------------------- 1 | package aws_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/aws" 9 | "github.com/IBM/ibm-cos-sdk-go/awstesting" 10 | ) 11 | 12 | func TestSleepWithContext(t *testing.T) { 13 | ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} 14 | 15 | err := aws.SleepWithContext(ctx, 1*time.Millisecond) 16 | if err != nil { 17 | t.Errorf("expect context to not be canceled, got %v", err) 18 | } 19 | } 20 | 21 | func TestSleepWithContext_Canceled(t *testing.T) { 22 | ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} 23 | 24 | expectErr := fmt.Errorf("context canceled") 25 | 26 | ctx.Error = expectErr 27 | close(ctx.DoneCh) 28 | 29 | err := aws.SleepWithContext(ctx, 10*time.Second) 30 | if err == nil { 31 | t.Fatalf("expect error, did not get one") 32 | } 33 | 34 | if e, a := expectErr, err; e != a { 35 | t.Errorf("expect %v error, got %v", e, a) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /aws/corehandlers/param_validator.go: -------------------------------------------------------------------------------- 1 | package corehandlers 2 | 3 | import "github.com/IBM/ibm-cos-sdk-go/aws/request" 4 | 5 | // ValidateParametersHandler is a request handler to validate the input parameters. 6 | // Validating parameters only has meaning if done prior to the request being sent. 7 | var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) { 8 | if !r.ParamsFilled() { 9 | return 10 | } 11 | 12 | if v, ok := r.Params.(request.Validator); ok { 13 | if err := v.Validate(); err != nil { 14 | r.Error = err 15 | } 16 | } 17 | }} 18 | -------------------------------------------------------------------------------- /aws/corehandlers/user_agent.go: -------------------------------------------------------------------------------- 1 | package corehandlers 2 | 3 | import ( 4 | "os" 5 | "runtime" 6 | 7 | "github.com/IBM/ibm-cos-sdk-go/aws" 8 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 9 | ) 10 | 11 | // SDKVersionUserAgentHandler is a request handler for adding the SDK Version 12 | // to the user agent. 13 | var SDKVersionUserAgentHandler = request.NamedHandler{ 14 | Name: "core.SDKVersionUserAgentHandler", 15 | Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion, 16 | runtime.Version(), runtime.GOOS, runtime.GOARCH), 17 | } 18 | 19 | const execEnvVar = `AWS_EXECUTION_ENV` 20 | const execEnvUAKey = `exec-env` 21 | 22 | // AddHostExecEnvUserAgentHander is a request handler appending the SDK's 23 | // execution environment to the user agent. 24 | // 25 | // If the environment variable AWS_EXECUTION_ENV is set, its value will be 26 | // appended to the user agent string. 27 | var AddHostExecEnvUserAgentHander = request.NamedHandler{ 28 | Name: "core.AddHostExecEnvUserAgentHander", 29 | Fn: func(r *request.Request) { 30 | v := os.Getenv(execEnvVar) 31 | if len(v) == 0 { 32 | return 33 | } 34 | 35 | request.AddToUserAgent(r, execEnvUAKey+"/"+v) 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /aws/corehandlers/user_agent_test.go: -------------------------------------------------------------------------------- 1 | package corehandlers 2 | 3 | import ( 4 | "net/http" 5 | "os" 6 | "testing" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 9 | "github.com/IBM/ibm-cos-sdk-go/internal/sdktesting" 10 | ) 11 | 12 | func TestAddHostExecEnvUserAgentHander(t *testing.T) { 13 | cases := []struct { 14 | ExecEnv string 15 | Expect string 16 | }{ 17 | {ExecEnv: "Lambda", Expect: execEnvUAKey + "/Lambda"}, 18 | {ExecEnv: "", Expect: ""}, 19 | {ExecEnv: "someThingCool", Expect: execEnvUAKey + "/someThingCool"}, 20 | } 21 | 22 | for i, c := range cases { 23 | sdktesting.StashEnv() 24 | os.Setenv(execEnvVar, c.ExecEnv) 25 | 26 | req := &request.Request{ 27 | HTTPRequest: &http.Request{ 28 | Header: http.Header{}, 29 | }, 30 | } 31 | AddHostExecEnvUserAgentHander.Fn(req) 32 | 33 | if err := req.Error; err != nil { 34 | t.Fatalf("%d, expect no error, got %v", i, err) 35 | } 36 | 37 | if e, a := c.Expect, req.HTTPRequest.Header.Get("User-Agent"); e != a { 38 | t.Errorf("%d, expect %v user agent, got %v", i, e, a) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /aws/credentials/context_background_go1.7.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package credentials 5 | 6 | import "context" 7 | 8 | // backgroundContext returns a context that will never be canceled, has no 9 | // values, and no deadline. This context is used by the SDK to provide 10 | // backwards compatibility with non-context API operations and functionality. 11 | // 12 | // Go 1.6 and before: 13 | // This context function is equivalent to context.Background in the Go stdlib. 14 | // 15 | // Go 1.7 and later: 16 | // The context returned will be the value returned by context.Background() 17 | // 18 | // See https://golang.org/pkg/context for more information on Contexts. 19 | func backgroundContext() Context { 20 | return context.Background() 21 | } 22 | -------------------------------------------------------------------------------- /aws/credentials/context_go1.9.go: -------------------------------------------------------------------------------- 1 | //go:build go1.9 2 | // +build go1.9 3 | 4 | package credentials 5 | 6 | import "context" 7 | 8 | // Context is an alias of the Go stdlib's context.Context interface. 9 | // It can be used within the SDK's API operation "WithContext" methods. 10 | // 11 | // This type, aws.Context, and context.Context are equivalent. 12 | // 13 | // See https://golang.org/pkg/context on how to use contexts. 14 | type Context = context.Context 15 | -------------------------------------------------------------------------------- /aws/credentials/example.ini: -------------------------------------------------------------------------------- 1 | [default] 2 | aws_access_key_id = accessKey 3 | aws_secret_access_key = secret 4 | aws_session_token = token 5 | 6 | [no_token] 7 | aws_access_key_id = accessKey 8 | aws_secret_access_key = secret 9 | 10 | [with_colon] 11 | aws_access_key_id: accessKey 12 | aws_secret_access_key: secret 13 | -------------------------------------------------------------------------------- /aws/credentials/ibmiam/env_provider.go: -------------------------------------------------------------------------------- 1 | package ibmiam 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/aws" 7 | "github.com/IBM/ibm-cos-sdk-go/aws/credentials" 8 | ) 9 | 10 | // EnvProviderName name of the IBM IAM provider that loads IAM credentials from environment 11 | // variables 12 | const EnvProviderName = "EnvProviderIBM" 13 | 14 | // NewEnvProvider constructor of the IBM IAM provider that loads IAM credentials from environment 15 | // variables 16 | // Parameter: 17 | // 18 | // AWS Config 19 | // 20 | // Returns: 21 | // 22 | // A new provider with AWS config, API Key, IBM IAM Authentication Server Endpoint and 23 | // Service Instance ID 24 | func NewEnvProvider(config *aws.Config) *Provider { 25 | apiKey := os.Getenv("IBM_API_KEY_ID") 26 | serviceInstanceID := os.Getenv("IBM_SERVICE_INSTANCE_ID") 27 | authEndPoint := os.Getenv("IBM_AUTH_ENDPOINT") 28 | 29 | return NewProvider(EnvProviderName, config, apiKey, authEndPoint, serviceInstanceID, nil) 30 | } 31 | 32 | // NewEnvCredentials Constructor 33 | func NewEnvCredentials(config *aws.Config) *credentials.Credentials { 34 | return credentials.NewCredentials(NewEnvProvider(config)) 35 | } 36 | -------------------------------------------------------------------------------- /aws/credentials/ibmiam/env_provider_trusted_profile.go: -------------------------------------------------------------------------------- 1 | package ibmiam 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/aws" 7 | "github.com/IBM/ibm-cos-sdk-go/aws/credentials" 8 | ) 9 | 10 | // EnvProviderName name of the IBM IAM provider that loads IAM trusted profile 11 | // credentials from environment variables 12 | const EnvProviderTrustedProfileName = "EnvProviderTrustedProfileIBM" 13 | 14 | // NewEnvProvider constructor of the IBM IAM provider that loads IAM trusted profile 15 | // credentials from environment variables 16 | // Parameter: 17 | // 18 | // AWS Config 19 | // 20 | // Returns: 21 | // 22 | // A new provider with AWS config, Trusted Profile ID, CR token file path, IBM IAM Authentication Server Endpoint and 23 | // Service Instance ID 24 | func NewEnvProviderTrustedProfile(config *aws.Config) *TrustedProfileProvider { 25 | trustedProfileID := os.Getenv("TRUSTED_PROFILE_ID") 26 | serviceInstanceID := os.Getenv("IBM_SERVICE_INSTANCE_ID") 27 | crTokenFilePath := os.Getenv("CR_TOKEN_FILE_PATH") 28 | authEndPoint := os.Getenv("IBM_AUTH_ENDPOINT") 29 | 30 | return NewTrustedProfileProvider(EnvProviderTrustedProfileName, config, authEndPoint, trustedProfileID, crTokenFilePath, serviceInstanceID, "CR") 31 | } 32 | 33 | // NewEnvCredentials Constructor 34 | func NewEnvCredentialsTrustedProfile(config *aws.Config) *credentials.Credentials { 35 | return credentials.NewCredentials(NewEnvProviderTrustedProfile(config)) 36 | } 37 | -------------------------------------------------------------------------------- /aws/credentials/ibmiam/iamcreds_file_utils.go: -------------------------------------------------------------------------------- 1 | package ibmiam 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 7 | ) 8 | 9 | // Helper function to check whether both api-key and trusted-profile-id are set 10 | // in environment variables. 11 | // 12 | // Returns: 13 | // 14 | // Error if both apiKey and trustedProfileID are set, nil if only either of them is set. 15 | func CheckForConflictingIamCredentials() error { 16 | apiKey := os.Getenv("IBM_API_KEY_ID") 17 | trustedProfileID := os.Getenv("TRUSTED_PROFILE_ID") 18 | 19 | if apiKey != "" && trustedProfileID != "" { 20 | return awserr.New("InvalidCredentials", 21 | `only one of ApiKey or TrustedProfileID should be set, not both`, 22 | nil) 23 | } 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /aws/credentials/ibmiam/static_provider.go: -------------------------------------------------------------------------------- 1 | package ibmiam 2 | 3 | import ( 4 | "github.com/IBM/ibm-cos-sdk-go/aws" 5 | "github.com/IBM/ibm-cos-sdk-go/aws/credentials" 6 | ) 7 | 8 | // StaticProviderName name of the IBM IAM provider that uses IAM details passed directly 9 | const StaticProviderName = "StaticProviderIBM" 10 | 11 | // NewStaticProvider constructor of the IBM IAM provider that uses IAM details passed directly 12 | // Returns: New Provider (AWS type) 13 | func NewStaticProvider(config *aws.Config, authEndPoint, apiKey, serviceInstanceID string) *Provider { 14 | return NewProvider(StaticProviderName, config, apiKey, authEndPoint, serviceInstanceID, nil) 15 | } 16 | 17 | // NewStaticCredentials constructor for IBM IAM that uses IAM credentials passed in 18 | // Returns: credentials.NewCredentials(newStaticProvider()) (AWS type) 19 | func NewStaticCredentials(config *aws.Config, authEndPoint, apiKey, serviceInstanceID string) *credentials.Credentials { 20 | return credentials.NewCredentials(NewStaticProvider(config, authEndPoint, apiKey, serviceInstanceID)) 21 | } 22 | -------------------------------------------------------------------------------- /aws/credentials/ibmiam/token/token.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import "encoding/json" 4 | 5 | // IBMIAMToken holder for the IBM IAM token details 6 | type Token struct { 7 | 8 | // Sets the access token 9 | AccessToken string `json:"access_token"` 10 | 11 | // Sets the refresh token 12 | RefreshToken string `json:"refresh_token"` 13 | 14 | // Sets the token type 15 | TokenType string `json:"token_type"` 16 | 17 | // Scope string `json:"scope"` 18 | 19 | // Sets the expiry timestamp 20 | ExpiresIn int64 `json:"expires_in"` 21 | 22 | // Sets the expiration timestamp 23 | Expiration int64 `json:"expiration"` 24 | } 25 | 26 | // Error type to help parse errors of IAM calls 27 | type Error struct { 28 | Context map[string]interface{} `json:"context"` 29 | ErrorCode string `json:"errorCode"` 30 | ErrorMessage string `json:"errorMessage"` 31 | } 32 | 33 | // Error function 34 | func (ie *Error) Error() string { 35 | bytes, err := json.Marshal(ie) 36 | if err != nil { 37 | return err.Error() 38 | } 39 | return string(bytes) 40 | } 41 | -------------------------------------------------------------------------------- /aws/credentials/ibmiam/tokenmanager/helper.go: -------------------------------------------------------------------------------- 1 | package tokenmanager 2 | 3 | import "net/http" 4 | 5 | // Constant values for the token manager package and testcases 6 | const ( 7 | // Not Match Constants 8 | httpClientNotMatch = "Http Client did not match" 9 | maxRetriesNotMatch = "Max Retries did not match" 10 | logLevelNotMatch = "Log Level did not match" 11 | loggerNotMatch = "logger did not match" 12 | backoffProgressionNotMatch = "BackOff Progression did not match" 13 | numberOfLogEntriesNotMatch = "Number of log entries do not match" 14 | tokensNotMatch = "Tokens do not Match" 15 | 16 | // Backoff constants 17 | initialBackoffUnset = "Initial BackOff unset" 18 | backoffProgressionUnset = "BackOff Progression unset" 19 | 20 | // Error constants 21 | errorBuildingRequest = "Error Building Request" 22 | badNumberOfRetries = "Bad Number of retries" 23 | errorGettingToken = "Error getting token" 24 | 25 | // Global LOGGER constant 26 | debugLog = "" 27 | 28 | // LOGGER constant for IBM Client Implementation 29 | defaultIBMCImpLog = "defaultIBMCImplementation" 30 | 31 | // LOGGER constant for IBM Token Management Implementation 32 | defaultTMImpLog = "defaultTMImplementation" 33 | getOpsLog = "GET OPERATION" 34 | backgroundRefreshLog = "BACKGROUND REFRESH" 35 | 36 | // Global constants 37 | endPoint = "EndPoint" 38 | ) 39 | 40 | // Returns a success response code (200 <= code < 300) 41 | func isSuccess(response *http.Response) bool { 42 | return response.StatusCode >= 200 && response.StatusCode < 300 43 | } 44 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/expired.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "AccessKeyId": "accessKey", 4 | "SecretAccessKey": "secret", 5 | "SessionToken": "tokenDefault", 6 | "Expiration": "2000-01-01T00:00:00-00:00" 7 | } 8 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/longsessiontoken.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "AccessKeyId": "ASIAXXXXXXXXXXXXXXXX", 4 | "Expiration": "2199-01-01T00:00:00Z", 5 | "SecretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 6 | "SessionToken": 7 | "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 8 | } 9 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/malformed.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1 3 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/missingkey.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "AccessKeyId": "accesskey" 4 | } 5 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/missingsecret.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "SecretAccessKey": "secretkey" 4 | } 5 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/nonexpire.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "AccessKeyId": "accessKey", 4 | "SecretAccessKey": "secret", 5 | "SessionToken": "nonDefaultToken" 6 | } 7 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/shconfig.ini: -------------------------------------------------------------------------------- 1 | [default] 2 | credential_process = cat ./testdata/expired.json 3 | 4 | [profile non_expire] 5 | credential_process = cat ./testdata/nonexpire.json 6 | 7 | [profile not_alone] 8 | aws_access_key_id = notFromCredProcAccess 9 | aws_secret_access_key = notFromCredProcSecret 10 | credential_process = cat ./testdata/verybad.json 11 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/shconfig_win.ini: -------------------------------------------------------------------------------- 1 | [default] 2 | credential_process = type .\testdata\expired.json 3 | 4 | [profile non_expire] 5 | credential_process = type .\testdata\nonexpire.json 6 | 7 | [profile not_alone] 8 | aws_access_key_id = notFromCredProcAccess 9 | aws_secret_access_key = notFromCredProcSecret 10 | credential_process = type .\testdata\verybad.json 11 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/shcred.ini: -------------------------------------------------------------------------------- 1 | [default] 2 | credential_process = cat ./testdata/expired.json 3 | 4 | [non_expire] 5 | credential_process = cat ./testdata/nonexpire.json 6 | 7 | [not_alone] 8 | aws_access_key_id = notFromCredProcAccess 9 | aws_secret_access_key = notFromCredProcSecret 10 | credential_process = cat ./testdata/verybad.json 11 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/shcred_win.ini: -------------------------------------------------------------------------------- 1 | [default] 2 | credential_process = type .\testdata\expired.json 3 | 4 | [non_expire] 5 | credential_process = type .\testdata\nonexpire.json 6 | 7 | [not_alone] 8 | aws_access_key_id = notFromCredProcAccess 9 | aws_secret_access_key = notFromCredProcSecret 10 | credential_process = type .\testdata\verybad.json 11 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/static.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version":1, 3 | "AccessKeyId":"accesskey", 4 | "SecretAccessKey":"secretkey" 5 | } 6 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/verybad.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version":1, 3 | "AccessKeyId":"veryBadAccessKeyID", 4 | "SecretAccessKey":"veryBadSecretAccessKey" 5 | } 6 | -------------------------------------------------------------------------------- /aws/credentials/processcreds/testdata/wrongversion.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 2 3 | } 4 | -------------------------------------------------------------------------------- /aws/credentials/static_provider_test.go: -------------------------------------------------------------------------------- 1 | package credentials 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestStaticProviderGet(t *testing.T) { 8 | s := StaticProvider{ 9 | Value: Value{ 10 | AccessKeyID: "AKID", 11 | SecretAccessKey: "SECRET", 12 | SessionToken: "", 13 | }, 14 | } 15 | 16 | creds, err := s.Retrieve() 17 | if err != nil { 18 | t.Errorf("expect nil, got %v", err) 19 | } 20 | if e, a := "AKID", creds.AccessKeyID; e != a { 21 | t.Errorf("expect %v, got %v", e, a) 22 | } 23 | if e, a := "SECRET", creds.SecretAccessKey; e != a { 24 | t.Errorf("expect %v, got %v", e, a) 25 | } 26 | if v := creds.SessionToken; len(v) != 0 { 27 | t.Errorf("Expect no session token, %v", v) 28 | } 29 | } 30 | 31 | func TestStaticProviderIsExpired(t *testing.T) { 32 | s := StaticProvider{ 33 | Value: Value{ 34 | AccessKeyID: "AKID", 35 | SecretAccessKey: "SECRET", 36 | SessionToken: "", 37 | }, 38 | } 39 | 40 | if s.IsExpired() { 41 | t.Errorf("Expect static credentials to never expire") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /aws/defaults/shared_config.go: -------------------------------------------------------------------------------- 1 | package defaults 2 | 3 | import ( 4 | "github.com/IBM/ibm-cos-sdk-go/internal/shareddefaults" 5 | ) 6 | 7 | // SharedCredentialsFilename returns the SDK's default file path 8 | // for the shared credentials file. 9 | // 10 | // Builds the shared config file path based on the OS's platform. 11 | // 12 | // - Linux/Unix: $HOME/.aws/credentials 13 | // - Windows: %USERPROFILE%\.aws\credentials 14 | func SharedCredentialsFilename() string { 15 | return shareddefaults.SharedCredentialsFilename() 16 | } 17 | 18 | // SharedConfigFilename returns the SDK's default file path for 19 | // the shared config file. 20 | // 21 | // Builds the shared config file path based on the OS's platform. 22 | // 23 | // - Linux/Unix: $HOME/.aws/config 24 | // - Windows: %USERPROFILE%\.aws\config 25 | func SharedConfigFilename() string { 26 | return shareddefaults.SharedConfigFilename() 27 | } 28 | -------------------------------------------------------------------------------- /aws/endpoints/legacy_regions.go: -------------------------------------------------------------------------------- 1 | package endpoints 2 | 3 | var legacyGlobalRegions = map[string]map[string]struct{}{ 4 | "s3": { 5 | "us-east-1": {}, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /aws/errors.go: -------------------------------------------------------------------------------- 1 | package aws 2 | 3 | import "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 4 | 5 | var ( 6 | // ErrMissingRegion is an error that is returned if region configuration is 7 | // not found. 8 | ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil) 9 | 10 | // ErrMissingEndpoint is an error that is returned if an endpoint cannot be 11 | // resolved for a service. 12 | ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) 13 | ) 14 | -------------------------------------------------------------------------------- /aws/jsonvalue.go: -------------------------------------------------------------------------------- 1 | package aws 2 | 3 | // JSONValue is a representation of a grab bag type that will be marshaled 4 | // into a json string. This type can be used just like any other map. 5 | // 6 | // Example: 7 | // 8 | // values := aws.JSONValue{ 9 | // "Foo": "Bar", 10 | // } 11 | // values["Baz"] = "Qux" 12 | type JSONValue map[string]interface{} 13 | -------------------------------------------------------------------------------- /aws/request/connection_reset_error.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | func isErrConnectionReset(err error) bool { 8 | if strings.Contains(err.Error(), "read: connection reset") { 9 | return false 10 | } 11 | 12 | if strings.Contains(err.Error(), "use of closed network connection") || 13 | strings.Contains(err.Error(), "connection reset") || 14 | strings.Contains(err.Error(), "broken pipe") { 15 | return true 16 | } 17 | 18 | return false 19 | } 20 | -------------------------------------------------------------------------------- /aws/request/http_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | "net/url" 7 | ) 8 | 9 | func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { 10 | req := new(http.Request) 11 | *req = *r 12 | req.URL = &url.URL{} 13 | *req.URL = *r.URL 14 | req.Body = body 15 | 16 | req.Header = http.Header{} 17 | for k, v := range r.Header { 18 | for _, vv := range v { 19 | req.Header.Add(k, vv) 20 | } 21 | } 22 | 23 | return req 24 | } 25 | -------------------------------------------------------------------------------- /aws/request/http_request_copy_test.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "bytes" 5 | "io/ioutil" 6 | "net/http" 7 | "net/url" 8 | "sync" 9 | "testing" 10 | ) 11 | 12 | func TestRequestCopyRace(t *testing.T) { 13 | origReq := &http.Request{URL: &url.URL{}, Header: http.Header{}} 14 | origReq.Header.Set("Header", "OrigValue") 15 | 16 | var wg sync.WaitGroup 17 | for i := 0; i < 100; i++ { 18 | wg.Add(1) 19 | go func() { 20 | req := copyHTTPRequest(origReq, ioutil.NopCloser(&bytes.Buffer{})) 21 | req.Header.Set("Header", "Value") 22 | go func() { 23 | req2 := copyHTTPRequest(req, ioutil.NopCloser(&bytes.Buffer{})) 24 | req2.Header.Add("Header", "Value2") 25 | }() 26 | _ = req.Header.Get("Header") 27 | wg.Done() 28 | }() 29 | _ = origReq.Header.Get("Header") 30 | } 31 | origReq.Header.Get("Header") 32 | 33 | wg.Wait() 34 | } 35 | -------------------------------------------------------------------------------- /aws/request/http_request_retry_test.go: -------------------------------------------------------------------------------- 1 | package request_test 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/IBM/ibm-cos-sdk-go/aws" 8 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 9 | "github.com/IBM/ibm-cos-sdk-go/awstesting/mock" 10 | ) 11 | 12 | func TestRequestCancelRetry(t *testing.T) { 13 | c := make(chan struct{}) 14 | reqNum := 0 15 | s := mock.NewMockClient(&aws.Config{ 16 | MaxRetries: aws.Int(1), 17 | }) 18 | s.Handlers.Validate.Clear() 19 | s.Handlers.Unmarshal.Clear() 20 | s.Handlers.UnmarshalMeta.Clear() 21 | s.Handlers.UnmarshalError.Clear() 22 | s.Handlers.Send.PushFront(func(r *request.Request) { 23 | reqNum++ 24 | }) 25 | out := &testData{} 26 | r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) 27 | r.HTTPRequest.Cancel = c 28 | close(c) 29 | 30 | err := r.Send() 31 | if !strings.Contains(err.Error(), "canceled") { 32 | t.Errorf("expect canceled in error, %v", err) 33 | } 34 | if e, a := 1, reqNum; e != a { 35 | t.Errorf("expect %v, got %v", e, a) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /aws/request/request_1_6_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.6 2 | // +build go1.6 3 | 4 | package request_test 5 | 6 | import ( 7 | "errors" 8 | "testing" 9 | 10 | "github.com/IBM/ibm-cos-sdk-go/aws" 11 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 12 | "github.com/IBM/ibm-cos-sdk-go/aws/client" 13 | "github.com/IBM/ibm-cos-sdk-go/aws/client/metadata" 14 | "github.com/IBM/ibm-cos-sdk-go/aws/defaults" 15 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 16 | ) 17 | 18 | // go version 1.4 and 1.5 do not return an error. Version 1.5 will url encode 19 | // the uri while 1.4 will not 20 | func TestRequestInvalidEndpoint(t *testing.T) { 21 | endpoint := "http://localhost:90 " 22 | 23 | r := request.New( 24 | aws.Config{}, 25 | metadata.ClientInfo{Endpoint: endpoint}, 26 | defaults.Handlers(), 27 | client.DefaultRetryer{}, 28 | &request.Operation{}, 29 | nil, 30 | nil, 31 | ) 32 | 33 | if r.Error == nil { 34 | t.Errorf("expect error") 35 | } 36 | } 37 | 38 | type timeoutErr struct { 39 | error 40 | } 41 | 42 | var errTimeout = awserr.New("foo", "bar", &timeoutErr{ 43 | errors.New("net/http: request canceled"), 44 | }) 45 | 46 | func (e *timeoutErr) Timeout() bool { 47 | return true 48 | } 49 | 50 | func (e *timeoutErr) Temporary() bool { 51 | return true 52 | } 53 | -------------------------------------------------------------------------------- /aws/request/request_1_8.go: -------------------------------------------------------------------------------- 1 | //go:build go1.8 2 | // +build go1.8 3 | 4 | package request 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 10 | ) 11 | 12 | // NoBody is a http.NoBody reader instructing Go HTTP client to not include 13 | // and body in the HTTP request. 14 | var NoBody = http.NoBody 15 | 16 | // ResetBody rewinds the request body back to its starting position, and 17 | // sets the HTTP Request body reference. When the body is read prior 18 | // to being sent in the HTTP request it will need to be rewound. 19 | // 20 | // ResetBody will automatically be called by the SDK's build handler, but if 21 | // the request is being used directly ResetBody must be called before the request 22 | // is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically 23 | // call ResetBody. 24 | // 25 | // Will also set the Go 1.8's http.Request.GetBody member to allow retrying 26 | // PUT/POST redirects. 27 | func (r *Request) ResetBody() { 28 | body, err := r.getNextRequestBody() 29 | if err != nil { 30 | r.Error = awserr.New(ErrCodeSerialization, 31 | "failed to reset request body", err) 32 | return 33 | } 34 | 35 | r.HTTPRequest.Body = body 36 | r.HTTPRequest.GetBody = r.getNextRequestBody 37 | } 38 | -------------------------------------------------------------------------------- /aws/request/request_context.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package request 5 | 6 | import "github.com/IBM/ibm-cos-sdk-go/aws" 7 | 8 | // setContext updates the Request to use the passed in context for cancellation. 9 | // Context will also be used for request retry delay. 10 | // 11 | // Creates shallow copy of the http.Request with the WithContext method. 12 | func setRequestContext(r *Request, ctx aws.Context) { 13 | r.context = ctx 14 | r.HTTPRequest = r.HTTPRequest.WithContext(ctx) 15 | } 16 | -------------------------------------------------------------------------------- /aws/request/request_context_test.go: -------------------------------------------------------------------------------- 1 | package request_test 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/aws/corehandlers" 9 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 10 | "github.com/IBM/ibm-cos-sdk-go/awstesting" 11 | ) 12 | 13 | func TestRequest_SetContext(t *testing.T) { 14 | svc := awstesting.NewClient() 15 | svc.Handlers.Clear() 16 | svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler) 17 | 18 | r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) 19 | ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} 20 | r.SetContext(ctx) 21 | 22 | ctx.Error = fmt.Errorf("context canceled") 23 | close(ctx.DoneCh) 24 | 25 | err := r.Send() 26 | if err == nil { 27 | t.Fatalf("expected error, got none") 28 | } 29 | 30 | // Only check against canceled because go 1.6 will not use the context's 31 | // Err(). 32 | if e, a := "canceled", err.Error(); !strings.Contains(a, e) { 33 | t.Errorf("expect %q to be in %q, but was not", e, a) 34 | } 35 | } 36 | 37 | func TestRequest_SetContextPanic(t *testing.T) { 38 | defer func() { 39 | if r := recover(); r == nil { 40 | t.Fatalf("expect SetContext to panic, did not") 41 | } 42 | }() 43 | r := &request.Request{} 44 | 45 | r.SetContext(nil) 46 | } 47 | -------------------------------------------------------------------------------- /aws/request/request_internal_test.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCopy(t *testing.T) { 8 | handlers := Handlers{} 9 | op := &Operation{} 10 | op.HTTPMethod = "Foo" 11 | req := &Request{} 12 | req.Operation = op 13 | req.Handlers = handlers 14 | 15 | r := req.copy() 16 | 17 | if r == req { 18 | t.Fatal("expect request pointer copy to be different") 19 | } 20 | if r.Operation == req.Operation { 21 | t.Errorf("expect request operation pointer to be different") 22 | } 23 | 24 | if e, a := req.Operation.HTTPMethod, r.Operation.HTTPMethod; e != a { 25 | t.Errorf("expect %q http method, got %q", e, a) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /aws/session/custom_transport.go: -------------------------------------------------------------------------------- 1 | //go:build go1.13 2 | // +build go1.13 3 | 4 | package session 5 | 6 | import ( 7 | "net" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | // Transport that should be used when a custom CA bundle is specified with the 13 | // SDK. 14 | func getCustomTransport() *http.Transport { 15 | return &http.Transport{ 16 | Proxy: http.ProxyFromEnvironment, 17 | DialContext: (&net.Dialer{ 18 | Timeout: 30 * time.Second, 19 | KeepAlive: 30 * time.Second, 20 | DualStack: true, 21 | }).DialContext, 22 | ForceAttemptHTTP2: true, 23 | MaxIdleConns: 100, 24 | IdleConnTimeout: 90 * time.Second, 25 | TLSHandshakeTimeout: 10 * time.Second, 26 | ExpectContinueTimeout: 1 * time.Second, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /aws/session/custom_transport_go1.12.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.13 && go1.7 2 | // +build !go1.13,go1.7 3 | 4 | package session 5 | 6 | import ( 7 | "net" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | // Transport that should be used when a custom CA bundle is specified with the 13 | // SDK. 14 | func getCustomTransport() *http.Transport { 15 | return &http.Transport{ 16 | Proxy: http.ProxyFromEnvironment, 17 | DialContext: (&net.Dialer{ 18 | Timeout: 30 * time.Second, 19 | KeepAlive: 30 * time.Second, 20 | DualStack: true, 21 | }).DialContext, 22 | MaxIdleConns: 100, 23 | IdleConnTimeout: 90 * time.Second, 24 | TLSHandshakeTimeout: 10 * time.Second, 25 | ExpectContinueTimeout: 1 * time.Second, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /aws/session/custom_transport_go1.5.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.6 && go1.5 2 | // +build !go1.6,go1.5 3 | 4 | package session 5 | 6 | import ( 7 | "net" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | // Transport that should be used when a custom CA bundle is specified with the 13 | // SDK. 14 | func getCustomTransport() *http.Transport { 15 | return &http.Transport{ 16 | Proxy: http.ProxyFromEnvironment, 17 | Dial: (&net.Dialer{ 18 | Timeout: 30 * time.Second, 19 | KeepAlive: 30 * time.Second, 20 | }).Dial, 21 | TLSHandshakeTimeout: 10 * time.Second, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /aws/session/custom_transport_go1.6.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.7 && go1.6 2 | // +build !go1.7,go1.6 3 | 4 | package session 5 | 6 | import ( 7 | "net" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | // Transport that should be used when a custom CA bundle is specified with the 13 | // SDK. 14 | func getCustomTransport() *http.Transport { 15 | return &http.Transport{ 16 | Proxy: http.ProxyFromEnvironment, 17 | Dial: (&net.Dialer{ 18 | Timeout: 30 * time.Second, 19 | KeepAlive: 30 * time.Second, 20 | }).Dial, 21 | TLSHandshakeTimeout: 10 * time.Second, 22 | ExpectContinueTimeout: 1 * time.Second, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /aws/session/shared_test.go: -------------------------------------------------------------------------------- 1 | package session 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/internal/sdktesting" 7 | ) 8 | 9 | func initSessionTestEnv() (oldEnv func()) { 10 | oldEnv = sdktesting.StashEnv() 11 | os.Setenv("AWS_CONFIG_FILE", "file_not_exists") 12 | os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "file_not_exists") 13 | 14 | return oldEnv 15 | } 16 | -------------------------------------------------------------------------------- /aws/session/testdata/credential_source_config_for_windows: -------------------------------------------------------------------------------- 1 | [cred_proc_no_arn_set] 2 | credential_process = type .\testdata\test_json.json 3 | 4 | [cred_proc_arn_set] 5 | role_arn = assume_role_w_creds_proc_role_arn 6 | credential_process = type .\testdata\test_json.json 7 | 8 | [chained_cred_proc] 9 | role_arn = assume_role_w_creds_proc_source_prof 10 | source_profile = cred_proc_no_arn_set 11 | 12 | [profile sso_mixed_credproc] 13 | sso_account_id = 012345678901 14 | sso_region = us-west-2 15 | sso_role_name = TestRole 16 | sso_start_url = https://127.0.0.1/start 17 | credential_process = type .\testdata\test_json.json 18 | 19 | [profile sso_mixed_webident] 20 | web_identity_token_file = .\testdata\wit.txt 21 | role_arn = sso_mixed_webident_arn 22 | sso_account_id = 012345678901 23 | sso_region = us-west-2 24 | sso_role_name = TestRole 25 | sso_start_url = https://127.0.0.1/start 26 | -------------------------------------------------------------------------------- /aws/session/testdata/shared_config_invalid_ini: -------------------------------------------------------------------------------- 1 | [profile_nam 2 | -------------------------------------------------------------------------------- /aws/session/testdata/shared_config_other: -------------------------------------------------------------------------------- 1 | [default] 2 | region = default_region 3 | 4 | [partial_creds] 5 | aws_access_key_id = AKID 6 | 7 | [profile alt_profile_name] 8 | region = alt_profile_name_region 9 | 10 | [creds_from_credentials] 11 | aws_access_key_id = creds_from_config_akid 12 | aws_secret_access_key = creds_from_config_secret 13 | 14 | [config_file_load_order] 15 | region = shared_config_other_region 16 | aws_access_key_id = shared_config_other_akid 17 | aws_secret_access_key = shared_config_other_secret 18 | -------------------------------------------------------------------------------- /aws/session/testdata/test_json.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "AccessKeyId": "cred_proc_akid", 4 | "SecretAccessKey": "cred_proc_secret" 5 | } 6 | -------------------------------------------------------------------------------- /aws/signer/ibmiam/common.go: -------------------------------------------------------------------------------- 1 | package ibmiam 2 | 3 | // IBM COS SDK Code -- START 4 | const ( 5 | // LOGGER constants 6 | debugLog = "" 7 | signRequestHandlerLog = "ibmiam.SignRequestHandler" 8 | 9 | // Error constants 10 | errorExpectedNotFound = "Error Expected Not Found" 11 | errorNotMatch = "Error not match" 12 | 13 | // Global constant 14 | operation = "Operation" 15 | ) 16 | 17 | // IBM COS SDK Code -- END 18 | -------------------------------------------------------------------------------- /aws/signer/v4/options.go: -------------------------------------------------------------------------------- 1 | package v4 2 | 3 | // WithUnsignedPayload will enable and set the UnsignedPayload field to 4 | // true of the signer. 5 | func WithUnsignedPayload(v4 *Signer) { 6 | v4.UnsignedPayload = true 7 | } 8 | -------------------------------------------------------------------------------- /aws/signer/v4/request_context_go1.7.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package v4 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/aws" 10 | ) 11 | 12 | func requestContext(r *http.Request) aws.Context { 13 | return r.Context() 14 | } 15 | -------------------------------------------------------------------------------- /aws/signer/v4/uri_path.go: -------------------------------------------------------------------------------- 1 | //go:build go1.5 2 | // +build go1.5 3 | 4 | package v4 5 | 6 | import ( 7 | "net/url" 8 | "strings" 9 | ) 10 | 11 | func getURIPath(u *url.URL) string { 12 | var uri string 13 | 14 | if len(u.Opaque) > 0 { 15 | uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") 16 | } else { 17 | uri = u.EscapedPath() 18 | } 19 | 20 | if len(uri) == 0 { 21 | uri = "/" 22 | } 23 | 24 | return uri 25 | } 26 | -------------------------------------------------------------------------------- /aws/url.go: -------------------------------------------------------------------------------- 1 | //go:build go1.8 2 | // +build go1.8 3 | 4 | package aws 5 | 6 | import "net/url" 7 | 8 | // URLHostname will extract the Hostname without port from the URL value. 9 | // 10 | // Wrapper of net/url#URL.Hostname for backwards Go version compatibility. 11 | func URLHostname(url *url.URL) string { 12 | return url.Hostname() 13 | } 14 | -------------------------------------------------------------------------------- /aws/version.go: -------------------------------------------------------------------------------- 1 | // Package aws provides core functionality for making requests to IBM COS services. 2 | package aws 3 | 4 | // IBM COS SDK Code -- START 5 | 6 | // SDKName is the name of this AWS SDK 7 | const SDKName = "ibm-cos-sdk-go" 8 | 9 | // SDKVersion is the version of this SDK 10 | const SDKVersion = "1.12.2" 11 | 12 | // IBM COS SDK Code -- END 13 | -------------------------------------------------------------------------------- /awstesting/README.md: -------------------------------------------------------------------------------- 1 | ## AWS SDK for Go awstesting packages ## 2 | `awstesting` is a collection of packages used internally by the SDK, and is subject to have breaking changes. This package is not `internal` so that if you really need to use its functionality, and understand breaking changes will be made, you are able to. 3 | 4 | These packages will be refactored in the future so that the API generator and model parsers are exposed cleanly on their own. 5 | -------------------------------------------------------------------------------- /awstesting/client.go: -------------------------------------------------------------------------------- 1 | package awstesting 2 | 3 | import ( 4 | "github.com/IBM/ibm-cos-sdk-go/aws" 5 | "github.com/IBM/ibm-cos-sdk-go/aws/client" 6 | "github.com/IBM/ibm-cos-sdk-go/aws/client/metadata" 7 | "github.com/IBM/ibm-cos-sdk-go/aws/defaults" 8 | ) 9 | 10 | // NewClient creates and initializes a generic service client for testing. 11 | func NewClient(cfgs ...*aws.Config) *client.Client { 12 | info := metadata.ClientInfo{ 13 | Endpoint: "http://endpoint", 14 | SigningName: "", 15 | } 16 | def := defaults.Get() 17 | def.Config.MergeIn(cfgs...) 18 | 19 | if v := aws.StringValue(def.Config.Endpoint); len(v) > 0 { 20 | info.Endpoint = v 21 | } 22 | 23 | return client.New(*def.Config, info, def.Handlers) 24 | } 25 | -------------------------------------------------------------------------------- /awstesting/discard.go: -------------------------------------------------------------------------------- 1 | package awstesting 2 | 3 | // DiscardAt is an io.WriteAt that discards 4 | // the requested bytes to be written 5 | type DiscardAt struct{} 6 | 7 | // WriteAt discards the given []byte slice and returns len(p) bytes 8 | // as having been written at the given offset. It will never return an error. 9 | func (d DiscardAt) WriteAt(p []byte, off int64) (n int, err error) { 10 | return len(p), nil 11 | } 12 | -------------------------------------------------------------------------------- /awstesting/endless_reader.go: -------------------------------------------------------------------------------- 1 | package awstesting 2 | 3 | // EndlessReader is an io.Reader that will always return 4 | // that bytes have been read. 5 | type EndlessReader struct{} 6 | 7 | // Read will report that it has read len(p) bytes in p. 8 | // The content in the []byte will be unmodified. 9 | // This will never return an error. 10 | func (e EndlessReader) Read(p []byte) (int, error) { 11 | return len(p), nil 12 | } 13 | -------------------------------------------------------------------------------- /awstesting/integration/performance/s3DownloadManager/client.go: -------------------------------------------------------------------------------- 1 | //go:build go1.13 && integration && perftest 2 | // +build go1.13,integration,perftest 3 | 4 | package main 5 | 6 | import ( 7 | "net" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | func NewClient(cfg ClientConfig) *http.Client { 13 | tr := &http.Transport{ 14 | Proxy: http.ProxyFromEnvironment, 15 | DialContext: (&net.Dialer{ 16 | Timeout: cfg.Timeouts.Connect, 17 | KeepAlive: 30 * time.Second, 18 | DualStack: true, 19 | }).DialContext, 20 | MaxIdleConns: cfg.MaxIdleConns, 21 | MaxIdleConnsPerHost: cfg.MaxIdleConnsPerHost, 22 | IdleConnTimeout: 90 * time.Second, 23 | 24 | DisableKeepAlives: !cfg.KeepAlive, 25 | TLSHandshakeTimeout: cfg.Timeouts.TLSHandshake, 26 | ExpectContinueTimeout: cfg.Timeouts.ExpectContinue, 27 | ResponseHeaderTimeout: cfg.Timeouts.ResponseHeader, 28 | 29 | ReadBufferSize: cfg.ReadBufferSize, 30 | WriteBufferSize: cfg.WriteBufferSize, 31 | } 32 | 33 | return &http.Client{ 34 | Transport: tr, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /awstesting/integration/performance/s3GetObject/client.go: -------------------------------------------------------------------------------- 1 | //go:build integration && perftest 2 | // +build integration,perftest 3 | 4 | package main 5 | 6 | import ( 7 | "net" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | func NewClient(cfg ClientConfig) *http.Client { 13 | tr := &http.Transport{ 14 | Proxy: http.ProxyFromEnvironment, 15 | DialContext: (&net.Dialer{ 16 | Timeout: cfg.Timeouts.Connect, 17 | KeepAlive: 30 * time.Second, 18 | DualStack: true, 19 | }).DialContext, 20 | MaxIdleConns: 100, 21 | IdleConnTimeout: 90 * time.Second, 22 | 23 | DisableKeepAlives: !cfg.KeepAlive, 24 | TLSHandshakeTimeout: cfg.Timeouts.TLSHandshake, 25 | ExpectContinueTimeout: cfg.Timeouts.ExpectContinue, 26 | ResponseHeaderTimeout: cfg.Timeouts.ResponseHeader, 27 | } 28 | 29 | return &http.Client{ 30 | Transport: tr, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /awstesting/integration/performance/s3UploadManager/client.go: -------------------------------------------------------------------------------- 1 | //go:build integration && perftest 2 | // +build integration,perftest 3 | 4 | package main 5 | 6 | import ( 7 | "net" 8 | "net/http" 9 | "time" 10 | ) 11 | 12 | func NewClient(cfg ClientConfig) *http.Client { 13 | tr := &http.Transport{ 14 | Proxy: http.ProxyFromEnvironment, 15 | DialContext: (&net.Dialer{ 16 | Timeout: cfg.Timeouts.Connect, 17 | KeepAlive: 30 * time.Second, 18 | DualStack: true, 19 | }).DialContext, 20 | MaxIdleConns: cfg.MaxIdleConns, 21 | MaxIdleConnsPerHost: cfg.MaxIdleConnsPerHost, 22 | IdleConnTimeout: 90 * time.Second, 23 | 24 | DisableKeepAlives: !cfg.KeepAlive, 25 | TLSHandshakeTimeout: cfg.Timeouts.TLSHandshake, 26 | ExpectContinueTimeout: cfg.Timeouts.ExpectContinue, 27 | ResponseHeaderTimeout: cfg.Timeouts.ResponseHeader, 28 | } 29 | 30 | return &http.Client{ 31 | Transport: tr, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.golang-tip: -------------------------------------------------------------------------------- 1 | # Based on docker-library's golang 1.6 alpine and wheezy docker files. 2 | # https://github.com/docker-library/golang/blob/master/1.6/alpine/Dockerfile 3 | # https://github.com/docker-library/golang/blob/master/1.6/wheezy/Dockerfile 4 | FROM buildpack-deps:buster-scm 5 | 6 | ENV GOLANG_SRC_REPO_URL https://github.com/golang/go 7 | 8 | ENV GOLANG_BOOTSTRAP_URL https://storage.googleapis.com/golang/go1.4.3.linux-amd64.tar.gz 9 | ENV GOLANG_BOOTSTRAP_SHA256 ce3140662f45356eb78bc16a88fc7cfb29fb00e18d7c632608245b789b2086d2 10 | ENV GOLANG_BOOTSTRAP_PATH /usr/local/bootstrap 11 | 12 | # gcc for cgo 13 | RUN apt-get update && apt-get install -y --no-install-recommends \ 14 | g++ \ 15 | gcc \ 16 | libc6-dev \ 17 | make \ 18 | git \ 19 | && rm -rf /var/lib/apt/lists/* 20 | 21 | # Setup the Bootstrap 22 | RUN mkdir -p "$GOLANG_BOOTSTRAP_PATH" \ 23 | && curl -fsSL "$GOLANG_BOOTSTRAP_URL" -o golang.tar.gz \ 24 | && echo "$GOLANG_BOOTSTRAP_SHA256 golang.tar.gz" | sha256sum -c - \ 25 | && tar -C "$GOLANG_BOOTSTRAP_PATH" -xzf golang.tar.gz \ 26 | && rm golang.tar.gz 27 | 28 | # Get and build Go tip 29 | RUN export GOROOT_BOOTSTRAP=$GOLANG_BOOTSTRAP_PATH/go \ 30 | && git clone "$GOLANG_SRC_REPO_URL" /usr/local/go \ 31 | && cd /usr/local/go/src \ 32 | && ./make.bash \ 33 | && rm -rf "$GOLANG_BOOTSTRAP_PATH" /usr/local/go/pkg/bootstrap 34 | 35 | # Build Go workspace and environment 36 | ENV GOPATH /go 37 | ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH 38 | RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" \ 39 | && chmod -R 777 "$GOPATH" 40 | 41 | WORKDIR $GOPATH 42 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.10: -------------------------------------------------------------------------------- 1 | FROM golang:1.10 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 10 | CMD ["make", "get-deps", "get-deps-x-tests", "get-deps-verify", "unit"] 11 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.11: -------------------------------------------------------------------------------- 1 | FROM golang:1.11 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 10 | CMD ["make", "get-deps", "get-deps-x-tests", "get-deps-verify", "unit"] 11 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.12: -------------------------------------------------------------------------------- 1 | FROM golang:1.12 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 10 | CMD ["make", "get-deps", "get-deps-x-tests", "get-deps-verify", "unit"] 11 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.13: -------------------------------------------------------------------------------- 1 | FROM golang:1.13 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.14: -------------------------------------------------------------------------------- 1 | FROM golang:1.14 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.15: -------------------------------------------------------------------------------- 1 | FROM golang:1.15 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.16: -------------------------------------------------------------------------------- 1 | FROM golang:1.16 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.17: -------------------------------------------------------------------------------- 1 | FROM golang:1.17 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.18: -------------------------------------------------------------------------------- 1 | FROM golang:1.18 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.19: -------------------------------------------------------------------------------- 1 | FROM golang:1.19 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.5: -------------------------------------------------------------------------------- 1 | FROM golang:1.5 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | ENV GO15VENDOREXPERIMENT="1" 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps", "unit-old-go-race-cover"] 13 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.5-novendorexp: -------------------------------------------------------------------------------- 1 | FROM golang:1.5 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 6 | CMD ["make", "get-deps-tests", "unit-old-go-race-cover"] 7 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.6: -------------------------------------------------------------------------------- 1 | FROM golang:1.6 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 10 | CMD ["make", "get-deps", "unit-old-go-race-cover"] 11 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.7: -------------------------------------------------------------------------------- 1 | FROM golang:1.7 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 10 | CMD ["make", "get-deps", "unit-old-go-race-cover"] 11 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.8: -------------------------------------------------------------------------------- 1 | FROM golang:1.8 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 10 | CMD ["make", "get-deps", "unit-old-go-race-cover"] 11 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.go1.9: -------------------------------------------------------------------------------- 1 | FROM golang:1.9 2 | 3 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 4 | 5 | RUN apt-get update && apt-get install -y --no-install-recommends \ 6 | vim \ 7 | && rm -rf /var/list/apt/lists/* 8 | 9 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 10 | CMD ["make", "get-deps", "unit-old-go-race-cover"] 11 | -------------------------------------------------------------------------------- /awstesting/sandbox/Dockerfile.test.gotip: -------------------------------------------------------------------------------- 1 | FROM aws-golang:tip 2 | 3 | ENV GOPROXY=direct 4 | 5 | ADD . /go/src/github.com/IBM/ibm-cos-sdk-go 6 | 7 | RUN apt-get update && apt-get install -y --no-install-recommends \ 8 | vim \ 9 | && rm -rf /var/list/apt/lists/* 10 | 11 | WORKDIR /go/src/github.com/IBM/ibm-cos-sdk-go 12 | CMD ["make", "get-deps-verify", "unit"] 13 | -------------------------------------------------------------------------------- /awstesting/unit/unit.go: -------------------------------------------------------------------------------- 1 | // Package unit performs initialization and validation for unit tests 2 | package unit 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/IBM/ibm-cos-sdk-go/aws" 8 | "github.com/IBM/ibm-cos-sdk-go/aws/credentials" 9 | "github.com/IBM/ibm-cos-sdk-go/aws/session" 10 | ) 11 | 12 | // Session is a shared session for unit tests to use. 13 | var Session = session.Must(session.NewSession(&aws.Config{ 14 | Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"), 15 | Region: aws.String("mock-region"), 16 | SleepDelay: func(time.Duration) {}, 17 | })) 18 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/callgraph.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/codewalkdir.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | {{range .}} 9 | 10 | {{$name_html := html .Name}} 11 | 12 | 13 | 14 | 15 | {{end}} 16 |
{{$name_html}} {{html .Title}}
17 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/dirlist.html: -------------------------------------------------------------------------------- 1 | 6 | 7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {{range .}} 20 | 21 | {{$name_html := fileInfoName . | html}} 22 | 23 | 24 | 25 | 26 | 27 | 28 | {{end}} 29 | 30 |
File Bytes Modified
..
{{$name_html}}{{html .Size}}{{fileInfoTime . | html}}
31 |

32 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/error.html: -------------------------------------------------------------------------------- 1 | 6 | 7 |

8 | {{html .}} 9 |

10 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/example.html: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 |

Example{{example_suffix .Name}}

7 | {{with .Doc}}

{{html .}}

{{end}} 8 | {{$output := .Output}} 9 | {{with .Play}} 10 |
11 |
12 |
{{html $output}}
13 |
14 | Run 15 | Format 16 | {{if $.Share}} 17 | 18 | {{end}} 19 |
20 |
21 | {{else}} 22 |

Code:

23 |
{{.Code}}
24 | {{with .Output}} 25 |

Output:

26 |
{{html .}}
27 | {{end}} 28 | {{end}} 29 |
30 |
31 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/implements.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/jquery.treeview.css: -------------------------------------------------------------------------------- 1 | /* https://github.com/jzaefferer/jquery-treeview/blob/master/jquery.treeview.css */ 2 | /* License: MIT. */ 3 | .treeview, .treeview ul { 4 | padding: 0; 5 | margin: 0; 6 | list-style: none; 7 | } 8 | 9 | .treeview ul { 10 | background-color: white; 11 | margin-top: 4px; 12 | } 13 | 14 | .treeview .hitarea { 15 | height: 16px; 16 | width: 16px; 17 | margin-left: -16px; 18 | float: left; 19 | cursor: pointer; 20 | } 21 | /* fix for IE6 */ 22 | * html .hitarea { 23 | display: inline; 24 | float:none; 25 | } 26 | 27 | .treeview li { 28 | margin: 0; 29 | padding: 3px 0pt 3px 16px; 30 | } 31 | 32 | .treeview a.selected { 33 | background-color: #eee; 34 | } 35 | 36 | #treecontrol { margin: 1em 0; display: none; } 37 | 38 | .treeview .hover { color: red; cursor: pointer; } 39 | 40 | .treeview li.collapsable, .treeview li.expandable { background-position: 0 -176px; } 41 | 42 | .treeview .expandable-hitarea { background-position: -80px -3px; } 43 | 44 | .treeview li.last { background-position: 0 -1766px } 45 | .treeview li.lastCollapsable { background-position: 0 -111px } 46 | .treeview li.lastExpandable { background-position: -32px -67px } 47 | 48 | .treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; } 49 | 50 | .treeview .placeholder { 51 | height: 16px; 52 | width: 16px; 53 | display: block; 54 | } 55 | 56 | .filetree li { padding: 3px 0 2px 16px; } 57 | .filetree span.folder, .filetree span.file { padding: 1px 0 1px 16px; display: block; } 58 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/methodset.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/opensearch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | godoc 4 | The Go Programming Language 5 | go golang 6 | 7 | 8 | /favicon.ico 9 | UTF-8 10 | UTF-8 11 | 12 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/pkglist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 |
9 | 11 | 14 |
15 |
    16 | {{range .List}} 17 |
  • 18 | {{html .Name}} 19 |
  • 20 | {{end}} 21 |
22 |
23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/search.html: -------------------------------------------------------------------------------- 1 | 6 | {{with .Alert}} 7 |

8 | {{html .}} 9 |

10 | {{end}} 11 | {{with .Alt}} 12 |

13 | Did you mean: 14 | {{range .Alts}} 15 | {{html .}} 16 | {{end}} 17 |

18 | {{end}} 19 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/searchdoc.html: -------------------------------------------------------------------------------- 1 | 6 | {{range $key, $val := .Idents}} 7 | {{if $val}} 8 |

{{$key.Name}}

9 | {{range $val}} 10 | {{$pkg_html := pkgLink .Path | html}} 11 | {{if eq "Packages" $key.Name}} 12 | {{html .Path}} 13 | {{else}} 14 | {{$doc_html := docLink .Path .Name| html}} 15 | {{html .Package}}.{{.Name}} 16 | {{end}} 17 | {{if .Doc}} 18 |

{{comment_html .Doc}}

19 | {{else}} 20 |

No documentation available

21 | {{end}} 22 | {{end}} 23 | {{end}} 24 | {{end}} 25 | -------------------------------------------------------------------------------- /doc-src/aws-godoc/templates/searchtxt.html: -------------------------------------------------------------------------------- 1 | 6 | {{$query_url := urlquery .Query}} 7 | {{with .Textual}} 8 | {{if $.Complete}} 9 |

{{html $.Found}} textual occurrences

10 | {{else}} 11 |

More than {{html $.Found}} textual occurrences

12 |

13 | Not all files or lines containing "{{html $.Query}}" are shown. 14 |

15 | {{end}} 16 |

17 | 18 | {{range .}} 19 | {{$file := .Filename}} 20 | 21 | 24 | 25 | 26 | 27 | 35 | 36 | {{end}} 37 | {{if not $.Complete}} 38 | 39 | {{end}} 40 |
22 | {{$file}}: 23 | {{len .Lines}} 28 | {{range .Lines}} 29 | {{html .}} 30 | {{end}} 31 | {{if not $.Complete}} 32 | ... 33 | {{end}} 34 |
...
41 |

42 | {{end}} 43 | -------------------------------------------------------------------------------- /doc-src/plugin/templates/default/layout/html/footer.erb: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 11 | 13 | 22 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc-src/plugin/templates/default/module/html/client.erb: -------------------------------------------------------------------------------- 1 |

Client Structure collapse

2 |
    3 | <%= yieldall :item => @client %> 4 |
5 | -------------------------------------------------------------------------------- /doc-src/plugin/templates/default/module/html/setup.rb: -------------------------------------------------------------------------------- 1 | def init 2 | super 3 | sections.place(:client, [:item_summary]).before(:constant_summary) 4 | end 5 | 6 | def client 7 | @client = object.children.find {|c| c.has_tag?(:service) } 8 | erb(:client) if @client 9 | end 10 | -------------------------------------------------------------------------------- /doc-src/plugin/templates/default/package/html/setup.rb: -------------------------------------------------------------------------------- 1 | def type_summary 2 | @items = object.children. 3 | select {|c| c.type == :bare_struct || c.type == :struct || c.type == :enum }. 4 | reject {|c| c.has_tag?(:service) }. 5 | sort_by {|c| c.name.to_s } 6 | @name = "Type" 7 | erb :list_summary 8 | end 9 | -------------------------------------------------------------------------------- /doc-src/plugin/templates/default/struct/html/paginators.erb: -------------------------------------------------------------------------------- 1 |
2 |

Pagination Methods

3 |

<%= @items.map {|pkg| link_object(pkg, pkg.name) }.join(" ") %>

4 |
5 | -------------------------------------------------------------------------------- /doc-src/plugin/templates/default/struct/html/request_methods.erb: -------------------------------------------------------------------------------- 1 |
2 |

Request Methods

3 |

<%= @items.map {|pkg| link_object(pkg, pkg.name) }.join(" ") %>

4 |
5 | -------------------------------------------------------------------------------- /doc-src/plugin/templates/default/struct/html/setup.rb: -------------------------------------------------------------------------------- 1 | def init 2 | super 3 | sections.place(:request_methods, :paginators).after(:method_summary) 4 | end 5 | 6 | def groups(list, type = "Method") 7 | super(list.reject {|o| o.has_tag?(:paginator) || o.has_tag?(:request_method) }, type) 8 | end 9 | 10 | def paginators 11 | @items = object.children.select {|o| o.has_tag?(:paginator) } 12 | return if @items.size == 0 13 | erb(:paginators) 14 | end 15 | 16 | def request_methods 17 | @items = object.children.select {|o| o.has_tag?(:request_method) } 18 | return if @items.size == 0 19 | erb(:request_methods) 20 | end 21 | -------------------------------------------------------------------------------- /example/aws/credentials/plugincreds/README.md: -------------------------------------------------------------------------------- 1 | Retrieve Credentials with Go Plugin 2 | === 3 | 4 | This example demonstrates how you can take advantage of Go 1.8's new Plugin 5 | functionality to retrieve AWS credentials dynamically from a plugin compiled 6 | separate from your application. 7 | 8 | Usage 9 | --- 10 | 11 | Example Plugin 12 | --- 13 | 14 | You can find the plugin at `plugin/plugin.go` nested within this example. The plugin 15 | demonstrates what symbol the SDK will use when lookup up the credential provider 16 | and the type signature that needs to be implemented. 17 | 18 | Compile the plugin with: 19 | 20 | go build -tags example -o myPlugin.so -buildmode=plugin plugin/plugin.go 21 | 22 | JSON Credentials File 23 | --- 24 | 25 | This example plugin will read the credentials from a JSON file pointed to by 26 | the `PLUGIN_CREDS_FILE` environment variable. The contents of the file are 27 | the credentials, Key, Secret, and Token. The `Token` filed does not need to be 28 | set if your credentials do not have one. 29 | 30 | ```json 31 | { 32 | "Key": "MyAWSCredAccessKeyID", 33 | "Secret": "MyAWSCredSecretKey", 34 | "Token": "MyAWSCredToken" 35 | } 36 | ``` 37 | 38 | Example Application 39 | --- 40 | 41 | The `main.go` file in this folder demonstrates how you can configure the SDK to 42 | use a plugin to retrieve credentials with. 43 | 44 | Compile and run application: 45 | 46 | go build -tags example -o myApp main.go 47 | 48 | PLUGIN_CREDS_FILE=pathToCreds.json ./myApp myPlugin.so myBucket myObjectKey 49 | 50 | -------------------------------------------------------------------------------- /example/aws/request/httptrace/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | // NewClient creates a new HTTP Client using the ClientConfig values. 10 | func NewClient(cfg ClientConfig) *http.Client { 11 | tr := &http.Transport{ 12 | Proxy: http.ProxyFromEnvironment, 13 | DialContext: (&net.Dialer{ 14 | Timeout: cfg.Timeouts.Connect, 15 | KeepAlive: 30 * time.Second, 16 | DualStack: true, 17 | }).DialContext, 18 | MaxIdleConns: 100, 19 | IdleConnTimeout: cfg.Timeouts.IdleConnection, 20 | 21 | DisableKeepAlives: !cfg.KeepAlive, 22 | TLSHandshakeTimeout: cfg.Timeouts.TLSHandshake, 23 | ExpectContinueTimeout: cfg.Timeouts.ExpectContinue, 24 | ResponseHeaderTimeout: cfg.Timeouts.ResponseHeader, 25 | } 26 | 27 | return &http.Client{ 28 | Transport: tr, 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/service/s3/concatObjects/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | This is an example using the AWS SDK for Go to concatenate two objects together. 4 | We use `UploadPartCopy` which uses an object for a part. Here in this example we have two parts, or in other words 5 | two objects that we want to concatenate together. 6 | 7 | 8 | # Usage 9 | 10 | The example uses the bucket name provided, two keys for each object, and lastly the output key. 11 | 12 | ```sh 13 | AWS_REGION= go run -tags example concatObjects.go 14 | ``` 15 | -------------------------------------------------------------------------------- /example/service/s3/getObjectWithProgress/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | This is an example using the AWS SDK for Go to download an S3 object with a 4 | progress bar. 5 | 6 | # Usage 7 | 8 | The example uses the bucket name provided, one key for object, and output the 9 | progress to stdout. 10 | 11 | ```prompt 12 | AWS_PROFILE=my-profile AWS_REGION=us-west-2 go run -tags example getObjectWithProgress.go cool-bucket my/object/prefix/cool_thing.zip 13 | 14 | 2019/02/22 13:04:52 File size is: 35.9 MB 15 | 2019/02/22 13:04:53 File size:35943530 downloaded:8580 percentage:0% 16 | 2019/02/22 13:04:53 File size:35943530 downloaded:17580 percentage:0% 17 | 2019/02/22 13:04:53 File size:35943530 downloaded:33940 percentage:0% 18 | 2019/02/22 13:04:53 File size:35943530 downloaded:34988 percentage:0% 19 | 2019/02/22 13:04:53 File size:35943530 downloaded:51348 percentage:0% 20 | 2019/02/22 13:04:53 File size:35943530 downloaded:52396 percentage:0% 21 | ... 22 | ``` 23 | -------------------------------------------------------------------------------- /example/service/s3/listObjects/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | This is an example using the AWS SDK for Go to list objects' key in a S3 bucket. 4 | 5 | 6 | # Usage 7 | 8 | The example uses the bucket name provided, and lists all object keys in a bucket. 9 | 10 | ```sh 11 | go run -tags example listObjects.go 12 | ``` 13 | 14 | Output: 15 | ``` 16 | Page, 0 17 | Object: myKey 18 | Object: mykey.txt 19 | Object: resources/0001/item-01 20 | Object: resources/0001/item-02 21 | Object: resources/0001/item-03 22 | Object: resources/0002/item-01 23 | Object: resources/0002/item-02 24 | Object: resources/0002/item-03 25 | Object: resources/0002/item-04 26 | Object: resources/0002/item-05 27 | ``` 28 | -------------------------------------------------------------------------------- /example/service/s3/listObjects/listObjects.go: -------------------------------------------------------------------------------- 1 | //go:build example 2 | // +build example 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | 10 | "github.com/IBM/ibm-cos-sdk-go/aws/session" 11 | "github.com/IBM/ibm-cos-sdk-go/service/s3" 12 | ) 13 | 14 | // Lists all objects in a bucket using pagination 15 | // 16 | // Usage: 17 | // listObjects 18 | func main() { 19 | if len(os.Args) < 2 { 20 | fmt.Println("you must specify a bucket") 21 | return 22 | } 23 | 24 | sess := session.Must(session.NewSession()) 25 | 26 | svc := s3.New(sess) 27 | 28 | i := 0 29 | err := svc.ListObjectsPages(&s3.ListObjectsInput{ 30 | Bucket: &os.Args[1], 31 | }, func(p *s3.ListObjectsOutput, last bool) (shouldContinue bool) { 32 | fmt.Println("Page,", i) 33 | i++ 34 | 35 | for _, obj := range p.Contents { 36 | fmt.Println("Object:", *obj.Key) 37 | } 38 | return true 39 | }) 40 | if err != nil { 41 | fmt.Println("failed to list objects", err) 42 | return 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /example/service/s3/listObjectsConcurrently/README.md: -------------------------------------------------------------------------------- 1 | ## Example 2 | 3 | This is an example using the AWS SDK for Go concurrently to list the encrypted objects in the S3 buckets owned by an account. 4 | 5 | ## Usage 6 | 7 | The example's `accounts` string slice contains a list of the SharedCredentials profiles which will be used to look up the buckets owned by each profile. Each bucket's objects will be queried. 8 | 9 | ``` 10 | AWS_REGION=us-east-1 go run -tags example listObjectsConcurrently.go 11 | ``` 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/service/s3/loggingUploadObjectReadBehavior/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | This example shows how you could wrap the reader of an file being 4 | uploaded to Amazon S3 with a logger that will log the usage of the 5 | reader, and print call stacks when the reader's Read, Seek, or ReadAt 6 | methods encounter an error. 7 | 8 | # Usage 9 | 10 | This bucket uses the bucket name, key, and local file name passed to upload the local file to S3 as the key into the bucket. 11 | 12 | ```sh 13 | AWS_REGION=us-west-2 AWS_PROFILE=default go run . "mybucket" "10MB.file" ./10MB.file 14 | ``` 15 | -------------------------------------------------------------------------------- /example/service/s3/putObjectAcl/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | putObjectAcl is an example using the AWS SDK for Go to put an ACL on an S3 object. 4 | 5 | # Usage 6 | 7 | ```sh 8 | putBucketAcl 9 | -region // required 10 | -bucket // required 11 | -key // required 12 | -owner-name 13 | -owner-id 14 | -grantee-type // required 15 | -uri 16 | -email 17 | -user-id 18 | -display-name 19 | ``` 20 | 21 | ```sh 22 | go run -tags example putObjectAcl.go 23 | -bucket 24 | -key 25 | -owner-name 26 | -owner-id 27 | -grantee-type 28 | -user-id 29 | ``` 30 | 31 | Depending on the type is used depends on which of the three, `uri`, `email`, or `user-id`, needs to be used. 32 | * `s3.TypeCanonicalUser`: `user-id` or `display-name` must be used 33 | * `s3.TypeAmazonCustomerByEmail`: `email` must be used 34 | * `s3.TypeGroup`: `uri` must be used 35 | 36 | Output: 37 | ``` 38 | success { 39 | } nil 40 | ``` 41 | -------------------------------------------------------------------------------- /example/service/s3/putObjectWithProcess/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | This is an example using the AWS SDK for Go to upload object with progress. 4 | We use CustomReader to implement it 5 | 6 | 7 | # Usage 8 | 9 | The example uses the bucket name provided, one key for object, and output the progress to stdout. 10 | The Object size should larger than 5M or your will not see the progress 11 | 12 | ```sh 13 | AWS_REGION= go run -tags example putObjWithProcess.go 14 | ``` 15 | -------------------------------------------------------------------------------- /example/service/s3/sync/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | sync will upload a given directory to Amazon S3 using the upload iterator interface defined in the 4 | s3manager package. This example uses a path that is specified during runtime to walk and build keys 5 | to upload to Amazon S3. It will use the keys to upload the files/folders to Amazon S3. 6 | 7 | # Usage 8 | 9 | ```sh 10 | sync 11 | -region // required 12 | -bucket // required 13 | -path // required 14 | ``` 15 | 16 | ```sh 17 | go run -tags example sync.go 18 | -region // required 19 | -bucket // required 20 | -path // required 21 | ``` 22 | 23 | Output: 24 | ``` 25 | success 26 | ``` 27 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/IBM/ibm-cos-sdk-go 2 | 3 | require ( 4 | github.com/IBM/go-sdk-core/v5 v5.19.0 5 | github.com/jmespath/go-jmespath v0.4.0 6 | github.com/stretchr/testify v1.10.0 7 | golang.org/x/net v0.37.0 8 | ) 9 | 10 | require ( 11 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect 12 | github.com/davecgh/go-spew v1.1.1 // indirect 13 | github.com/gabriel-vasile/mimetype v1.4.8 // indirect 14 | github.com/go-openapi/errors v0.22.0 // indirect 15 | github.com/go-openapi/strfmt v0.23.0 // indirect 16 | github.com/go-playground/locales v0.14.1 // indirect 17 | github.com/go-playground/universal-translator v0.18.1 // indirect 18 | github.com/go-playground/validator/v10 v10.24.0 // indirect 19 | github.com/google/uuid v1.6.0 // indirect 20 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 21 | github.com/hashicorp/go-retryablehttp v0.7.7 // indirect 22 | github.com/leodido/go-urn v1.4.0 // indirect 23 | github.com/mitchellh/mapstructure v1.5.0 // indirect 24 | github.com/oklog/ulid v1.3.1 // indirect 25 | github.com/pmezard/go-difflib v1.0.0 // indirect 26 | go.mongodb.org/mongo-driver v1.17.2 // indirect 27 | golang.org/x/crypto v0.36.0 // indirect 28 | golang.org/x/sys v0.31.0 // indirect 29 | golang.org/x/text v0.23.0 // indirect 30 | gopkg.in/yaml.v2 v2.4.0 // indirect 31 | gopkg.in/yaml.v3 v3.0.1 // indirect 32 | ) 33 | 34 | go 1.23.0 35 | 36 | toolchain go1.23.7 37 | -------------------------------------------------------------------------------- /internal/ini/bench_test.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | const ( 8 | section = `[default] 9 | region = us-west-2 10 | credential_source = Ec2InstanceMetadata 11 | s3 = 12 | foo=bar 13 | bar=baz 14 | output = json 15 | 16 | [assumerole] 17 | output = json 18 | region = us-west-2 19 | ` 20 | ) 21 | 22 | func BenchmarkINIParser(b *testing.B) { 23 | for i := 0; i < b.N; i++ { 24 | ParseBytes([]byte(section)) 25 | } 26 | } 27 | 28 | func BenchmarkTokenize(b *testing.B) { 29 | lexer := iniLexer{} 30 | for i := 0; i < b.N; i++ { 31 | lexer.tokenize([]byte(section)) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /internal/ini/comma_token.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | var commaRunes = []rune(",") 4 | 5 | func isComma(b rune) bool { 6 | return b == ',' 7 | } 8 | 9 | func newCommaToken() Token { 10 | return newToken(TokenComma, commaRunes, NoneType) 11 | } 12 | -------------------------------------------------------------------------------- /internal/ini/comment_token.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | // isComment will return whether or not the next byte(s) is a 4 | // comment. 5 | func isComment(b []rune) bool { 6 | if len(b) == 0 { 7 | return false 8 | } 9 | 10 | switch b[0] { 11 | case ';': 12 | return true 13 | case '#': 14 | return true 15 | } 16 | 17 | return false 18 | } 19 | 20 | // newCommentToken will create a comment token and 21 | // return how many bytes were read. 22 | func newCommentToken(b []rune) (Token, int, error) { 23 | i := 0 24 | for ; i < len(b); i++ { 25 | if b[i] == '\n' { 26 | break 27 | } 28 | 29 | if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' { 30 | break 31 | } 32 | } 33 | 34 | return newToken(TokenComment, b[:i], NoneType), i, nil 35 | } 36 | -------------------------------------------------------------------------------- /internal/ini/doc.go: -------------------------------------------------------------------------------- 1 | // Package ini is an LL(1) parser for configuration files. 2 | // 3 | // Example: 4 | // sections, err := ini.OpenFile("/path/to/file") 5 | // if err != nil { 6 | // panic(err) 7 | // } 8 | // 9 | // profile := "foo" 10 | // section, ok := sections.GetSection(profile) 11 | // if !ok { 12 | // fmt.Printf("section %q could not be found", profile) 13 | // } 14 | // 15 | // Below is the BNF that describes this parser 16 | // 17 | // Grammar: 18 | // stmt -> section | stmt' 19 | // stmt' -> epsilon | expr 20 | // expr -> value (stmt)* | equal_expr (stmt)* 21 | // equal_expr -> value ( ':' | '=' ) equal_expr' 22 | // equal_expr' -> number | string | quoted_string 23 | // quoted_string -> " quoted_string' 24 | // quoted_string' -> string quoted_string_end 25 | // quoted_string_end -> " 26 | // 27 | // section -> [ section' 28 | // section' -> section_value section_close 29 | // section_value -> number | string_subset | boolean | quoted_string_subset 30 | // quoted_string_subset -> " quoted_string_subset' 31 | // quoted_string_subset' -> string_subset quoted_string_end 32 | // quoted_string_subset -> " 33 | // section_close -> ] 34 | // 35 | // value -> number | string_subset | boolean 36 | // string -> ? UTF-8 Code-Points except '\n' (U+000A) and '\r\n' (U+000D U+000A) ? 37 | // string_subset -> ? Code-points excepted by grammar except ':' (U+003A), '=' (U+003D), '[' (U+005B), and ']' (U+005D) ? 38 | // 39 | // SkipState will skip (NL WS)+ 40 | // 41 | // comment -> # comment' | ; comment' 42 | // comment' -> epsilon | value 43 | package ini 44 | -------------------------------------------------------------------------------- /internal/ini/empty_token.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | // emptyToken is used to satisfy the Token interface 4 | var emptyToken = newToken(TokenNone, []rune{}, NoneType) 5 | -------------------------------------------------------------------------------- /internal/ini/expression.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | // newExpression will return an expression AST. 4 | // Expr represents an expression 5 | // 6 | // grammar: 7 | // expr -> string | number 8 | func newExpression(tok Token) AST { 9 | return newASTWithRootToken(ASTKindExpr, tok) 10 | } 11 | 12 | func newEqualExpr(left AST, tok Token) AST { 13 | return newASTWithRootToken(ASTKindEqualExpr, tok, left) 14 | } 15 | 16 | // EqualExprKey will return a LHS value in the equal expr 17 | func EqualExprKey(ast AST) string { 18 | children := ast.GetChildren() 19 | if len(children) == 0 || ast.Kind != ASTKindEqualExpr { 20 | return "" 21 | } 22 | 23 | return string(children[0].Root.Raw()) 24 | } 25 | -------------------------------------------------------------------------------- /internal/ini/fuzz.go: -------------------------------------------------------------------------------- 1 | //go:build gofuzz 2 | // +build gofuzz 3 | 4 | package ini 5 | 6 | import ( 7 | "bytes" 8 | ) 9 | 10 | func Fuzz(data []byte) int { 11 | b := bytes.NewReader(data) 12 | 13 | if _, err := Parse(b); err != nil { 14 | return 0 15 | } 16 | 17 | return 1 18 | } 19 | -------------------------------------------------------------------------------- /internal/ini/fuzz_test.go: -------------------------------------------------------------------------------- 1 | //go:build fuzz 2 | // +build fuzz 3 | 4 | // fuzz test data is stored in Amazon S3. 5 | package ini_test 6 | 7 | import ( 8 | "path/filepath" 9 | "testing" 10 | 11 | "github.com/IBM/ibm-cos-sdk-go/internal/ini" 12 | ) 13 | 14 | // TestFuzz is used to test for crashes and not validity of the input 15 | func TestFuzz(t *testing.T) { 16 | paths, err := filepath.Glob("testdata/fuzz/*") 17 | if err != nil { 18 | t.Errorf("expected no error, but received %v", err) 19 | } 20 | 21 | if paths == nil { 22 | t.Errorf("expected fuzz files, but received none") 23 | } 24 | 25 | for _, path := range paths { 26 | t.Run(path, func(t *testing.T) { 27 | ini.OpenFile(path) 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /internal/ini/ini.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import ( 4 | "io" 5 | "os" 6 | 7 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 8 | ) 9 | 10 | // OpenFile takes a path to a given file, and will open and parse 11 | // that file. 12 | func OpenFile(path string) (Sections, error) { 13 | f, err := os.Open(path) 14 | if err != nil { 15 | return Sections{}, awserr.New(ErrCodeUnableToReadFile, "unable to open file", err) 16 | } 17 | defer f.Close() 18 | 19 | return Parse(f) 20 | } 21 | 22 | // Parse will parse the given file using the shared config 23 | // visitor. 24 | func Parse(f io.Reader) (Sections, error) { 25 | tree, err := ParseAST(f) 26 | if err != nil { 27 | return Sections{}, err 28 | } 29 | 30 | v := NewDefaultVisitor() 31 | if err = Walk(tree, v); err != nil { 32 | return Sections{}, err 33 | } 34 | 35 | return v.Sections, nil 36 | } 37 | 38 | // ParseBytes will parse the given bytes and return the parsed sections. 39 | func ParseBytes(b []byte) (Sections, error) { 40 | tree, err := ParseASTBytes(b) 41 | if err != nil { 42 | return Sections{}, err 43 | } 44 | 45 | v := NewDefaultVisitor() 46 | if err = Walk(tree, v); err != nil { 47 | return Sections{}, err 48 | } 49 | 50 | return v.Sections, nil 51 | } 52 | -------------------------------------------------------------------------------- /internal/ini/ini_lexer_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package ini 5 | 6 | import ( 7 | "bytes" 8 | "io" 9 | "reflect" 10 | "testing" 11 | ) 12 | 13 | func TestTokenize(t *testing.T) { 14 | cases := []struct { 15 | r io.Reader 16 | expectedTokens []Token 17 | expectedError bool 18 | }{ 19 | { 20 | r: bytes.NewBuffer([]byte(`x = 123`)), 21 | expectedTokens: []Token{ 22 | newToken(TokenLit, []rune("x"), StringType), 23 | newToken(TokenWS, []rune(" "), NoneType), 24 | newToken(TokenOp, []rune("="), NoneType), 25 | newToken(TokenWS, []rune(" "), NoneType), 26 | newToken(TokenLit, []rune("123"), StringType), 27 | }, 28 | }, 29 | { 30 | r: bytes.NewBuffer([]byte(`[ foo ]`)), 31 | expectedTokens: []Token{ 32 | newToken(TokenSep, []rune("["), NoneType), 33 | newToken(TokenWS, []rune(" "), NoneType), 34 | newToken(TokenLit, []rune("foo"), StringType), 35 | newToken(TokenWS, []rune(" "), NoneType), 36 | newToken(TokenSep, []rune("]"), NoneType), 37 | }, 38 | }, 39 | } 40 | 41 | for _, c := range cases { 42 | lex := iniLexer{} 43 | tokens, err := lex.Tokenize(c.r) 44 | 45 | if e, a := c.expectedError, err != nil; e != a { 46 | t.Errorf("expected %t, but received %t", e, a) 47 | } 48 | 49 | if e, a := c.expectedTokens, tokens; !reflect.DeepEqual(e, a) { 50 | t.Errorf("expected %v, but received %v", e, a) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /internal/ini/newline_token.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | func isNewline(b []rune) bool { 4 | if len(b) == 0 { 5 | return false 6 | } 7 | 8 | if b[0] == '\n' { 9 | return true 10 | } 11 | 12 | if len(b) < 2 { 13 | return false 14 | } 15 | 16 | return b[0] == '\r' && b[1] == '\n' 17 | } 18 | 19 | func newNewlineToken(b []rune) (Token, int, error) { 20 | i := 1 21 | if b[0] == '\r' && isNewline(b[1:]) { 22 | i++ 23 | } 24 | 25 | if !isNewline([]rune(b[:i])) { 26 | return emptyToken, 0, NewParseError("invalid new line token") 27 | } 28 | 29 | return newToken(TokenNL, b[:i], NoneType), i, nil 30 | } 31 | -------------------------------------------------------------------------------- /internal/ini/op_tokens.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var ( 8 | equalOp = []rune("=") 9 | equalColonOp = []rune(":") 10 | ) 11 | 12 | func isOp(b []rune) bool { 13 | if len(b) == 0 { 14 | return false 15 | } 16 | 17 | switch b[0] { 18 | case '=': 19 | return true 20 | case ':': 21 | return true 22 | default: 23 | return false 24 | } 25 | } 26 | 27 | func newOpToken(b []rune) (Token, int, error) { 28 | tok := Token{} 29 | 30 | switch b[0] { 31 | case '=': 32 | tok = newToken(TokenOp, equalOp, NoneType) 33 | case ':': 34 | tok = newToken(TokenOp, equalColonOp, NoneType) 35 | default: 36 | return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0])) 37 | } 38 | return tok, 1, nil 39 | } 40 | -------------------------------------------------------------------------------- /internal/ini/parse_error.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import "fmt" 4 | 5 | const ( 6 | // ErrCodeParseError is returned when a parsing error 7 | // has occurred. 8 | ErrCodeParseError = "INIParseError" 9 | ) 10 | 11 | // ParseError is an error which is returned during any part of 12 | // the parsing process. 13 | type ParseError struct { 14 | msg string 15 | } 16 | 17 | // NewParseError will return a new ParseError where message 18 | // is the description of the error. 19 | func NewParseError(message string) *ParseError { 20 | return &ParseError{ 21 | msg: message, 22 | } 23 | } 24 | 25 | // Code will return the ErrCodeParseError 26 | func (err *ParseError) Code() string { 27 | return ErrCodeParseError 28 | } 29 | 30 | // Message returns the error's message 31 | func (err *ParseError) Message() string { 32 | return err.msg 33 | } 34 | 35 | // OrigError return nothing since there will never be any 36 | // original error. 37 | func (err *ParseError) OrigError() error { 38 | return nil 39 | } 40 | 41 | func (err *ParseError) Error() string { 42 | return fmt.Sprintf("%s: %s", err.Code(), err.Message()) 43 | } 44 | -------------------------------------------------------------------------------- /internal/ini/parse_stack.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | ) 7 | 8 | // ParseStack is a stack that contains a container, the stack portion, 9 | // and the list which is the list of ASTs that have been successfully 10 | // parsed. 11 | type ParseStack struct { 12 | top int 13 | container []AST 14 | list []AST 15 | index int 16 | } 17 | 18 | func newParseStack(sizeContainer, sizeList int) ParseStack { 19 | return ParseStack{ 20 | container: make([]AST, sizeContainer), 21 | list: make([]AST, sizeList), 22 | } 23 | } 24 | 25 | // Pop will return and truncate the last container element. 26 | func (s *ParseStack) Pop() AST { 27 | s.top-- 28 | return s.container[s.top] 29 | } 30 | 31 | // Push will add the new AST to the container 32 | func (s *ParseStack) Push(ast AST) { 33 | s.container[s.top] = ast 34 | s.top++ 35 | } 36 | 37 | // MarkComplete will append the AST to the list of completed statements 38 | func (s *ParseStack) MarkComplete(ast AST) { 39 | s.list[s.index] = ast 40 | s.index++ 41 | } 42 | 43 | // List will return the completed statements 44 | func (s ParseStack) List() []AST { 45 | return s.list[:s.index] 46 | } 47 | 48 | // Len will return the length of the container 49 | func (s *ParseStack) Len() int { 50 | return s.top 51 | } 52 | 53 | func (s ParseStack) String() string { 54 | buf := bytes.Buffer{} 55 | for i, node := range s.list { 56 | buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node)) 57 | } 58 | 59 | return buf.String() 60 | } 61 | -------------------------------------------------------------------------------- /internal/ini/parse_stack_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package ini 5 | 6 | import ( 7 | "reflect" 8 | "testing" 9 | ) 10 | 11 | func newMockAST(v []rune) AST { 12 | return newASTWithRootToken(ASTKindNone, Token{raw: v}) 13 | } 14 | 15 | func TestStack(t *testing.T) { 16 | cases := []struct { 17 | asts []AST 18 | expected []AST 19 | }{ 20 | { 21 | asts: []AST{ 22 | newMockAST([]rune("0")), 23 | newMockAST([]rune("1")), 24 | newMockAST([]rune("2")), 25 | newMockAST([]rune("3")), 26 | newMockAST([]rune("4")), 27 | }, 28 | expected: []AST{ 29 | newMockAST([]rune("0")), 30 | newMockAST([]rune("1")), 31 | newMockAST([]rune("2")), 32 | newMockAST([]rune("3")), 33 | newMockAST([]rune("4")), 34 | }, 35 | }, 36 | } 37 | 38 | for _, c := range cases { 39 | p := newParseStack(10, 10) 40 | for _, ast := range c.asts { 41 | p.Push(ast) 42 | p.MarkComplete(ast) 43 | } 44 | 45 | if e, a := len(c.expected), p.Len(); e != a { 46 | t.Errorf("expected the same legnth with %d, but received %d", e, a) 47 | } 48 | for i := len(c.expected) - 1; i >= 0; i-- { 49 | if e, a := c.expected[i], p.Pop(); !reflect.DeepEqual(e, a) { 50 | t.Errorf("stack element %d invalid: expected %v, but received %v", i, e, a) 51 | } 52 | } 53 | 54 | if e, a := len(c.expected), p.index; e != a { 55 | t.Errorf("expected %d, but received %d", e, a) 56 | } 57 | 58 | if e, a := c.asts, p.list[:p.index]; !reflect.DeepEqual(e, a) { 59 | t.Errorf("expected %v, but received %v", e, a) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /internal/ini/sep_tokens.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var ( 8 | emptyRunes = []rune{} 9 | ) 10 | 11 | func isSep(b []rune) bool { 12 | if len(b) == 0 { 13 | return false 14 | } 15 | 16 | switch b[0] { 17 | case '[', ']': 18 | return true 19 | default: 20 | return false 21 | } 22 | } 23 | 24 | var ( 25 | openBrace = []rune("[") 26 | closeBrace = []rune("]") 27 | ) 28 | 29 | func newSepToken(b []rune) (Token, int, error) { 30 | tok := Token{} 31 | 32 | switch b[0] { 33 | case '[': 34 | tok = newToken(TokenSep, openBrace, NoneType) 35 | case ']': 36 | tok = newToken(TokenSep, closeBrace, NoneType) 37 | default: 38 | return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0])) 39 | } 40 | return tok, 1, nil 41 | } 42 | -------------------------------------------------------------------------------- /internal/ini/skipper.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | // skipper is used to skip certain blocks of an ini file. 4 | // Currently skipper is used to skip nested blocks of ini 5 | // files. See example below 6 | // 7 | // [ foo ] 8 | // nested = ; this section will be skipped 9 | // a=b 10 | // c=d 11 | // bar=baz ; this will be included 12 | type skipper struct { 13 | shouldSkip bool 14 | TokenSet bool 15 | prevTok Token 16 | } 17 | 18 | func newSkipper() skipper { 19 | return skipper{ 20 | prevTok: emptyToken, 21 | } 22 | } 23 | 24 | func (s *skipper) ShouldSkip(tok Token) bool { 25 | // should skip state will be modified only if previous token was new line (NL); 26 | // and the current token is not WhiteSpace (WS). 27 | if s.shouldSkip && 28 | s.prevTok.Type() == TokenNL && 29 | tok.Type() != TokenWS { 30 | s.Continue() 31 | return false 32 | } 33 | s.prevTok = tok 34 | return s.shouldSkip 35 | } 36 | 37 | func (s *skipper) Skip() { 38 | s.shouldSkip = true 39 | } 40 | 41 | func (s *skipper) Continue() { 42 | s.shouldSkip = false 43 | // empty token is assigned as we return to default state, when should skip is false 44 | s.prevTok = emptyToken 45 | } 46 | -------------------------------------------------------------------------------- /internal/ini/statement.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | // Statement is an empty AST mostly used for transitioning states. 4 | func newStatement() AST { 5 | return newAST(ASTKindStatement, AST{}) 6 | } 7 | 8 | // SectionStatement represents a section AST 9 | func newSectionStatement(tok Token) AST { 10 | return newASTWithRootToken(ASTKindSectionStatement, tok) 11 | } 12 | 13 | // ExprStatement represents a completed expression AST 14 | func newExprStatement(ast AST) AST { 15 | return newAST(ASTKindExprStatement, ast) 16 | } 17 | 18 | // CommentStatement represents a comment in the ini definition. 19 | // 20 | // grammar: 21 | // comment -> #comment' | ;comment' 22 | // comment' -> epsilon | value 23 | func newCommentStatement(tok Token) AST { 24 | return newAST(ASTKindCommentStatement, newExpression(tok)) 25 | } 26 | 27 | // CompletedSectionStatement represents a completed section 28 | func newCompletedSectionStatement(ast AST) AST { 29 | return newAST(ASTKindCompletedSectionStatement, ast) 30 | } 31 | 32 | // SkipStatement is used to skip whole statements 33 | func newSkipStatement(ast AST) AST { 34 | return newAST(ASTKindSkipStatement, ast) 35 | } 36 | -------------------------------------------------------------------------------- /internal/ini/testdata/invalid/bad_section_name: -------------------------------------------------------------------------------- 1 | [ :=foo ] 2 | -------------------------------------------------------------------------------- /internal/ini/testdata/invalid/bad_syntax_1: -------------------------------------------------------------------------------- 1 | [[ foo ] 2 | -------------------------------------------------------------------------------- /internal/ini/testdata/invalid/bad_syntax_2: -------------------------------------------------------------------------------- 1 | [ foo ]] 2 | -------------------------------------------------------------------------------- /internal/ini/testdata/invalid/incomplete_section_profile: -------------------------------------------------------------------------------- 1 | [ default 2 | -------------------------------------------------------------------------------- /internal/ini/testdata/invalid/invalid_keys: -------------------------------------------------------------------------------- 1 | [assumerole] 2 | key[id] = value 3 | -------------------------------------------------------------------------------- /internal/ini/testdata/invalid/syntax_error_comment: -------------------------------------------------------------------------------- 1 | [ default #] 2 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/arn_profile: -------------------------------------------------------------------------------- 1 | [arn:aws:sts::1234:assumed-role/My-Role/session-name] 2 | region = "foo-region" 3 | arn = arn:aws:sts::1234:assumed-role/My-Role/session-name 4 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/arn_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "arn:aws:sts::1234:assumed-role/My-Role/session-name": { 3 | "region": "foo-region", 4 | "arn": "arn:aws:sts::1234:assumed-role/My-Role/session-name" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/array_profile: -------------------------------------------------------------------------------- 1 | [ foo ] 2 | bar = "one","two", "three" 3 | baz = 123 4 | qux = 5 | moo = 123,456 6 | cow = 1 7 | milk = 123,456 8 | zed = "zee" 9 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/array_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "foo": { 3 | "baz": "123", 4 | "zed": "zee" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/base_numbers_profile: -------------------------------------------------------------------------------- 1 | [ default ] 2 | binary=0b1001 3 | octal=0o107 4 | ten=12 5 | hex=0xAFB1 6 | hex2=0xafb1 7 | color=970b00 8 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/base_numbers_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "binary": "0b1001", 4 | "octal": "0o107", 5 | "ten": "12", 6 | "hex": "0xAFB1", 7 | "hex2": "0xafb1", 8 | "color": "970b00" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/commented_profile: -------------------------------------------------------------------------------- 1 | # comment here 2 | [ default ] 3 | region = "foo-region" # another comment 4 | output = json # comment again 5 | bar = 123 ; comment with semi-colon 6 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/commented_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "region": "foo-region", 4 | "output": "json", 5 | "bar": "123" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/empty_profile: -------------------------------------------------------------------------------- 1 | [ default ] 2 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/empty_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/escaped_profile: -------------------------------------------------------------------------------- 1 | [ default ] 2 | foo = "\"bar\"" 3 | baz = "qux\n" 4 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/escaped_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "foo": "\"bar\"", 4 | "baz": "qux\n" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/exponent_profile: -------------------------------------------------------------------------------- 1 | [ default ] 2 | exponent = 1e4 3 | exponent_2 = 1E-4 4 | exponent_should_be_string = 0x1ob 5 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/exponent_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "exponent": "1e4", 4 | "exponent_2": "1E-4", 5 | "exponent_should_be_string": "0x1ob" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/global_values_profile: -------------------------------------------------------------------------------- 1 | foo=bar 2 | [default] 3 | foo=bar 4 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/global_values_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "foo": "bar" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/issue_2253: -------------------------------------------------------------------------------- 1 | [default] 2 | large_number = 1234567890123456789012345678901234567890 3 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/issue_2253_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "large_number": "1234567890123456789012345678901234567890" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/issue_2281: -------------------------------------------------------------------------------- 1 | [foo-profile] 2 | aws_access_key_id = accesskey 3 | aws_secret_access_key = secret 4 | aws_session_token = token 5 | aws_security_token = sectoken 6 | x_principal_arn = arn:aws:sts::myarn 7 | x_security_token_expires = time 8 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/issue_2281_expected: -------------------------------------------------------------------------------- 1 | { 2 | "foo-profile": { 3 | "aws_access_key_id": "accesskey", 4 | "aws_secret_access_key": "secret", 5 | "aws_session_token": "token", 6 | "aws_security_token": "sectoken", 7 | "x_principal_arn": "arn:aws:sts::myarn", 8 | "x_security_token_expires": "time" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/issue_2800: -------------------------------------------------------------------------------- 1 | [foo] 2 | aws_access_key_id = 3 | aws_secret_access_key = 4 | aws_session_token = 5 | [bar] 6 | aws_access_key_id = valid 7 | aws_secret_access_key = valid 8 | aws_session_token = valid 9 | [baz] 10 | aws_access_key_id = valid 11 | aws_secret_access_key = valid 12 | aws_session_token = valid 13 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/issue_2800_expected: -------------------------------------------------------------------------------- 1 | { 2 | "foo": { 3 | }, 4 | "bar": { 5 | "aws_access_key_id": "valid", 6 | "aws_secret_access_key": "valid", 7 | "aws_session_token": "valid" 8 | }, 9 | "baz": { 10 | "aws_access_key_id": "valid", 11 | "aws_secret_access_key": "valid", 12 | "aws_session_token": "valid" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/nested_fields: -------------------------------------------------------------------------------- 1 | [foo] 2 | aws_access_key_id = 3 | aws_secret_access_key = valid 4 | aws_session_token = valid 5 | [bar] 6 | aws_access_key_id = valid 7 | aws_secret_access_key = valid 8 | aws_session_token = valid 9 | [baz] 10 | aws_access_key_id = valid 11 | aws_secret_access_key = valid 12 | aws_session_token = valid 13 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/nested_fields_expected: -------------------------------------------------------------------------------- 1 | { 2 | "foo": { 3 | "aws_session_token": "valid" 4 | }, 5 | "bar": { 6 | "aws_access_key_id": "valid", 7 | "aws_secret_access_key": "valid", 8 | "aws_session_token": "valid" 9 | }, 10 | "baz": { 11 | "aws_access_key_id": "valid", 12 | "aws_secret_access_key": "valid", 13 | "aws_session_token": "valid" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/number_lhs_expr: -------------------------------------------------------------------------------- 1 | [default] 2 | 123 = 456.456 3 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/number_lhs_expr_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "123": "456.456" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/op_sep_in_values: -------------------------------------------------------------------------------- 1 | [case1] 2 | sepInValue = =:[foo]]bar[ 3 | key:= value1 4 | 5 | [case2] 6 | sepInValue==:[foo]]bar[ 7 | key = value2 8 | 9 | [case3] 10 | sepInValue = [] 11 | key== value3 12 | 13 | [case4] 14 | sepInValue = [value] x=a 15 | key:=value4 16 | 17 | [case5] 18 | key : value5 19 | 20 | [case6] 21 | s3 = 22 | [nested6] 23 | key = valuen6 24 | key :=value6 25 | 26 | [case7] 27 | s3 = 28 | key :value7 29 | [sub7] 30 | key ==values7 31 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/op_sep_in_values_expected: -------------------------------------------------------------------------------- 1 | { 2 | "case1": { 3 | "sepInValue": "=:[foo]]bar[", 4 | "key": "= value1" 5 | }, 6 | "case2": { 7 | "sepInValue": "=:[foo]]bar[", 8 | "key": "value2" 9 | }, 10 | "case3": { 11 | "sepInValue": "[]", 12 | "key": "= value3" 13 | }, 14 | "case4": { 15 | "sepInValue": "[value] x=a", 16 | "key": "=value4" 17 | }, 18 | "case5": { 19 | "key": "value5" 20 | }, 21 | "case6": { 22 | "s3": "", 23 | "key": "=value6" 24 | }, 25 | "case7": { 26 | "s3": "", 27 | "key": "value7" 28 | }, 29 | "sub7": { 30 | "key": "=values7" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/profile_name: -------------------------------------------------------------------------------- 1 | [ profile foo ] 2 | bar = baz 3 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/profile_name_expected: -------------------------------------------------------------------------------- 1 | { 2 | "profile foo": { 3 | "bar": "baz" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/sections_profile: -------------------------------------------------------------------------------- 1 | [ default ] 2 | region = "foo-region" 3 | output = json 4 | 5 | [ foo ] 6 | bar = baz 7 | [bar] 8 | baz=qux 9 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/sections_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "region": "foo-region", 4 | "output": "json" 5 | }, 6 | "foo": { 7 | "bar": "baz" 8 | }, 9 | "bar": { 10 | "baz": "qux" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/simple_profile: -------------------------------------------------------------------------------- 1 | [ default ] 2 | region = "foo-region" 3 | output = json 4 | foo = bar = baz 5 | bar = baz qux 6 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/simple_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "default": { 3 | "output": "json", 4 | "region": "foo-region", 5 | "foo": "bar = baz", 6 | "bar": "baz qux" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/space_lhs: -------------------------------------------------------------------------------- 1 | [ hyphen-profile-name ] 2 | aws region = "foo-region" 3 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/space_lhs_expected: -------------------------------------------------------------------------------- 1 | { 2 | "hyphen-profile-name": { 3 | "aws region": "foo-region" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/utf_8_profile: -------------------------------------------------------------------------------- 1 | [ ʃʉʍΡιξ ] 2 | ϰϪϧ = Ϯϴϖ 3 | ϝϧ = "ϟΞ΅" 4 | -------------------------------------------------------------------------------- /internal/ini/testdata/valid/utf_8_profile_expected: -------------------------------------------------------------------------------- 1 | { 2 | "ʃʉʍΡιξ": { 3 | "ϰϪϧ": "Ϯϴϖ", 4 | "ϝϧ": "ϟΞ΅" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /internal/ini/trim_spaces_test.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestTrimSpaces(t *testing.T) { 9 | cases := []struct { 10 | name string 11 | node AST 12 | expectedNode AST 13 | }{ 14 | { 15 | name: "simple case", 16 | node: AST{ 17 | Root: Token{ 18 | raw: []rune("foo"), 19 | }, 20 | }, 21 | expectedNode: AST{ 22 | Root: Token{ 23 | raw: []rune("foo"), 24 | }, 25 | }, 26 | }, 27 | { 28 | name: "LHS case", 29 | node: AST{ 30 | Root: Token{ 31 | raw: []rune(" foo"), 32 | }, 33 | }, 34 | expectedNode: AST{ 35 | Root: Token{ 36 | raw: []rune("foo"), 37 | }, 38 | }, 39 | }, 40 | { 41 | name: "RHS case", 42 | node: AST{ 43 | Root: Token{ 44 | raw: []rune("foo "), 45 | }, 46 | }, 47 | expectedNode: AST{ 48 | Root: Token{ 49 | raw: []rune("foo"), 50 | }, 51 | }, 52 | }, 53 | { 54 | name: "both sides case", 55 | node: AST{ 56 | Root: Token{ 57 | raw: []rune(" foo "), 58 | }, 59 | }, 60 | expectedNode: AST{ 61 | Root: Token{ 62 | raw: []rune("foo"), 63 | }, 64 | }, 65 | }, 66 | } 67 | 68 | for _, c := range cases { 69 | node := trimSpaces(c.node) 70 | 71 | if e, a := c.expectedNode, node; !reflect.DeepEqual(e, a) { 72 | t.Errorf("%s: expected %v, but received %v", c.name, e, a) 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /internal/ini/walker.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | // Walk will traverse the AST using the v, the Visitor. 4 | func Walk(tree []AST, v Visitor) error { 5 | for _, node := range tree { 6 | switch node.Kind { 7 | case ASTKindExpr, 8 | ASTKindExprStatement: 9 | 10 | if err := v.VisitExpr(node); err != nil { 11 | return err 12 | } 13 | case ASTKindStatement, 14 | ASTKindCompletedSectionStatement, 15 | ASTKindNestedSectionStatement, 16 | ASTKindCompletedNestedSectionStatement: 17 | 18 | if err := v.VisitStatement(node); err != nil { 19 | return err 20 | } 21 | } 22 | } 23 | 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /internal/ini/ws_token.go: -------------------------------------------------------------------------------- 1 | package ini 2 | 3 | import ( 4 | "unicode" 5 | ) 6 | 7 | // isWhitespace will return whether or not the character is 8 | // a whitespace character. 9 | // 10 | // Whitespace is defined as a space or tab. 11 | func isWhitespace(c rune) bool { 12 | return unicode.IsSpace(c) && c != '\n' && c != '\r' 13 | } 14 | 15 | func newWSToken(b []rune) (Token, int, error) { 16 | i := 0 17 | for ; i < len(b); i++ { 18 | if !isWhitespace(b[i]) { 19 | break 20 | } 21 | } 22 | 23 | return newToken(TokenWS, b[:i], NoneType), i, nil 24 | } 25 | -------------------------------------------------------------------------------- /internal/s3shared/arn/s3_object_lambda_arn.go: -------------------------------------------------------------------------------- 1 | package arn 2 | 3 | // S3ObjectLambdaARN represents an ARN for the s3-object-lambda service 4 | type S3ObjectLambdaARN interface { 5 | Resource 6 | 7 | isS3ObjectLambdasARN() 8 | } 9 | 10 | // S3ObjectLambdaAccessPointARN is an S3ObjectLambdaARN for the Access Point resource type 11 | type S3ObjectLambdaAccessPointARN struct { 12 | AccessPointARN 13 | } 14 | 15 | func (s S3ObjectLambdaAccessPointARN) isS3ObjectLambdasARN() {} 16 | -------------------------------------------------------------------------------- /internal/sdkio/byte.go: -------------------------------------------------------------------------------- 1 | package sdkio 2 | 3 | const ( 4 | // Byte is 8 bits 5 | Byte int64 = 1 6 | // KibiByte (KiB) is 1024 Bytes 7 | KibiByte = Byte * 1024 8 | // MebiByte (MiB) is 1024 KiB 9 | MebiByte = KibiByte * 1024 10 | // GibiByte (GiB) is 1024 MiB 11 | GibiByte = MebiByte * 1024 12 | ) 13 | -------------------------------------------------------------------------------- /internal/sdkio/io_go1.7.go: -------------------------------------------------------------------------------- 1 | //go:build go1.7 2 | // +build go1.7 3 | 4 | package sdkio 5 | 6 | import "io" 7 | 8 | // Alias for Go 1.7 io package Seeker constants 9 | const ( 10 | SeekStart = io.SeekStart // seek relative to the origin of the file 11 | SeekCurrent = io.SeekCurrent // seek relative to the current offset 12 | SeekEnd = io.SeekEnd // seek relative to the end 13 | ) 14 | -------------------------------------------------------------------------------- /internal/sdkmath/floor.go: -------------------------------------------------------------------------------- 1 | //go:build go1.10 2 | // +build go1.10 3 | 4 | package sdkmath 5 | 6 | import "math" 7 | 8 | // Round returns the nearest integer, rounding half away from zero. 9 | // 10 | // Special cases are: 11 | // 12 | // Round(±0) = ±0 13 | // Round(±Inf) = ±Inf 14 | // Round(NaN) = NaN 15 | func Round(x float64) float64 { 16 | return math.Round(x) 17 | } 18 | -------------------------------------------------------------------------------- /internal/sdkrand/locked_source.go: -------------------------------------------------------------------------------- 1 | package sdkrand 2 | 3 | import ( 4 | "math/rand" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | // lockedSource is a thread-safe implementation of rand.Source 10 | type lockedSource struct { 11 | lk sync.Mutex 12 | src rand.Source 13 | } 14 | 15 | func (r *lockedSource) Int63() (n int64) { 16 | r.lk.Lock() 17 | n = r.src.Int63() 18 | r.lk.Unlock() 19 | return 20 | } 21 | 22 | func (r *lockedSource) Seed(seed int64) { 23 | r.lk.Lock() 24 | r.src.Seed(seed) 25 | r.lk.Unlock() 26 | } 27 | 28 | // SeededRand is a new RNG using a thread safe implementation of rand.Source 29 | var SeededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) 30 | -------------------------------------------------------------------------------- /internal/sdkrand/read.go: -------------------------------------------------------------------------------- 1 | //go:build go1.6 2 | // +build go1.6 3 | 4 | package sdkrand 5 | 6 | import "math/rand" 7 | 8 | // Read provides the stub for math.Rand.Read method support for go version's 9 | // 1.6 and greater. 10 | func Read(r *rand.Rand, p []byte) (int, error) { 11 | return r.Read(p) 12 | } 13 | -------------------------------------------------------------------------------- /internal/sdktesting/env.go: -------------------------------------------------------------------------------- 1 | package sdktesting 2 | 3 | import ( 4 | "os" 5 | "runtime" 6 | "strings" 7 | ) 8 | 9 | // StashEnv stashes the current environment variables except variables listed in envToKeepx 10 | // Returns an function to pop out old environment 11 | func StashEnv(envToKeep ...string) func() { 12 | if runtime.GOOS == "windows" { 13 | envToKeep = append(envToKeep, "ComSpec") 14 | envToKeep = append(envToKeep, "SYSTEM32") 15 | envToKeep = append(envToKeep, "SYSTEMROOT") 16 | } 17 | envToKeep = append(envToKeep, "PATH") 18 | extraEnv := getEnvs(envToKeep) 19 | originalEnv := os.Environ() 20 | os.Clearenv() // clear env 21 | for key, val := range extraEnv { 22 | os.Setenv(key, val) 23 | } 24 | return func() { 25 | popEnv(originalEnv) 26 | } 27 | } 28 | 29 | func getEnvs(envs []string) map[string]string { 30 | extraEnvs := make(map[string]string) 31 | for _, env := range envs { 32 | if val, ok := os.LookupEnv(env); ok && len(val) > 0 { 33 | extraEnvs[env] = val 34 | } 35 | } 36 | return extraEnvs 37 | } 38 | 39 | // PopEnv takes the list of the environment values and injects them into the 40 | // process's environment variable data. Clears any existing environment values 41 | // that may already exist. 42 | func popEnv(env []string) { 43 | os.Clearenv() 44 | 45 | for _, e := range env { 46 | p := strings.SplitN(e, "=", 2) 47 | k, v := p[0], "" 48 | if len(p) > 1 { 49 | v = p[1] 50 | } 51 | os.Setenv(k, v) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /internal/sdkuri/path.go: -------------------------------------------------------------------------------- 1 | package sdkuri 2 | 3 | import ( 4 | "path" 5 | "strings" 6 | ) 7 | 8 | // PathJoin will join the elements of the path delimited by the "/" 9 | // character. Similar to path.Join with the exception the trailing "/" 10 | // character is preserved if present. 11 | func PathJoin(elems ...string) string { 12 | if len(elems) == 0 { 13 | return "" 14 | } 15 | 16 | hasTrailing := strings.HasSuffix(elems[len(elems)-1], "/") 17 | str := path.Join(elems...) 18 | if hasTrailing && str != "/" { 19 | str += "/" 20 | } 21 | 22 | return str 23 | } 24 | -------------------------------------------------------------------------------- /internal/sdkuri/path_test.go: -------------------------------------------------------------------------------- 1 | package sdkuri 2 | 3 | import "testing" 4 | 5 | func TestPathJoin(t *testing.T) { 6 | cases := []struct { 7 | Elems []string 8 | Expect string 9 | }{ 10 | {Elems: []string{"/"}, Expect: "/"}, 11 | {Elems: []string{}, Expect: ""}, 12 | {Elems: []string{"blah", "el", "blah/"}, Expect: "blah/el/blah/"}, 13 | {Elems: []string{"/asd", "asdfa", "asdfasd/"}, Expect: "/asd/asdfa/asdfasd/"}, 14 | {Elems: []string{"asdfa", "asdfa", "asdfads"}, Expect: "asdfa/asdfa/asdfads"}, 15 | } 16 | for _, c := range cases { 17 | if e, a := c.Expect, PathJoin(c.Elems...); e != a { 18 | t.Errorf("expect %v, got %v", e, a) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /internal/shareddefaults/ecs_container.go: -------------------------------------------------------------------------------- 1 | package shareddefaults 2 | 3 | const ( 4 | // ECSCredsProviderEnvVar is an environmental variable key used to 5 | // determine which path needs to be hit. 6 | ECSCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" 7 | ) 8 | 9 | // ECSContainerCredentialsURI is the endpoint to retrieve container 10 | // credentials. This can be overridden to test to ensure the credential process 11 | // is behaving correctly. 12 | var ECSContainerCredentialsURI = "http://169.254.170.2" 13 | -------------------------------------------------------------------------------- /internal/shareddefaults/shared_config.go: -------------------------------------------------------------------------------- 1 | package shareddefaults 2 | 3 | import ( 4 | "os/user" 5 | "path/filepath" 6 | ) 7 | 8 | // SharedCredentialsFilename returns the SDK's default file path 9 | // for the shared credentials file. 10 | // 11 | // Builds the shared config file path based on the OS's platform. 12 | // 13 | // - Linux/Unix: $HOME/.aws/credentials 14 | // - Windows: %USERPROFILE%\.aws\credentials 15 | func SharedCredentialsFilename() string { 16 | return filepath.Join(UserHomeDir(), ".aws", "credentials") 17 | } 18 | 19 | // SharedConfigFilename returns the SDK's default file path for 20 | // the shared config file. 21 | // 22 | // Builds the shared config file path based on the OS's platform. 23 | // 24 | // - Linux/Unix: $HOME/.aws/config 25 | // - Windows: %USERPROFILE%\.aws\config 26 | func SharedConfigFilename() string { 27 | return filepath.Join(UserHomeDir(), ".aws", "config") 28 | } 29 | 30 | // UserHomeDir returns the home directory for the user the process is 31 | // running under. 32 | func UserHomeDir() string { 33 | var home string 34 | 35 | home = userHomeDir() 36 | if len(home) > 0 { 37 | return home 38 | } 39 | 40 | currUser, _ := user.Current() 41 | if currUser != nil { 42 | home = currUser.HomeDir 43 | } 44 | 45 | return home 46 | } 47 | -------------------------------------------------------------------------------- /internal/shareddefaults/shared_config_other_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package shareddefaults_test 5 | 6 | import ( 7 | "os" 8 | "path/filepath" 9 | "testing" 10 | 11 | "github.com/IBM/ibm-cos-sdk-go/internal/sdktesting" 12 | "github.com/IBM/ibm-cos-sdk-go/internal/shareddefaults" 13 | ) 14 | 15 | func TestSharedCredsFilename(t *testing.T) { 16 | restoreEnvFn := sdktesting.StashEnv() 17 | defer restoreEnvFn() 18 | 19 | os.Setenv("HOME", "home_dir") 20 | os.Setenv("USERPROFILE", "profile_dir") 21 | 22 | expect := filepath.Join("home_dir", ".aws", "credentials") 23 | 24 | name := shareddefaults.SharedCredentialsFilename() 25 | if e, a := expect, name; e != a { 26 | t.Errorf("expect %q shared creds filename, got %q", e, a) 27 | } 28 | } 29 | 30 | func TestSharedConfigFilename(t *testing.T) { 31 | restoreEnvFn := sdktesting.StashEnv() 32 | defer restoreEnvFn() 33 | 34 | os.Setenv("HOME", "home_dir") 35 | os.Setenv("USERPROFILE", "profile_dir") 36 | 37 | expect := filepath.Join("home_dir", ".aws", "config") 38 | 39 | name := shareddefaults.SharedConfigFilename() 40 | if e, a := expect, name; e != a { 41 | t.Errorf("expect %q shared config filename, got %q", e, a) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /internal/shareddefaults/shared_config_resolve_home.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.12 2 | // +build !go1.12 3 | 4 | package shareddefaults 5 | 6 | import ( 7 | "os" 8 | "runtime" 9 | ) 10 | 11 | func userHomeDir() string { 12 | if runtime.GOOS == "windows" { // Windows 13 | return os.Getenv("USERPROFILE") 14 | } 15 | 16 | // *nix 17 | return os.Getenv("HOME") 18 | } 19 | -------------------------------------------------------------------------------- /internal/shareddefaults/shared_config_resolve_home_go1.12.go: -------------------------------------------------------------------------------- 1 | //go:build go1.12 2 | // +build go1.12 3 | 4 | package shareddefaults 5 | 6 | import ( 7 | "os" 8 | ) 9 | 10 | func userHomeDir() string { 11 | home, _ := os.UserHomeDir() 12 | return home 13 | } 14 | -------------------------------------------------------------------------------- /internal/shareddefaults/shared_config_windows_test.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package shareddefaults_test 5 | 6 | import ( 7 | "os" 8 | "path/filepath" 9 | "testing" 10 | 11 | "github.com/IBM/ibm-cos-sdk-go/internal/sdktesting" 12 | "github.com/IBM/ibm-cos-sdk-go/internal/shareddefaults" 13 | ) 14 | 15 | func TestSharedCredsFilename(t *testing.T) { 16 | restoreEnvFn := sdktesting.StashEnv() 17 | defer restoreEnvFn() 18 | 19 | os.Setenv("HOME", "home_dir") 20 | os.Setenv("USERPROFILE", "profile_dir") 21 | 22 | expect := filepath.Join("profile_dir", ".aws", "credentials") 23 | 24 | name := shareddefaults.SharedCredentialsFilename() 25 | if e, a := expect, name; e != a { 26 | t.Errorf("expect %q shared creds filename, got %q", e, a) 27 | } 28 | } 29 | 30 | func TestSharedConfigFilename(t *testing.T) { 31 | restoreEnvFn := sdktesting.StashEnv() 32 | defer restoreEnvFn() 33 | 34 | os.Setenv("HOME", "home_dir") 35 | os.Setenv("USERPROFILE", "profile_dir") 36 | 37 | expect := filepath.Join("profile_dir", ".aws", "config") 38 | 39 | name := shareddefaults.SharedConfigFilename() 40 | if e, a := expect, name; e != a { 41 | t.Errorf("expect %q shared config filename, got %q", e, a) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /internal/smithytesting/document.go: -------------------------------------------------------------------------------- 1 | package smithytesting 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "reflect" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/internal/smithytesting/xml" 9 | ) 10 | 11 | // XMLEqual asserts two XML documents by sorting the XML and comparing the 12 | // strings It returns an error in case of mismatch or in case of malformed XML 13 | // found while sorting. In case of mismatched XML, the error string will 14 | // contain the diff between the two XML documents. 15 | func XMLEqual(expectBytes, actualBytes []byte) error { 16 | actualString, err := xml.SortXML(bytes.NewBuffer(actualBytes), true) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | expectString, err := xml.SortXML(bytes.NewBuffer(expectBytes), true) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | if !reflect.DeepEqual(expectString, actualString) { 27 | return fmt.Errorf("unexpected XML mismatch\nexpect: %+v\nactual: %+v", 28 | expectString, actualString) 29 | } 30 | 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /internal/smithytesting/xml/doc.go: -------------------------------------------------------------------------------- 1 | // Package xml is XML testing package that supports XML comparison utility. 2 | // The package consists of ToStruct and StructToXML utils that help sort XML 3 | // elements as per their nesting level. ToStruct function converts an XML 4 | // document into a sorted tree node structure, while StructToXML converts the 5 | // sorted XML nodes into a sorted XML document. SortXML function should be 6 | // used to sort an XML document. It can be configured to ignore indentation 7 | package xml 8 | -------------------------------------------------------------------------------- /internal/smithytesting/xml/sort.go: -------------------------------------------------------------------------------- 1 | package xml 2 | 3 | import ( 4 | "bytes" 5 | "encoding/xml" 6 | "io" 7 | "strings" 8 | ) 9 | 10 | type xmlAttrSlice []xml.Attr 11 | 12 | func (x xmlAttrSlice) Len() int { 13 | return len(x) 14 | } 15 | 16 | func (x xmlAttrSlice) Less(i, j int) bool { 17 | spaceI, spaceJ := x[i].Name.Space, x[j].Name.Space 18 | localI, localJ := x[i].Name.Local, x[j].Name.Local 19 | valueI, valueJ := x[i].Value, x[j].Value 20 | 21 | spaceCmp := strings.Compare(spaceI, spaceJ) 22 | localCmp := strings.Compare(localI, localJ) 23 | valueCmp := strings.Compare(valueI, valueJ) 24 | 25 | if spaceCmp == -1 || (spaceCmp == 0 && (localCmp == -1 || (localCmp == 0 && valueCmp == -1))) { 26 | return true 27 | } 28 | 29 | return false 30 | } 31 | 32 | func (x xmlAttrSlice) Swap(i, j int) { 33 | x[i], x[j] = x[j], x[i] 34 | } 35 | 36 | // SortXML sorts the reader's XML elements 37 | func SortXML(r io.Reader, ignoreIndentation bool) (string, error) { 38 | var buf bytes.Buffer 39 | d := xml.NewDecoder(r) 40 | root, err := ToStruct(d, nil, ignoreIndentation) 41 | if err != nil { 42 | return buf.String(), err 43 | } 44 | 45 | e := xml.NewEncoder(&buf) 46 | err = StructToXML(e, root, true) 47 | return buf.String(), err 48 | } 49 | -------------------------------------------------------------------------------- /internal/smithytesting/xml/sort_test.go: -------------------------------------------------------------------------------- 1 | package xml 2 | 3 | import ( 4 | "bytes" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestSortXML(t *testing.T) { 10 | xmlInput := bytes.NewReader([]byte(`xyz1231`)) 11 | sortedXML, err := SortXML(xmlInput, false) 12 | expectedsortedXML := `123xyz1` 13 | if err != nil { 14 | t.Fatalf("expected no error, got %v", err) 15 | } 16 | 17 | if !reflect.DeepEqual(sortedXML, expectedsortedXML) { 18 | t.Errorf("expect match\nexpect: %+v\nactual: %+v\n", expectedsortedXML, sortedXML) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /internal/strings/strings.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | // HasPrefixFold tests whether the string s begins with prefix, interpreted as UTF-8 strings, 8 | // under Unicode case-folding. 9 | func HasPrefixFold(s, prefix string) bool { 10 | return len(s) >= len(prefix) && strings.EqualFold(s[0:len(prefix)], prefix) 11 | } 12 | -------------------------------------------------------------------------------- /internal/sync/singleflight/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /models/apis/check_collisions_test.go: -------------------------------------------------------------------------------- 1 | //go:build awsinclude 2 | // +build awsinclude 3 | 4 | package apis 5 | 6 | import ( 7 | "os/exec" 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | func TestCollidingFolders(t *testing.T) { 13 | m := map[string]struct{}{} 14 | folders, err := getFolderNames() 15 | if err != nil { 16 | t.Error(err) 17 | } 18 | 19 | for _, folder := range folders { 20 | lcName := strings.ToLower(folder) 21 | if _, ok := m[lcName]; ok { 22 | t.Errorf("folder %q collision detected", folder) 23 | } 24 | m[lcName] = struct{}{} 25 | } 26 | } 27 | 28 | func getFolderNames() ([]string, error) { 29 | cmd := exec.Command("git", "ls-tree", "-d", "--name-only", "HEAD") 30 | output, err := cmd.Output() 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | return strings.Split(string(output), "\n"), nil 36 | } 37 | -------------------------------------------------------------------------------- /models/apis/kms/2014-11-01/paginators-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "pagination": { 3 | "DescribeCustomKeyStores": { 4 | "input_token": "Marker", 5 | "limit_key": "Limit", 6 | "output_token": "NextMarker", 7 | "result_key": "CustomKeyStores" 8 | }, 9 | "ListAliases": { 10 | "input_token": "Marker", 11 | "limit_key": "Limit", 12 | "output_token": "NextMarker", 13 | "result_key": "Aliases" 14 | }, 15 | "ListGrants": { 16 | "input_token": "Marker", 17 | "limit_key": "Limit", 18 | "output_token": "NextMarker", 19 | "result_key": "Grants" 20 | }, 21 | "ListKeyPolicies": { 22 | "input_token": "Marker", 23 | "limit_key": "Limit", 24 | "output_token": "NextMarker", 25 | "result_key": "PolicyNames" 26 | }, 27 | "ListKeys": { 28 | "input_token": "Marker", 29 | "limit_key": "Limit", 30 | "output_token": "NextMarker", 31 | "result_key": "Keys" 32 | }, 33 | "ListResourceTags": { 34 | "input_token": "Marker", 35 | "limit_key": "Limit", 36 | "output_token": "NextMarker", 37 | "result_key": "Tags" 38 | }, 39 | "ListRetirableGrants": { 40 | "input_token": "Marker", 41 | "limit_key": "Limit", 42 | "output_token": "NextMarker", 43 | "result_key": "Grants" 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /models/apis/kms/2014-11-01/smoke.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "defaultRegion": "us-west-2", 4 | "testCases": [ 5 | { 6 | "operationName": "ListAliases", 7 | "input": {}, 8 | "errorExpectedFromService": false 9 | }, 10 | { 11 | "operationName": "GetKeyPolicy", 12 | "input": { 13 | "KeyId": "12345678-1234-1234-1234-123456789012", 14 | "PolicyName": "fakePolicy" 15 | }, 16 | "errorExpectedFromService": true 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /models/apis/s3/2006-03-01/smoke.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "defaultRegion": "us-west-2", 4 | "testCases": [ 5 | { 6 | "operationName": "ListBuckets", 7 | "input": {}, 8 | "errorExpectedFromService": false 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /models/apis/stub.go: -------------------------------------------------------------------------------- 1 | //go:build awsinclude 2 | // +build awsinclude 3 | 4 | package apis 5 | -------------------------------------------------------------------------------- /models/endpoints/generate.go: -------------------------------------------------------------------------------- 1 | // Package endpoints contains the models for endpoints that should be used 2 | // to generate endpoint definition files for the SDK. 3 | package endpoints 4 | 5 | //go:generate go run -tags codegen ../../private/model/cli/gen-endpoints/main.go -model ./endpoints.json -out ../../aws/endpoints/defaults.go 6 | //go:generate gofmt -s -w ../../aws/endpoints 7 | -------------------------------------------------------------------------------- /private/README.md: -------------------------------------------------------------------------------- 1 | ## AWS SDK for Go Private packages ## 2 | `private` is a collection of packages used internally by the SDK, and is subject to have breaking changes. This package is not `internal` so that if you really need to use its functionality, and understand breaking changes will be made, you are able to. 3 | 4 | These packages will be refactored in the future so that the API generator and model parsers are exposed cleanly on their own. Making it easier for you to generate your own code based on the API models. 5 | -------------------------------------------------------------------------------- /private/checksum/content_md5.go: -------------------------------------------------------------------------------- 1 | package checksum 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/base64" 6 | "fmt" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/aws" 9 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 10 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 11 | ) 12 | 13 | const contentMD5Header = "Content-Md5" 14 | 15 | // AddBodyContentMD5Handler computes and sets the HTTP Content-MD5 header for requests that 16 | // require it. 17 | func AddBodyContentMD5Handler(r *request.Request) { 18 | // if Content-MD5 header is already present, return 19 | if v := r.HTTPRequest.Header.Get(contentMD5Header); len(v) != 0 { 20 | return 21 | } 22 | 23 | // if S3DisableContentMD5Validation flag is set, return 24 | if aws.BoolValue(r.Config.S3DisableContentMD5Validation) { 25 | return 26 | } 27 | 28 | // if request is presigned, return 29 | if r.IsPresigned() { 30 | return 31 | } 32 | 33 | // if body is not seekable, return 34 | if !aws.IsReaderSeekable(r.Body) { 35 | if r.Config.Logger != nil { 36 | r.Config.Logger.Log(fmt.Sprintf( 37 | "Unable to compute Content-MD5 for unseekable body, S3.%s", 38 | r.Operation.Name)) 39 | } 40 | return 41 | } 42 | 43 | h := md5.New() 44 | 45 | if _, err := aws.CopySeekableBody(h, r.Body); err != nil { 46 | r.Error = awserr.New("ContentMD5", "failed to compute body MD5", err) 47 | return 48 | } 49 | 50 | // encode the md5 checksum in base64 and set the request header. 51 | v := base64.StdEncoding.EncodeToString(h.Sum(nil)) 52 | r.HTTPRequest.Header.Set(contentMD5Header, v) 53 | } 54 | -------------------------------------------------------------------------------- /private/model/api/codegentest/models/jsonrpc/0000-00-00/docs-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "service": null, 4 | "operations": { 5 | }, 6 | "shapes":{} 7 | } 8 | -------------------------------------------------------------------------------- /private/model/api/codegentest/models/restjson/0000-00-00/docs-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "service": null, 4 | "operations": { 5 | }, 6 | "shapes":{} 7 | } 8 | -------------------------------------------------------------------------------- /private/model/api/codegentest/models/restxml/0000-00-00/docs-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "service": null, 4 | "operations": { 5 | }, 6 | "shapes":{} 7 | } 8 | -------------------------------------------------------------------------------- /private/model/api/codegentest/service/generate.go: -------------------------------------------------------------------------------- 1 | // Package service contains automatically generated AWS clients. 2 | package service 3 | 4 | //go:generate go run -tags codegen ../../../cli/gen-api/main.go -path=../service -svc-import-path "github.com/IBM/ibm-cos-sdk-go/private/model/api/codegentest/service" ../models/*/*/api-2.json 5 | //go:generate gofmt -s -w ../service 6 | -------------------------------------------------------------------------------- /private/model/api/codegentest/service/restjsonservice/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | // Package restjsonservice provides the client and types for making API 4 | // requests to REST JSON Service. 5 | // 6 | // See https://docs.aws.amazon.com/goto/WebAPI/RESTJSONService-0000-00-00 for more information on this service. 7 | // 8 | // See restjsonservice package documentation for more information. 9 | // https://docs.aws.amazon.com/sdk-for-go/api/service/restjsonservice/ 10 | // 11 | // # Using the Client 12 | // 13 | // To contact REST JSON Service with the SDK use the New function to create 14 | // a new service client. With that client you can make API requests to the service. 15 | // These clients are safe to use concurrently. 16 | // 17 | // See the SDK's documentation for more information on how to use the SDK. 18 | // https://docs.aws.amazon.com/sdk-for-go/api/ 19 | // 20 | // See aws.Config documentation for more information on configuring SDK clients. 21 | // https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config 22 | // 23 | // See the REST JSON Service client RESTJSONService for more 24 | // information on creating client for this service. 25 | // https://docs.aws.amazon.com/sdk-for-go/api/service/restjsonservice/#New 26 | package restjsonservice 27 | -------------------------------------------------------------------------------- /private/model/api/codegentest/service/restjsonservice/errors.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | package restjsonservice 4 | 5 | import ( 6 | "github.com/IBM/ibm-cos-sdk-go/private/protocol" 7 | ) 8 | 9 | const ( 10 | 11 | // ErrCodeExceptionEvent for service response error code 12 | // "ExceptionEvent". 13 | ErrCodeExceptionEvent = "ExceptionEvent" 14 | 15 | // ErrCodeExceptionEvent2 for service response error code 16 | // "ExceptionEvent2". 17 | ErrCodeExceptionEvent2 = "ExceptionEvent2" 18 | ) 19 | 20 | var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{ 21 | "ExceptionEvent": newErrorExceptionEvent, 22 | "ExceptionEvent2": newErrorExceptionEvent2, 23 | } 24 | -------------------------------------------------------------------------------- /private/model/api/codegentest/service/restxmlservice/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | // Package restxmlservice provides the client and types for making API 4 | // requests to REST XML Service. 5 | // 6 | // See https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00 for more information on this service. 7 | // 8 | // See restxmlservice package documentation for more information. 9 | // https://docs.aws.amazon.com/sdk-for-go/api/service/restxmlservice/ 10 | // 11 | // # Using the Client 12 | // 13 | // To contact REST XML Service with the SDK use the New function to create 14 | // a new service client. With that client you can make API requests to the service. 15 | // These clients are safe to use concurrently. 16 | // 17 | // See the SDK's documentation for more information on how to use the SDK. 18 | // https://docs.aws.amazon.com/sdk-for-go/api/ 19 | // 20 | // See aws.Config documentation for more information on configuring SDK clients. 21 | // https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config 22 | // 23 | // See the REST XML Service client RESTXMLService for more 24 | // information on creating client for this service. 25 | // https://docs.aws.amazon.com/sdk-for-go/api/service/restxmlservice/#New 26 | package restxmlservice 27 | -------------------------------------------------------------------------------- /private/model/api/codegentest/service/restxmlservice/errors.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | package restxmlservice 4 | 5 | const ( 6 | 7 | // ErrCodeExceptionEvent for service response error code 8 | // "ExceptionEvent". 9 | ErrCodeExceptionEvent = "ExceptionEvent" 10 | 11 | // ErrCodeExceptionEvent2 for service response error code 12 | // "ExceptionEvent2". 13 | ErrCodeExceptionEvent2 = "ExceptionEvent2" 14 | ) 15 | -------------------------------------------------------------------------------- /private/model/api/codegentest/service/rpcservice/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | // Package rpcservice provides the client and types for making API 4 | // requests to RPC Service. 5 | // 6 | // See https://docs.aws.amazon.com/goto/WebAPI/RPCService-0000-00-00 for more information on this service. 7 | // 8 | // See rpcservice package documentation for more information. 9 | // https://docs.aws.amazon.com/sdk-for-go/api/service/rpcservice/ 10 | // 11 | // # Using the Client 12 | // 13 | // To contact RPC Service with the SDK use the New function to create 14 | // a new service client. With that client you can make API requests to the service. 15 | // These clients are safe to use concurrently. 16 | // 17 | // See the SDK's documentation for more information on how to use the SDK. 18 | // https://docs.aws.amazon.com/sdk-for-go/api/ 19 | // 20 | // See aws.Config documentation for more information on configuring SDK clients. 21 | // https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config 22 | // 23 | // See the RPC Service client RPCService for more 24 | // information on creating client for this service. 25 | // https://docs.aws.amazon.com/sdk-for-go/api/service/rpcservice/#New 26 | package rpcservice 27 | -------------------------------------------------------------------------------- /private/model/api/codegentest/service/rpcservice/errors.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | package rpcservice 4 | 5 | import ( 6 | "github.com/IBM/ibm-cos-sdk-go/private/protocol" 7 | ) 8 | 9 | const ( 10 | 11 | // ErrCodeExceptionEvent for service response error code 12 | // "ExceptionEvent". 13 | ErrCodeExceptionEvent = "ExceptionEvent" 14 | 15 | // ErrCodeExceptionEvent2 for service response error code 16 | // "ExceptionEvent2". 17 | ErrCodeExceptionEvent2 = "ExceptionEvent2" 18 | ) 19 | 20 | var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{ 21 | "ExceptionEvent": newErrorExceptionEvent, 22 | "ExceptionEvent2": newErrorExceptionEvent2, 23 | } 24 | -------------------------------------------------------------------------------- /private/model/api/endpoint_trait.go: -------------------------------------------------------------------------------- 1 | //go:build codegen 2 | // +build codegen 3 | 4 | package api 5 | 6 | import ( 7 | "fmt" 8 | "text/template" 9 | ) 10 | 11 | func setupEndpointHostPrefix(op *Operation) { 12 | op.API.AddSDKImport("private/protocol") 13 | 14 | buildHandler := fmt.Sprintf("protocol.NewHostPrefixHandler(%q, ", 15 | op.Endpoint.HostPrefix) 16 | 17 | if op.InputRef.Shape.HasHostLabelMembers() { 18 | buildHandler += "input.hostLabels" 19 | } else { 20 | buildHandler += "nil" 21 | } 22 | 23 | buildHandler += ")" 24 | 25 | op.CustomBuildHandlers = append(op.CustomBuildHandlers, 26 | buildHandler, 27 | "protocol.ValidateEndpointHostHandler", 28 | ) 29 | } 30 | 31 | // HasHostLabelMembers returns true if the shape contains any members which are 32 | // decorated with the hostLabel trait. 33 | func (s *Shape) HasHostLabelMembers() bool { 34 | for _, ref := range s.MemberRefs { 35 | if ref.HostLabel { 36 | return true 37 | } 38 | } 39 | 40 | return false 41 | } 42 | 43 | var hostLabelsShapeTmpl = template.Must( 44 | template.New("hostLabelsShapeTmpl"). 45 | Parse(hostLabelsShapeTmplDef), 46 | ) 47 | 48 | const hostLabelsShapeTmplDef = ` 49 | {{- define "hostLabelsShapeTmpl" }} 50 | func (s *{{ $.ShapeName }}) hostLabels() map[string]string { 51 | return map[string]string{ 52 | {{- range $name, $ref := $.MemberRefs }} 53 | {{- if $ref.HostLabel }} 54 | "{{ $name }}": aws.StringValue(s.{{ $name }}), 55 | {{- end }} 56 | {{- end }} 57 | } 58 | } 59 | {{- end }} 60 | ` 61 | -------------------------------------------------------------------------------- /private/model/api/examples_builder_customizations.go: -------------------------------------------------------------------------------- 1 | //go:build codegen 2 | // +build codegen 3 | 4 | package api 5 | 6 | type wafregionalExamplesBuilder struct { 7 | defaultExamplesBuilder 8 | } 9 | 10 | func NewWAFregionalExamplesBuilder() wafregionalExamplesBuilder { 11 | return wafregionalExamplesBuilder{defaultExamplesBuilder: NewExamplesBuilder()} 12 | } 13 | func (builder wafregionalExamplesBuilder) Imports(a *API) string { 14 | return `"fmt" 15 | "strings" 16 | "time" 17 | 18 | "` + SDKImportRoot + `/aws" 19 | "` + SDKImportRoot + `/aws/awserr" 20 | "` + SDKImportRoot + `/aws/session" 21 | "` + SDKImportRoot + `/service/waf" 22 | "` + SDKImportRoot + `/service/` + a.PackageName() + `" 23 | ` 24 | } 25 | -------------------------------------------------------------------------------- /private/model/api/exportable_name.go: -------------------------------------------------------------------------------- 1 | //go:build codegen 2 | // +build codegen 3 | 4 | package api 5 | 6 | import "strings" 7 | 8 | // ExportableName a name which is exportable as a value or name in Go code 9 | func (a *API) ExportableName(name string) string { 10 | if name == "" { 11 | return name 12 | } 13 | 14 | return strings.ToUpper(name[0:1]) + name[1:] 15 | } 16 | -------------------------------------------------------------------------------- /private/model/api/legacy_io_suffix.go: -------------------------------------------------------------------------------- 1 | //go:build codegen 2 | // +build codegen 3 | 4 | package api 5 | 6 | // IoSuffix represents map of service to shape names that 7 | // are suffixed with `Input`, `Output` string and are not 8 | // Input or Output shapes used by any operation within 9 | // the service enclosure. 10 | type IoSuffix map[string]map[string]struct{} 11 | 12 | // LegacyIoSuffix returns if the shape names are legacy 13 | // names that contain "Input" and "Output" name as suffix. 14 | func (i IoSuffix) LegacyIOSuffix(a *API, shapeName string) bool { 15 | names, ok := i[a.name] 16 | if !ok { 17 | return false 18 | } 19 | 20 | _, ok = names[shapeName] 21 | return ok 22 | } 23 | 24 | // legacyIOSuffixed is the list of known shapes that have "Input" and "Output" 25 | // as suffix in shape name, but are not the actual input, output shape 26 | // for a corresponding service operation. 27 | var legacyIOSuffixed = IoSuffix{ 28 | "S3": { 29 | "ParquetInput": struct{}{}, 30 | "CSVOutput": struct{}{}, 31 | "JSONOutput": struct{}{}, 32 | "JSONInput": struct{}{}, 33 | "CSVInput": struct{}{}, 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /private/model/api/legacy_struct_names.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | var legacyStructNames = map[string]string{ 4 | "kms": "KMS", 5 | "s3": "Amazon S3", 6 | } 7 | -------------------------------------------------------------------------------- /private/model/api/logger.go: -------------------------------------------------------------------------------- 1 | //go:build codegen 2 | // +build codegen 3 | 4 | package api 5 | 6 | import ( 7 | "fmt" 8 | "io" 9 | "sync" 10 | ) 11 | 12 | var debugLogger *logger 13 | var initDebugLoggerOnce sync.Once 14 | 15 | // logger provides a basic logging 16 | type logger struct { 17 | w io.Writer 18 | } 19 | 20 | // LogDebug initialize's the debug logger for the components in the api 21 | // package to log debug lines to. 22 | // 23 | // Panics if called multiple times. 24 | // 25 | // Must be used prior to any model loading or code gen. 26 | func LogDebug(w io.Writer) { 27 | var initialized bool 28 | initDebugLoggerOnce.Do(func() { 29 | debugLogger = &logger{ 30 | w: w, 31 | } 32 | initialized = true 33 | }) 34 | 35 | if !initialized && debugLogger != nil { 36 | panic("LogDebug called multiple times. Can only be called once") 37 | } 38 | } 39 | 40 | // Logf logs using the fmt printf pattern. Appends a new line to the end of the 41 | // logged statement. 42 | func (l *logger) Logf(format string, args ...interface{}) { 43 | if l == nil { 44 | return 45 | } 46 | fmt.Fprintf(l.w, format+"\n", args...) 47 | } 48 | 49 | // Logln logs using the fmt println pattern. 50 | func (l *logger) Logln(args ...interface{}) { 51 | if l == nil { 52 | return 53 | } 54 | fmt.Fprintln(l.w, args...) 55 | } 56 | -------------------------------------------------------------------------------- /private/model/api/shape_alias.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | var shapeNameAliases = map[string]map[string]string{ 4 | "APIGateway": { 5 | "RequestValidator": "UpdateRequestValidatorOutput", 6 | "VpcLink": "UpdateVpcLinkOutput", 7 | "GatewayResponse": "UpdateGatewayResponseOutput", 8 | }, 9 | "Lambda": { 10 | "Concurrency": "PutFunctionConcurrencyOutput", 11 | }, 12 | "Neptune": { 13 | "DBClusterParameterGroupNameMessage": "ResetDBClusterParameterGroupOutput", 14 | "DBParameterGroupNameMessage": "ResetDBParameterGroupOutput", 15 | }, 16 | "RDS": { 17 | "DBClusterBacktrack": "BacktrackDBClusterOutput", 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /private/model/api/shapetag_test.go: -------------------------------------------------------------------------------- 1 | //go:build 1.6 && codegen 2 | // +build 1.6,codegen 3 | 4 | package api_test 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/private/model/api" 10 | ) 11 | 12 | func TestShapeTagJoin(t *testing.T) { 13 | s := api.ShapeTags{ 14 | {Key: "location", Val: "query"}, 15 | {Key: "locationName", Val: "abc"}, 16 | {Key: "type", Val: "string"}, 17 | } 18 | 19 | expected := `location:"query" locationName:"abc" type:"string"` 20 | 21 | o := s.Join(" ") 22 | o2 := s.String() 23 | if expected != o { 24 | t.Errorf("Expected %s, but received %s", expected, o) 25 | } 26 | if expected != o2 { 27 | t.Errorf("Expected %s, but received %s", expected, o2) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /private/model/cli/api-info/api-info.go: -------------------------------------------------------------------------------- 1 | //go:build codegen 2 | // +build codegen 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "path/filepath" 10 | "sort" 11 | 12 | "github.com/IBM/ibm-cos-sdk-go/private/model/api" 13 | ) 14 | 15 | func main() { 16 | dir, _ := os.Open(filepath.Join("models", "apis")) 17 | names, _ := dir.Readdirnames(0) 18 | for _, name := range names { 19 | m, _ := filepath.Glob(filepath.Join("models", "apis", name, "*", "api-2.json")) 20 | if len(m) == 0 { 21 | continue 22 | } 23 | 24 | sort.Strings(m) 25 | f := m[len(m)-1] 26 | a := api.API{} 27 | a.Attach(f) 28 | fmt.Printf("%s\t%s\n", a.Metadata.ServiceFullName, a.Metadata.APIVersion) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /private/model/cli/cleanup-models/main.go: -------------------------------------------------------------------------------- 1 | //go:build codegen 2 | // +build codegen 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "path/filepath" 10 | 11 | "github.com/IBM/ibm-cos-sdk-go/private/model/api" 12 | ) 13 | 14 | func main() { 15 | glob := filepath.FromSlash(os.Args[1]) 16 | modelPaths, err := api.ExpandModelGlobPath(glob) 17 | if err != nil { 18 | fmt.Fprintf(os.Stderr, "failed to expand glob, %v\n", err) 19 | os.Exit(1) 20 | } 21 | 22 | _, excluded := api.TrimModelServiceVersions(modelPaths) 23 | 24 | for _, exclude := range excluded { 25 | modelPath := filepath.Dir(exclude) 26 | fmt.Println("removing:", modelPath) 27 | os.RemoveAll(modelPath) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /private/protocol/eventstream/encode_test.go: -------------------------------------------------------------------------------- 1 | package eventstream 2 | 3 | import ( 4 | "bytes" 5 | "encoding/hex" 6 | "reflect" 7 | "testing" 8 | ) 9 | 10 | func TestEncoder_Encode(t *testing.T) { 11 | cases, err := readPositiveTests("testdata") 12 | if err != nil { 13 | t.Fatalf("failed to load positive tests, %v", err) 14 | } 15 | 16 | for _, c := range cases { 17 | var w bytes.Buffer 18 | encoder := NewEncoder(&w) 19 | 20 | err = encoder.Encode(c.Decoded.Message()) 21 | if err != nil { 22 | t.Fatalf("%s, failed to encode message, %v", c.Name, err) 23 | } 24 | 25 | if e, a := c.Encoded, w.Bytes(); !reflect.DeepEqual(e, a) { 26 | t.Errorf("%s, expect:\n%v\nactual:\n%v\n", c.Name, 27 | hex.Dump(e), hex.Dump(a)) 28 | } 29 | } 30 | } 31 | 32 | func BenchmarkEncode(b *testing.B) { 33 | var w bytes.Buffer 34 | encoder := NewEncoder(&w) 35 | msg := Message{ 36 | Headers: Headers{ 37 | {Name: "event-id", Value: Int16Value(123)}, 38 | }, 39 | Payload: []byte(`{"abc":123}`), 40 | } 41 | 42 | b.ResetTimer() 43 | 44 | for i := 0; i < b.N; i++ { 45 | err := encoder.Encode(msg) 46 | if err != nil { 47 | b.Fatal(err) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /private/protocol/eventstream/error.go: -------------------------------------------------------------------------------- 1 | package eventstream 2 | 3 | import "fmt" 4 | 5 | // LengthError provides the error for items being larger than a maximum length. 6 | type LengthError struct { 7 | Part string 8 | Want int 9 | Have int 10 | Value interface{} 11 | } 12 | 13 | func (e LengthError) Error() string { 14 | return fmt.Sprintf("%s length invalid, %d/%d, %v", 15 | e.Part, e.Want, e.Have, e.Value) 16 | } 17 | 18 | // ChecksumError provides the error for message checksum invalidation errors. 19 | type ChecksumError struct{} 20 | 21 | func (e ChecksumError) Error() string { 22 | return "message checksum mismatch" 23 | } 24 | -------------------------------------------------------------------------------- /private/protocol/eventstream/eventstreamapi/shared.go: -------------------------------------------------------------------------------- 1 | package eventstreamapi 2 | 3 | // EventStream headers with specific meaning to async API functionality. 4 | const ( 5 | ChunkSignatureHeader = `:chunk-signature` // chunk signature for message 6 | DateHeader = `:date` // Date header for signature 7 | 8 | // Message header and values 9 | MessageTypeHeader = `:message-type` // Identifies type of message. 10 | EventMessageType = `event` 11 | ErrorMessageType = `error` 12 | ExceptionMessageType = `exception` 13 | 14 | // Message Events 15 | EventTypeHeader = `:event-type` // Identifies message event type e.g. "Stats". 16 | 17 | // Message Error 18 | ErrorCodeHeader = `:error-code` 19 | ErrorMessageHeader = `:error-message` 20 | 21 | // Message Exception 22 | ExceptionTypeHeader = `:exception-type` 23 | ) 24 | -------------------------------------------------------------------------------- /private/protocol/eventstream/eventstreamapi/transport.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package eventstreamapi 5 | 6 | import "github.com/IBM/ibm-cos-sdk-go/aws/request" 7 | 8 | // ApplyHTTPTransportFixes is a no-op for Go 1.18 and above. 9 | func ApplyHTTPTransportFixes(r *request.Request) { 10 | } 11 | -------------------------------------------------------------------------------- /private/protocol/eventstream/eventstreamapi/transport_go1.17.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.18 2 | // +build !go1.18 3 | 4 | package eventstreamapi 5 | 6 | import "github.com/IBM/ibm-cos-sdk-go/aws/request" 7 | 8 | // ApplyHTTPTransportFixes applies fixes to the HTTP request for proper event 9 | // stream functionality. Go 1.15 through 1.17 HTTP client could hang forever 10 | // when an HTTP/2 connection failed with an non-200 status code and err. Using 11 | // Expect 100-Continue, allows the HTTP client to gracefully handle the non-200 12 | // status code, and close the connection. 13 | // 14 | // This is a no-op for Go 1.18 and above. 15 | func ApplyHTTPTransportFixes(r *request.Request) { 16 | r.Handlers.Sign.PushBack(func(r *request.Request) { 17 | r.HTTPRequest.Header.Set("Expect", "100-Continue") 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /private/protocol/eventstream/eventstreamtest/setup_server.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.10 2 | // +build !go1.10 3 | 4 | package eventstreamtest 5 | 6 | import ( 7 | "net/http" 8 | "net/http/httptest" 9 | ) 10 | 11 | // /x/net/http2 is only available for the latest two versions of Go. Any Go 12 | // version older than that cannot use the utility to configure the http2 13 | // server. 14 | func setupServer(server *httptest.Server, useH2 bool) *http.Client { 15 | server.Start() 16 | 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /private/protocol/eventstream/eventstreamtest/setup_server_1_10.go: -------------------------------------------------------------------------------- 1 | //go:build go1.15 2 | // +build go1.15 3 | 4 | package eventstreamtest 5 | 6 | import ( 7 | "crypto/tls" 8 | "net/http" 9 | "net/http/httptest" 10 | 11 | "golang.org/x/net/http2" 12 | ) 13 | 14 | // /x/net/http2 is only available for the latest two versions of Go. Any Go 15 | // version older than that cannot use the utility to configure the http2 16 | // server. 17 | func setupServer(server *httptest.Server, useH2 bool) *http.Client { 18 | server.Config.TLSConfig = &tls.Config{ 19 | InsecureSkipVerify: true, 20 | } 21 | 22 | clientTrans := &http.Transport{ 23 | TLSClientConfig: &tls.Config{ 24 | InsecureSkipVerify: true, 25 | }, 26 | } 27 | 28 | if useH2 { 29 | http2.ConfigureServer(server.Config, nil) 30 | http2.ConfigureTransport(clientTrans) 31 | server.Config.TLSConfig.NextProtos = []string{http2.NextProtoTLS} 32 | clientTrans.TLSClientConfig.NextProtos = []string{http2.NextProtoTLS} 33 | } 34 | server.TLS = server.Config.TLSConfig 35 | 36 | server.StartTLS() 37 | 38 | return &http.Client{ 39 | Transport: clientTrans, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /private/protocol/eventstream/eventstreamtest/stub_go1.9.go: -------------------------------------------------------------------------------- 1 | //go:build go1.9 2 | // +build go1.9 3 | 4 | package eventstreamtest 5 | 6 | import "testing" 7 | 8 | var getHelper = func(t testing.TB) func() { 9 | return t.Helper 10 | } 11 | -------------------------------------------------------------------------------- /private/protocol/eventstream/eventstreamtest/stub_old.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.9 2 | // +build !go1.9 3 | 4 | package eventstreamtest 5 | 6 | import "testing" 7 | 8 | var getHelper = func(t testing.TB) func() { 9 | return nopHelper 10 | } 11 | 12 | func nopHelper() {} 13 | -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/negative/corrupted_header_len: -------------------------------------------------------------------------------- 1 | Prelude checksum mismatch -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/negative/corrupted_headers: -------------------------------------------------------------------------------- 1 | Message checksum mismatch -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/negative/corrupted_length: -------------------------------------------------------------------------------- 1 | Prelude checksum mismatch -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/negative/corrupted_payload: -------------------------------------------------------------------------------- 1 | Message checksum mismatch -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/positive/all_headers: -------------------------------------------------------------------------------- 1 | { 2 | "total_length": 204, 3 | "headers_length": 175, 4 | "prelude_crc": 263087306, 5 | "headers": [ { 6 | "name": "event-type", 7 | "type": 4, 8 | "value": 40972 9 | }, 10 | { 11 | "name": "content-type", 12 | "type": 7, 13 | "value": "YXBwbGljYXRpb24vanNvbg==" 14 | }, 15 | { 16 | "name": "bool false", 17 | "type": 1, 18 | "value": false 19 | }, 20 | { 21 | "name": "bool true", 22 | "type": 0, 23 | "value": true 24 | }, 25 | { 26 | "name": "byte", 27 | "type": 2, 28 | "value": -49 29 | }, 30 | { 31 | "name": "byte buf", 32 | "type": 6, 33 | "value": "SSdtIGEgbGl0dGxlIHRlYXBvdCE=" 34 | }, 35 | { 36 | "name": "timestamp", 37 | "type": 8, 38 | "value": 8675309 39 | }, 40 | { 41 | "name": "int16", 42 | "type": 3, 43 | "value": 42 44 | }, 45 | { 46 | "name": "int64", 47 | "type": 5, 48 | "value": 42424242 49 | }, 50 | { 51 | "name": "uuid", 52 | "type": 9, 53 | "value": "AQIDBAUGBwgJCgsMDQ4PEA==" 54 | } 55 | ], 56 | "payload": "eydmb28nOidiYXInfQ==", 57 | "message_crc": -1415188212 58 | } 59 | -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/positive/empty_message: -------------------------------------------------------------------------------- 1 | { 2 | "total_length": 16, 3 | "headers_length": 0, 4 | "prelude_crc": 96618731, 5 | "headers": [ ], 6 | "payload": "", 7 | "message_crc": 2107164927 8 | } 9 | -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/positive/int32_header: -------------------------------------------------------------------------------- 1 | { 2 | "total_length": 45, 3 | "headers_length": 16, 4 | "prelude_crc": 1103373496, 5 | "headers": [ { 6 | "name": "event-type", 7 | "type": 4, 8 | "value": 40972 9 | } 10 | ], 11 | "payload": "eydmb28nOidiYXInfQ==", 12 | "message_crc": 921993376 13 | } 14 | -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/positive/payload_no_headers: -------------------------------------------------------------------------------- 1 | { 2 | "total_length": 29, 3 | "headers_length": 0, 4 | "prelude_crc": -44921766, 5 | "headers": [ ], 6 | "payload": "eydmb28nOidiYXInfQ==", 7 | "message_crc": -1016776394 8 | } 9 | -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/decoded/positive/payload_one_str_header: -------------------------------------------------------------------------------- 1 | { 2 | "total_length": 61, 3 | "headers_length": 32, 4 | "prelude_crc": 134054806, 5 | "headers": [ { 6 | "name": "content-type", 7 | "type": 7, 8 | "value": "YXBwbGljYXRpb24vanNvbg==" 9 | } 10 | ], 11 | "payload": "eydmb28nOidiYXInfQ==", 12 | "message_crc": -1919153999 13 | } 14 | -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/negative/corrupted_header_len: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/negative/corrupted_header_len -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/negative/corrupted_headers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/negative/corrupted_headers -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/negative/corrupted_length: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/negative/corrupted_length -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/negative/corrupted_payload: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/negative/corrupted_payload -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/positive/all_headers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/positive/all_headers -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/positive/empty_message: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/positive/empty_message -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/positive/int32_header: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/positive/int32_header -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/positive/payload_no_headers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/positive/payload_no_headers -------------------------------------------------------------------------------- /private/protocol/eventstream/testdata/encoded/positive/payload_one_str_header: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-cos-sdk-go/62ba6c910b34fa3f0c22d8b240c0c75a42a1c53a/private/protocol/eventstream/testdata/encoded/positive/payload_one_str_header -------------------------------------------------------------------------------- /private/protocol/host_prefix.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/aws" 7 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 8 | ) 9 | 10 | // HostPrefixHandlerName is the handler name for the host prefix request 11 | // handler. 12 | const HostPrefixHandlerName = "awssdk.endpoint.HostPrefixHandler" 13 | 14 | // NewHostPrefixHandler constructs a build handler 15 | func NewHostPrefixHandler(prefix string, labelsFn func() map[string]string) request.NamedHandler { 16 | builder := HostPrefixBuilder{ 17 | Prefix: prefix, 18 | LabelsFn: labelsFn, 19 | } 20 | 21 | return request.NamedHandler{ 22 | Name: HostPrefixHandlerName, 23 | Fn: builder.Build, 24 | } 25 | } 26 | 27 | // HostPrefixBuilder provides the request handler to expand and prepend 28 | // the host prefix into the operation's request endpoint host. 29 | type HostPrefixBuilder struct { 30 | Prefix string 31 | LabelsFn func() map[string]string 32 | } 33 | 34 | // Build updates the passed in Request with the HostPrefix template expanded. 35 | func (h HostPrefixBuilder) Build(r *request.Request) { 36 | if aws.BoolValue(r.Config.DisableEndpointHostPrefix) { 37 | return 38 | } 39 | 40 | var labels map[string]string 41 | if h.LabelsFn != nil { 42 | labels = h.LabelsFn() 43 | } 44 | 45 | prefix := h.Prefix 46 | for name, value := range labels { 47 | prefix = strings.Replace(prefix, "{"+name+"}", value, -1) 48 | } 49 | 50 | r.HTTPRequest.URL.Host = prefix + r.HTTPRequest.URL.Host 51 | if len(r.HTTPRequest.Host) > 0 { 52 | r.HTTPRequest.Host = prefix + r.HTTPRequest.Host 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /private/protocol/query/build.go: -------------------------------------------------------------------------------- 1 | // Package query provides serialization of AWS query requests, and responses. 2 | package query 3 | 4 | //go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/query.json build_test.go 5 | 6 | import ( 7 | "net/url" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 10 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 11 | "github.com/IBM/ibm-cos-sdk-go/private/protocol/query/queryutil" 12 | ) 13 | 14 | // BuildHandler is a named request handler for building query protocol requests 15 | var BuildHandler = request.NamedHandler{Name: "awssdk.query.Build", Fn: Build} 16 | 17 | // Build builds a request for an AWS Query service. 18 | func Build(r *request.Request) { 19 | body := url.Values{ 20 | "Action": {r.Operation.Name}, 21 | "Version": {r.ClientInfo.APIVersion}, 22 | } 23 | if err := queryutil.Parse(body, r.Params, false); err != nil { 24 | r.Error = awserr.New(request.ErrCodeSerialization, "failed encoding Query request", err) 25 | return 26 | } 27 | 28 | if !r.IsPresigned() { 29 | r.HTTPRequest.Method = "POST" 30 | r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") 31 | r.SetBufferBody([]byte(body.Encode())) 32 | } else { // This is a pre-signed request 33 | r.HTTPRequest.Method = "GET" 34 | r.HTTPRequest.URL.RawQuery = body.Encode() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /private/protocol/query/unmarshal.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | //go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/query.json unmarshal_test.go 4 | 5 | import ( 6 | "encoding/xml" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 9 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 10 | "github.com/IBM/ibm-cos-sdk-go/private/protocol/xml/xmlutil" 11 | ) 12 | 13 | // UnmarshalHandler is a named request handler for unmarshaling query protocol requests 14 | var UnmarshalHandler = request.NamedHandler{Name: "awssdk.query.Unmarshal", Fn: Unmarshal} 15 | 16 | // UnmarshalMetaHandler is a named request handler for unmarshaling query protocol request metadata 17 | var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalMeta", Fn: UnmarshalMeta} 18 | 19 | // Unmarshal unmarshals a response for an AWS Query service. 20 | func Unmarshal(r *request.Request) { 21 | defer r.HTTPResponse.Body.Close() 22 | if r.DataFilled() { 23 | decoder := xml.NewDecoder(r.HTTPResponse.Body) 24 | err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") 25 | if err != nil { 26 | r.Error = awserr.NewRequestFailure( 27 | awserr.New(request.ErrCodeSerialization, "failed decoding Query response", err), 28 | r.HTTPResponse.StatusCode, 29 | r.RequestID, 30 | ) 31 | return 32 | } 33 | } 34 | } 35 | 36 | // UnmarshalMeta unmarshals header response values for an AWS Query service. 37 | func UnmarshalMeta(r *request.Request) { 38 | r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") 39 | } 40 | -------------------------------------------------------------------------------- /private/protocol/rest/payload.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import "reflect" 4 | 5 | // PayloadMember returns the payload field member of i if there is one, or nil. 6 | func PayloadMember(i interface{}) interface{} { 7 | if i == nil { 8 | return nil 9 | } 10 | 11 | v := reflect.ValueOf(i).Elem() 12 | if !v.IsValid() { 13 | return nil 14 | } 15 | if field, ok := v.Type().FieldByName("_"); ok { 16 | if payloadName := field.Tag.Get("payload"); payloadName != "" { 17 | field, _ := v.Type().FieldByName(payloadName) 18 | if field.Tag.Get("type") != "structure" { 19 | return nil 20 | } 21 | 22 | payload := v.FieldByName(payloadName) 23 | if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { 24 | return payload.Interface() 25 | } 26 | } 27 | } 28 | return nil 29 | } 30 | 31 | const nopayloadPayloadType = "nopayload" 32 | 33 | // PayloadType returns the type of a payload field member of i if there is one, 34 | // or "". 35 | func PayloadType(i interface{}) string { 36 | v := reflect.Indirect(reflect.ValueOf(i)) 37 | if !v.IsValid() { 38 | return "" 39 | } 40 | 41 | if field, ok := v.Type().FieldByName("_"); ok { 42 | if noPayload := field.Tag.Get(nopayloadPayloadType); noPayload != "" { 43 | return nopayloadPayloadType 44 | } 45 | 46 | if payloadName := field.Tag.Get("payload"); payloadName != "" { 47 | if member, ok := v.Type().FieldByName(payloadName); ok { 48 | return member.Tag.Get("type") 49 | } 50 | } 51 | } 52 | 53 | return "" 54 | } 55 | -------------------------------------------------------------------------------- /private/protocol/unmarshal.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | 7 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 8 | ) 9 | 10 | // UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body 11 | var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody} 12 | 13 | // UnmarshalDiscardBody is a request handler to empty a response's body and closing it. 14 | func UnmarshalDiscardBody(r *request.Request) { 15 | if r.HTTPResponse == nil || r.HTTPResponse.Body == nil { 16 | return 17 | } 18 | 19 | io.Copy(ioutil.Discard, r.HTTPResponse.Body) 20 | r.HTTPResponse.Body.Close() 21 | } 22 | 23 | // ResponseMetadata provides the SDK response metadata attributes. 24 | type ResponseMetadata struct { 25 | StatusCode int 26 | RequestID string 27 | } 28 | -------------------------------------------------------------------------------- /private/protocol/xml/xmlutil/sort.go: -------------------------------------------------------------------------------- 1 | package xmlutil 2 | 3 | import ( 4 | "encoding/xml" 5 | "strings" 6 | ) 7 | 8 | type xmlAttrSlice []xml.Attr 9 | 10 | func (x xmlAttrSlice) Len() int { 11 | return len(x) 12 | } 13 | 14 | func (x xmlAttrSlice) Less(i, j int) bool { 15 | spaceI, spaceJ := x[i].Name.Space, x[j].Name.Space 16 | localI, localJ := x[i].Name.Local, x[j].Name.Local 17 | valueI, valueJ := x[i].Value, x[j].Value 18 | 19 | spaceCmp := strings.Compare(spaceI, spaceJ) 20 | localCmp := strings.Compare(localI, localJ) 21 | valueCmp := strings.Compare(valueI, valueJ) 22 | 23 | if spaceCmp == -1 || (spaceCmp == 0 && (localCmp == -1 || (localCmp == 0 && valueCmp == -1))) { 24 | return true 25 | } 26 | 27 | return false 28 | } 29 | 30 | func (x xmlAttrSlice) Swap(i, j int) { 31 | x[i], x[j] = x[j], x[i] 32 | } 33 | -------------------------------------------------------------------------------- /private/util/sort_keys.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "sort" 4 | 5 | // SortedKeys returns a sorted slice of keys of a map. 6 | func SortedKeys(m map[string]interface{}) []string { 7 | i, sorted := 0, make([]string, len(m)) 8 | for k := range m { 9 | sorted[i] = k 10 | i++ 11 | } 12 | sort.Strings(sorted) 13 | return sorted 14 | } 15 | -------------------------------------------------------------------------------- /service/generate.go: -------------------------------------------------------------------------------- 1 | // Package service contains automatically generated AWS clients. 2 | package service 3 | 4 | //go:generate go run -tags codegen ../private/model/cli/gen-api/main.go -path=../service ../models/apis/*/*/api-2.json 5 | //go:generate gofmt -s -w ../service 6 | -------------------------------------------------------------------------------- /service/s3/bench_test.go: -------------------------------------------------------------------------------- 1 | package s3 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | "time" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/aws" 9 | "github.com/IBM/ibm-cos-sdk-go/awstesting/unit" 10 | ) 11 | 12 | func BenchmarkPresign_GetObject(b *testing.B) { 13 | sess := unit.Session 14 | svc := New(sess) 15 | 16 | for i := 0; i < b.N; i++ { 17 | req, _ := svc.GetObjectRequest(&GetObjectInput{ 18 | Bucket: aws.String("mock-bucket"), 19 | Key: aws.String("mock-key"), 20 | }) 21 | 22 | u, h, err := req.PresignRequest(15 * time.Minute) 23 | if err != nil { 24 | b.Fatalf("expect no error, got %v", err) 25 | } 26 | if len(u) == 0 { 27 | b.Fatalf("expect url, got none") 28 | } 29 | if len(h) != 0 { 30 | b.Fatalf("no signed headers, got %v", h) 31 | } 32 | } 33 | } 34 | 35 | func BenchmarkPresign_PutObject(b *testing.B) { 36 | sess := unit.Session 37 | svc := New(sess) 38 | 39 | body := make([]byte, 1024*1024*20) 40 | for i := 0; i < b.N; i++ { 41 | req, _ := svc.PutObjectRequest(&PutObjectInput{ 42 | Bucket: aws.String("mock-bucket"), 43 | Key: aws.String("mock-key"), 44 | Body: bytes.NewReader(body), 45 | }) 46 | 47 | u, h, err := req.PresignRequest(15 * time.Minute) 48 | if err != nil { 49 | b.Fatalf("expect no error, got %v", err) 50 | } 51 | if len(u) == 0 { 52 | b.Fatalf("expect url, got none") 53 | } 54 | if len(h) == 0 { 55 | b.Fatalf("expect signed header, got none") 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /service/s3/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | // Package s3 provides the client and types for making API 4 | // requests to Amazon Simple Storage Service. 5 | // 6 | // See https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01 for more information on this service. 7 | // 8 | // See s3 package documentation for more information. 9 | // https://docs.aws.amazon.com/sdk-for-go/api/service/s3/ 10 | // 11 | // # Using the Client 12 | // 13 | // To contact Amazon Simple Storage Service with the SDK use the New function to create 14 | // a new service client. With that client you can make API requests to the service. 15 | // These clients are safe to use concurrently. 16 | // 17 | // See the SDK's documentation for more information on how to use the SDK. 18 | // https://docs.aws.amazon.com/sdk-for-go/api/ 19 | // 20 | // See aws.Config documentation for more information on configuring SDK clients. 21 | // https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config 22 | // 23 | // See the Amazon Simple Storage Service client S3 for more 24 | // information on creating client for this service. 25 | // https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#New 26 | package s3 27 | -------------------------------------------------------------------------------- /service/s3/integ_test.go: -------------------------------------------------------------------------------- 1 | // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 | 3 | //go:build go1.16 && integration 4 | // +build go1.16,integration 5 | 6 | package s3_test 7 | 8 | import ( 9 | "context" 10 | "testing" 11 | "time" 12 | 13 | "github.com/IBM/ibm-cos-sdk-go/aws" 14 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 15 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 16 | "github.com/IBM/ibm-cos-sdk-go/awstesting/integration" 17 | "github.com/IBM/ibm-cos-sdk-go/service/s3" 18 | ) 19 | 20 | var _ aws.Config 21 | var _ awserr.Error 22 | var _ request.Request 23 | 24 | func TestInteg_00_ListBuckets(t *testing.T) { 25 | ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second) 26 | defer cancelFn() 27 | 28 | sess := integration.SessionWithDefaultRegion("us-west-2") 29 | svc := s3.New(sess) 30 | params := &s3.ListBucketsInput{} 31 | _, err := svc.ListBucketsWithContext(ctx, params, func(r *request.Request) { 32 | r.Handlers.Validate.RemoveByName("core.ValidateParametersHandler") 33 | }) 34 | if err != nil { 35 | t.Errorf("expect no error, got %v", err) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /service/s3/internal/s3testing/s3testing.go: -------------------------------------------------------------------------------- 1 | package s3testing 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | 7 | "github.com/IBM/ibm-cos-sdk-go/internal/sdkio" 8 | "github.com/IBM/ibm-cos-sdk-go/internal/sdkrand" 9 | ) 10 | 11 | var randBytes = func() []byte { 12 | rr := rand.New(rand.NewSource(0)) 13 | b := make([]byte, 10*sdkio.MebiByte) 14 | 15 | if _, err := sdkrand.Read(rr, b); err != nil { 16 | panic(fmt.Sprintf("failed to read random bytes, %v", err)) 17 | } 18 | return b 19 | }() 20 | 21 | // GetTestBytes returns a pseudo-random []byte of length size 22 | func GetTestBytes(size int) []byte { 23 | if len(randBytes) >= size { 24 | return randBytes[:size] 25 | } 26 | 27 | b := append(randBytes, GetTestBytes(size-len(randBytes))...) 28 | return b 29 | } 30 | -------------------------------------------------------------------------------- /service/s3/platform_handlers.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.6 2 | // +build !go1.6 3 | 4 | package s3 5 | 6 | import "github.com/IBM/ibm-cos-sdk-go/aws/request" 7 | 8 | func platformRequestHandlers(r *request.Request) { 9 | } 10 | -------------------------------------------------------------------------------- /service/s3/platform_handlers_go1.6.go: -------------------------------------------------------------------------------- 1 | //go:build go1.6 2 | // +build go1.6 3 | 4 | package s3 5 | 6 | import ( 7 | "github.com/IBM/ibm-cos-sdk-go/aws" 8 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 9 | ) 10 | 11 | func platformRequestHandlers(r *request.Request) { 12 | if r.Operation.HTTPMethod == "PUT" { 13 | // 100-Continue should only be used on put requests. 14 | r.Handlers.Sign.PushBack(add100Continue) 15 | } 16 | } 17 | 18 | func add100Continue(r *request.Request) { 19 | if aws.BoolValue(r.Config.S3Disable100Continue) { 20 | return 21 | } 22 | if r.HTTPRequest.ContentLength < 1024*1024*2 { 23 | // Ignore requests smaller than 2MB. This helps prevent delaying 24 | // requests unnecessarily. 25 | return 26 | } 27 | 28 | r.HTTPRequest.Header.Set("Expect", "100-continue") 29 | } 30 | -------------------------------------------------------------------------------- /service/s3/s3crypto/aes_cbc_padder.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | const ( 4 | pkcs5BlockSize = 16 5 | ) 6 | 7 | var aescbcPadding = aescbcPadder{pkcs7Padder{16}} 8 | 9 | // AESCBCPadder is used to pad AES encrypted and decrypted data. 10 | // Although it uses the pkcs5Padder, it isn't following the RFC 11 | // for PKCS5. The only reason why it is called pkcs5Padder is 12 | // due to the Name returning PKCS5Padding. 13 | var AESCBCPadder = Padder(aescbcPadding) 14 | 15 | type aescbcPadder struct { 16 | padder pkcs7Padder 17 | } 18 | 19 | func (padder aescbcPadder) Pad(b []byte, n int) ([]byte, error) { 20 | return padder.padder.Pad(b, n) 21 | } 22 | 23 | func (padder aescbcPadder) Unpad(b []byte) ([]byte, error) { 24 | return padder.padder.Unpad(b) 25 | } 26 | 27 | func (padder aescbcPadder) Name() string { 28 | return "PKCS5Padding" 29 | } 30 | -------------------------------------------------------------------------------- /service/s3/s3crypto/aes_cbc_padder_test.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | func TestAESCBCPadding(t *testing.T) { 10 | for i := 0; i < 16; i++ { 11 | input := make([]byte, i) 12 | expected := append(input, bytes.Repeat([]byte{byte(16 - i)}, 16-i)...) 13 | b, err := AESCBCPadder.Pad(input, len(input)) 14 | if err != nil { 15 | t.Fatal("Expected error to be nil but received " + err.Error()) 16 | } 17 | if len(b) != len(expected) { 18 | t.Fatal(fmt.Sprintf("Case %d: data is not of the same length", i)) 19 | } 20 | if bytes.Compare(b, expected) != 0 { 21 | t.Fatal(fmt.Sprintf("Expected %v but got %v", expected, b)) 22 | } 23 | } 24 | } 25 | 26 | func TestAESCBCUnpadding(t *testing.T) { 27 | for i := 0; i < 16; i++ { 28 | expected := make([]byte, i) 29 | input := append(expected, bytes.Repeat([]byte{byte(16 - i)}, 16-i)...) 30 | b, err := AESCBCPadder.Unpad(input) 31 | if err != nil { 32 | t.Fatal("Error received, was expecting nil: " + err.Error()) 33 | } 34 | if len(b) != len(expected) { 35 | t.Fatal(fmt.Sprintf("Case %d: data is not of the same length", i)) 36 | } 37 | if bytes.Compare(b, expected) != 0 { 38 | t.Fatal(fmt.Sprintf("Expected %v but got %v", expected, b)) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /service/s3/s3crypto/cipher.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | // Cipher interface allows for either encryption and decryption of an object 8 | type Cipher interface { 9 | Encrypter 10 | Decrypter 11 | } 12 | 13 | // Encrypter interface with only the encrypt method 14 | type Encrypter interface { 15 | Encrypt(io.Reader) io.Reader 16 | } 17 | 18 | // Decrypter interface with only the decrypt method 19 | type Decrypter interface { 20 | Decrypt(io.Reader) io.Reader 21 | } 22 | 23 | // CryptoReadCloser handles closing of the body and allowing reads from the decrypted 24 | // content. 25 | type CryptoReadCloser struct { 26 | Body io.ReadCloser 27 | Decrypter io.Reader 28 | isClosed bool 29 | } 30 | 31 | // Close lets the CryptoReadCloser satisfy io.ReadCloser interface 32 | func (rc *CryptoReadCloser) Close() error { 33 | rc.isClosed = true 34 | return rc.Body.Close() 35 | } 36 | 37 | // Read lets the CryptoReadCloser satisfy io.ReadCloser interface 38 | func (rc *CryptoReadCloser) Read(b []byte) (int, error) { 39 | if rc.isClosed { 40 | return 0, io.EOF 41 | } 42 | return rc.Decrypter.Read(b) 43 | } 44 | -------------------------------------------------------------------------------- /service/s3/s3crypto/cipher_builder.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/IBM/ibm-cos-sdk-go/aws" 7 | ) 8 | 9 | // ContentCipherBuilder is a builder interface that builds 10 | // ciphers for each request. 11 | type ContentCipherBuilder interface { 12 | ContentCipher() (ContentCipher, error) 13 | } 14 | 15 | // ContentCipherBuilderWithContext is a builder interface that builds 16 | // ciphers for each request. 17 | type ContentCipherBuilderWithContext interface { 18 | ContentCipherWithContext(aws.Context) (ContentCipher, error) 19 | } 20 | 21 | // ContentCipher deals with encrypting and decrypting content 22 | type ContentCipher interface { 23 | EncryptContents(io.Reader) (io.Reader, error) 24 | DecryptContents(io.ReadCloser) (io.ReadCloser, error) 25 | GetCipherData() CipherData 26 | } 27 | 28 | // CipherData is used for content encryption. It is used for storing the 29 | // metadata of the encrypted content. 30 | type CipherData struct { 31 | Key []byte 32 | IV []byte 33 | WrapAlgorithm string 34 | CEKAlgorithm string 35 | TagLength string 36 | MaterialDescription MaterialDescription 37 | // EncryptedKey should be populated when calling GenerateCipherData 38 | EncryptedKey []byte 39 | 40 | Padder Padder 41 | } 42 | 43 | // Clone returns a new copy of CipherData 44 | func (cd CipherData) Clone() (v CipherData) { 45 | v = cd 46 | v.MaterialDescription = cd.MaterialDescription.Clone() 47 | return v 48 | } 49 | -------------------------------------------------------------------------------- /service/s3/s3crypto/cipher_test.go: -------------------------------------------------------------------------------- 1 | package s3crypto_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/IBM/ibm-cos-sdk-go/service/s3/s3crypto" 9 | ) 10 | 11 | func TestCryptoReadCloserRead(t *testing.T) { 12 | expectedStr := "HELLO WORLD " 13 | str := strings.NewReader(expectedStr) 14 | rc := &s3crypto.CryptoReadCloser{Body: ioutil.NopCloser(str), Decrypter: str} 15 | 16 | b, err := ioutil.ReadAll(rc) 17 | if err != nil { 18 | t.Errorf("expected no error, but received %v", err) 19 | } 20 | if expectedStr != string(b) { 21 | t.Errorf("expected %s, but received %s", expectedStr, string(b)) 22 | } 23 | } 24 | 25 | func TestCryptoReadCloserClose(t *testing.T) { 26 | data := "HELLO WORLD " 27 | expectedStr := "" 28 | 29 | str := strings.NewReader(data) 30 | rc := &s3crypto.CryptoReadCloser{Body: ioutil.NopCloser(str), Decrypter: str} 31 | rc.Close() 32 | 33 | b, err := ioutil.ReadAll(rc) 34 | if err != nil { 35 | t.Errorf("expected no error, but received %v", err) 36 | } 37 | if expectedStr != string(b) { 38 | t.Errorf("expected %s, but received %s", expectedStr, string(b)) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /service/s3/s3crypto/cipher_util.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import ( 4 | "encoding/base64" 5 | "strconv" 6 | ) 7 | 8 | // AESGCMNoPadding is the constant value that is used to specify 9 | // the cek algorithm consiting of AES GCM with no padding. 10 | const AESGCMNoPadding = "AES/GCM/NoPadding" 11 | 12 | // AESCBC is the string constant that signifies the AES CBC algorithm cipher. 13 | const AESCBC = "AES/CBC" 14 | 15 | func encodeMeta(reader lengthReader, cd CipherData) (Envelope, error) { 16 | iv := base64.StdEncoding.EncodeToString(cd.IV) 17 | key := base64.StdEncoding.EncodeToString(cd.EncryptedKey) 18 | 19 | contentLength := reader.GetContentLength() 20 | 21 | matdesc, err := cd.MaterialDescription.encodeDescription() 22 | if err != nil { 23 | return Envelope{}, err 24 | } 25 | 26 | return Envelope{ 27 | CipherKey: key, 28 | IV: iv, 29 | MatDesc: string(matdesc), 30 | WrapAlg: cd.WrapAlgorithm, 31 | CEKAlg: cd.CEKAlgorithm, 32 | TagLen: cd.TagLength, 33 | UnencryptedContentLen: strconv.FormatInt(contentLength, 10), 34 | }, nil 35 | } 36 | -------------------------------------------------------------------------------- /service/s3/s3crypto/errors.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import "fmt" 4 | 5 | var errNilCryptoRegistry = fmt.Errorf("provided CryptoRegistry must not be nil") 6 | var errNilWrapEntry = fmt.Errorf("wrap entry must not be nil") 7 | var errNilCEKEntry = fmt.Errorf("cek entry must not be nil") 8 | var errNilPadder = fmt.Errorf("padder must not be nil") 9 | 10 | func newErrDuplicateWrapEntry(name string) error { 11 | return newErrDuplicateRegistryEntry("wrap", name) 12 | } 13 | 14 | func newErrDuplicateCEKEntry(name string) error { 15 | return newErrDuplicateRegistryEntry("cek", name) 16 | } 17 | 18 | func newErrDuplicatePadderEntry(name string) error { 19 | return newErrDuplicateRegistryEntry("padder", name) 20 | } 21 | 22 | func newErrDuplicateRegistryEntry(registry, key string) error { 23 | return fmt.Errorf("duplicate %v registry entry, %v", registry, key) 24 | } 25 | -------------------------------------------------------------------------------- /service/s3/s3crypto/fixture.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import "fmt" 4 | 5 | type clientVersion int 6 | 7 | const ( 8 | v1ClientVersion clientVersion = 1 + iota 9 | v2ClientVersion 10 | ) 11 | 12 | var errDeprecatedIncompatibleCipherBuilder = fmt.Errorf("attempted to use deprecated or incompatible cipher builder") 13 | 14 | // compatibleEncryptionFixture is an unexported interface to expose whether a given fixture is compatible for encryption 15 | // given the provided client version. 16 | type compatibleEncryptionFixture interface { 17 | isEncryptionVersionCompatible(clientVersion) error 18 | } 19 | 20 | // awsFixture is an unexported interface to expose whether a given fixture is an aws provided fixture, and whether that 21 | // fixtures dependencies were constructed using aws types. 22 | // 23 | // This interface is used in v2 clients to warn users if they are using custom implementations of ContentCipherBuilder 24 | // or CipherDataGenerator. 25 | type awsFixture interface { 26 | isAWSFixture() bool 27 | } 28 | -------------------------------------------------------------------------------- /service/s3/s3crypto/hash_io.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import ( 4 | "crypto/sha256" 5 | "hash" 6 | "io" 7 | ) 8 | 9 | // lengthReader returns the content length 10 | type lengthReader interface { 11 | GetContentLength() int64 12 | } 13 | 14 | type contentLengthReader struct { 15 | contentLength int64 16 | body io.Reader 17 | } 18 | 19 | func newContentLengthReader(f io.Reader) *contentLengthReader { 20 | return &contentLengthReader{body: f} 21 | } 22 | 23 | func (r *contentLengthReader) Read(b []byte) (int, error) { 24 | n, err := r.body.Read(b) 25 | if err != nil && err != io.EOF { 26 | return n, err 27 | } 28 | r.contentLength += int64(n) 29 | return n, err 30 | } 31 | 32 | func (r *contentLengthReader) GetContentLength() int64 { 33 | return r.contentLength 34 | } 35 | 36 | type sha256Writer struct { 37 | sha256 []byte 38 | hash hash.Hash 39 | out io.Writer 40 | } 41 | 42 | func newSHA256Writer(f io.Writer) *sha256Writer { 43 | return &sha256Writer{hash: sha256.New(), out: f} 44 | } 45 | func (r *sha256Writer) Write(b []byte) (int, error) { 46 | r.hash.Write(b) 47 | return r.out.Write(b) 48 | } 49 | 50 | func (r *sha256Writer) GetValue() []byte { 51 | return r.hash.Sum(nil) 52 | } 53 | -------------------------------------------------------------------------------- /service/s3/s3crypto/key_handler_test.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestGenerateBytes(t *testing.T) { 8 | b, _ := generateBytes(5) 9 | if e, a := 5, len(b); e != a { 10 | t.Errorf("expected %d, but received %d", e, a) 11 | } 12 | b, _ = generateBytes(0) 13 | if e, a := 0, len(b); e != a { 14 | t.Errorf("expected %d, but received %d", e, a) 15 | } 16 | b, _ = generateBytes(1024) 17 | if e, a := 1024, len(b); e != a { 18 | t.Errorf("expected %d, but received %d", e, a) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /service/s3/s3crypto/mat_desc.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | // MaterialDescription is used to identify how and what master 8 | // key has been used. 9 | type MaterialDescription map[string]*string 10 | 11 | // Clone returns a copy of the MaterialDescription 12 | func (md MaterialDescription) Clone() (clone MaterialDescription) { 13 | if md == nil { 14 | return nil 15 | } 16 | clone = make(MaterialDescription, len(md)) 17 | for k, v := range md { 18 | clone[k] = copyPtrString(v) 19 | } 20 | return clone 21 | } 22 | 23 | func (md *MaterialDescription) encodeDescription() ([]byte, error) { 24 | v, err := json.Marshal(&md) 25 | return v, err 26 | } 27 | 28 | func (md *MaterialDescription) decodeDescription(b []byte) error { 29 | return json.Unmarshal(b, &md) 30 | } 31 | 32 | func copyPtrString(v *string) *string { 33 | if v == nil { 34 | return nil 35 | } 36 | ns := *v 37 | return &ns 38 | } 39 | -------------------------------------------------------------------------------- /service/s3/s3crypto/padder.go: -------------------------------------------------------------------------------- 1 | package s3crypto 2 | 3 | // Padder handles padding of crypto data 4 | type Padder interface { 5 | // Pad will pad the byte array. 6 | // The second parameter is NOT how many 7 | // bytes to pad by, but how many bytes 8 | // have been read prior to the padding. 9 | // This allows for streamable padding. 10 | Pad([]byte, int) ([]byte, error) 11 | // Unpad will unpad the byte bytes. Unpad 12 | // methods must be constant time. 13 | Unpad([]byte) ([]byte, error) 14 | // Name returns the name of the padder. 15 | // This is used when decrypting on 16 | // instantiating new padders. 17 | Name() string 18 | } 19 | 20 | // NoPadder does not pad anything 21 | var NoPadder = Padder(noPadder{}) 22 | 23 | type noPadder struct{} 24 | 25 | func (padder noPadder) Pad(b []byte, n int) ([]byte, error) { 26 | return b, nil 27 | } 28 | 29 | func (padder noPadder) Unpad(b []byte) ([]byte, error) { 30 | return b, nil 31 | } 32 | 33 | func (padder noPadder) Name() string { 34 | return "NoPadding" 35 | } 36 | -------------------------------------------------------------------------------- /service/s3/s3manager/arn.go: -------------------------------------------------------------------------------- 1 | package s3manager 2 | 3 | import ( 4 | "fmt" 5 | "github.com/IBM/ibm-cos-sdk-go/aws/arn" 6 | ) 7 | 8 | func validateSupportedARNType(bucket string) error { 9 | if !arn.IsARN(bucket) { 10 | return nil 11 | } 12 | 13 | parsedARN, err := arn.Parse(bucket) 14 | if err != nil { 15 | return err 16 | } 17 | 18 | if parsedARN.Service == "s3-object-lambda" { 19 | return fmt.Errorf("manager does not support s3-object-lambda service ARNs") 20 | } 21 | 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /service/s3/s3manager/default_read_seeker_write_to.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package s3manager 5 | 6 | func defaultUploadBufferProvider() ReadSeekerWriteToProvider { 7 | return nil 8 | } 9 | -------------------------------------------------------------------------------- /service/s3/s3manager/default_read_seeker_write_to_windows.go: -------------------------------------------------------------------------------- 1 | package s3manager 2 | 3 | func defaultUploadBufferProvider() ReadSeekerWriteToProvider { 4 | return NewBufferedReadSeekerWriteToPool(1024 * 1024) 5 | } 6 | -------------------------------------------------------------------------------- /service/s3/s3manager/default_writer_read_from.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package s3manager 5 | 6 | func defaultDownloadBufferProvider() WriterReadFromProvider { 7 | return nil 8 | } 9 | -------------------------------------------------------------------------------- /service/s3/s3manager/default_writer_read_from_windows.go: -------------------------------------------------------------------------------- 1 | package s3manager 2 | 3 | func defaultDownloadBufferProvider() WriterReadFromProvider { 4 | return NewPooledBufferedWriterReadFromProvider(1024 * 1024) 5 | } 6 | -------------------------------------------------------------------------------- /service/s3/s3manager/doc.go: -------------------------------------------------------------------------------- 1 | // Package s3manager provides utilities to upload and download objects from 2 | // S3 concurrently. Helpful for when working with large objects. 3 | package s3manager 4 | -------------------------------------------------------------------------------- /service/s3/s3manager/integ_bucket_region_test.go: -------------------------------------------------------------------------------- 1 | //go:build integration 2 | // +build integration 3 | 4 | package s3manager_test 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/aws" 10 | "github.com/IBM/ibm-cos-sdk-go/service/s3/s3manager" 11 | ) 12 | 13 | func TestGetBucketRegion(t *testing.T) { 14 | expectRegion := aws.StringValue(integSess.Config.Region) 15 | 16 | ctx := aws.BackgroundContext() 17 | region, err := s3manager.GetBucketRegion(ctx, integSess, 18 | aws.StringValue(bucketName), expectRegion) 19 | 20 | if err != nil { 21 | t.Fatalf("expect no error, got %v", err) 22 | } 23 | 24 | if e, a := expectRegion, region; e != a { 25 | t.Errorf("expect %s bucket region, got %s", e, a) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /service/s3/s3manager/shared_test.go: -------------------------------------------------------------------------------- 1 | package s3manager_test 2 | 3 | var buf12MB = make([]byte, 1024*1024*12) 4 | var buf2MB = make([]byte, 1024*1024*2) 5 | -------------------------------------------------------------------------------- /service/s3/statusok_error.go: -------------------------------------------------------------------------------- 1 | package s3 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "io/ioutil" 7 | "net/http" 8 | 9 | "github.com/IBM/ibm-cos-sdk-go/aws/awserr" 10 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 11 | "github.com/IBM/ibm-cos-sdk-go/internal/sdkio" 12 | ) 13 | 14 | func copyMultipartStatusOKUnmarshalError(r *request.Request) { 15 | b, err := ioutil.ReadAll(r.HTTPResponse.Body) 16 | r.HTTPResponse.Body.Close() 17 | if err != nil { 18 | r.Error = awserr.NewRequestFailure( 19 | awserr.New(request.ErrCodeSerialization, "unable to read response body", err), 20 | r.HTTPResponse.StatusCode, 21 | r.RequestID, 22 | ) 23 | // Note, some middleware later in the stack like restxml.Unmarshal expect a valid, non-closed Body 24 | // even in case of an error, so we replace it with an empty Reader. 25 | r.HTTPResponse.Body = ioutil.NopCloser(bytes.NewBuffer(nil)) 26 | return 27 | } 28 | 29 | body := bytes.NewReader(b) 30 | r.HTTPResponse.Body = ioutil.NopCloser(body) 31 | defer body.Seek(0, sdkio.SeekStart) 32 | 33 | unmarshalError(r) 34 | if err, ok := r.Error.(awserr.Error); ok && err != nil { 35 | if err.Code() == request.ErrCodeSerialization && 36 | err.OrigErr() != io.EOF { 37 | r.Error = nil 38 | return 39 | } 40 | // if empty payload 41 | if err.OrigErr() == io.EOF { 42 | r.HTTPResponse.StatusCode = http.StatusInternalServerError 43 | } else { 44 | r.HTTPResponse.StatusCode = http.StatusServiceUnavailable 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /service/s3/unmarshal_error_leak_test.go: -------------------------------------------------------------------------------- 1 | package s3 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | 7 | "github.com/IBM/ibm-cos-sdk-go/aws/request" 8 | "github.com/IBM/ibm-cos-sdk-go/awstesting" 9 | ) 10 | 11 | func TestUnmarhsalErrorLeak(t *testing.T) { 12 | req := &request.Request{ 13 | HTTPRequest: &http.Request{ 14 | Header: make(http.Header), 15 | Body: &awstesting.ReadCloser{Size: 2048}, 16 | }, 17 | } 18 | req.HTTPResponse = &http.Response{ 19 | Body: &awstesting.ReadCloser{Size: 2048}, 20 | Header: http.Header{ 21 | "X-Amzn-Requestid": []string{"1"}, 22 | }, 23 | StatusCode: http.StatusOK, 24 | } 25 | 26 | reader := req.HTTPResponse.Body.(*awstesting.ReadCloser) 27 | unmarshalError(req) 28 | 29 | if req.Error == nil { 30 | t.Error("expected an error, but received none") 31 | } 32 | 33 | if !reader.Closed { 34 | t.Error("expected reader to be closed") 35 | } 36 | 37 | if e, a := 0, reader.Size; e != a { 38 | t.Errorf("expected %d, but received %d", e, a) 39 | } 40 | } 41 | --------------------------------------------------------------------------------