From f7978cbb6d72e96000e0caf82d7290e659a95552 Mon Sep 17 00:00:00 2001 From: lzp0412 <641785844@qq.com> Date: Wed, 17 Jul 2019 13:01:38 +0800 Subject: [PATCH] 0.1.0 --- .gitignore | 1 - Gopkg.lock | 60 +- Gopkg.toml | 4 + README.md | 7 +- clients/client_factory.go | 8 +- clients/config_client/config_client.go | 89 +- clients/config_client/config_client_test.go | 39 +- clients/config_client/config_proxy.go | 28 +- clients/nacos_client/nacos_client.go | 7 +- clients/naming_client/beat_reactor.go | 91 +- clients/naming_client/host_reator.go | 21 + clients/naming_client/naming_client.go | 13 + .../naming_client/naming_client_interface.go | 3 + clients/naming_client/naming_proxy.go | 9 + common/constant/config.go | 4 + common/constant/const.go | 2 + common/constant/preserved_metadata_keys.go | 7 + common/http_agent/get.go | 3 + common/nacos_error/nacos_error.go | 32 +- common/nacos_server/nacos_server.go | 133 +- example/main/main.go | 1 - go.mod | 5 - go.sum | 7 - model/service.go | 4 + utils/common.go | 14 + .../aliyun/alibaba-cloud-sdk-go/LICENSE | 201 + .../sdk/auth/credential.go | 18 + .../auth/credentials/access_key_credential.go | 34 + .../credentials/bearer_token_credential.go | 12 + .../sdk/auth/credentials/ecs_ram_role.go | 29 + .../sdk/auth/credentials/provider/env.go | 30 + .../provider/instance_credentials.go | 92 + .../provider/profile_credentials.go | 158 + .../sdk/auth/credentials/provider/provider.go | 19 + .../credentials/provider/provider_chain.go | 34 + .../credentials/rsa_key_pair_credential.go | 15 + .../sdk/auth/credentials/sts_credential.go | 15 + .../credentials/sts_role_arn_credential.go | 61 + .../sdk/auth/roa_signature_composer.go | 136 + .../sdk/auth/rpc_signature_composer.go | 94 + .../alibaba-cloud-sdk-go/sdk/auth/signer.go | 98 + .../sdk/auth/signers/algorithms.go | 57 + .../sdk/auth/signers/credential_updater.go | 54 + .../sdk/auth/signers/session_credential.go | 7 + .../sdk/auth/signers/signer_access_key.go | 54 + .../sdk/auth/signers/signer_bearer_token.go | 35 + .../sdk/auth/signers/signer_ecs_ram_role.go | 167 + .../sdk/auth/signers/signer_key_pair.go | 148 + .../sdk/auth/signers/signer_ram_role_arn.go | 175 + .../sdk/auth/signers/signer_sts_token.go | 54 + .../sdk/auth/signers/signer_v2.go | 54 + .../aliyun/alibaba-cloud-sdk-go/sdk/client.go | 725 +++ .../aliyun/alibaba-cloud-sdk-go/sdk/config.go | 91 + .../sdk/endpoints/endpoints_config.go | 4126 +++++++++++++++++ .../sdk/endpoints/local_global_resolver.go | 43 + .../sdk/endpoints/local_regional_resolver.go | 48 + .../sdk/endpoints/location_resolver.go | 176 + .../sdk/endpoints/mapping_resolver.go | 48 + .../sdk/endpoints/resolver.go | 98 + .../sdk/endpoints/simple_host_resolver.go | 33 + .../sdk/errors/client_error.go | 92 + .../alibaba-cloud-sdk-go/sdk/errors/error.go | 23 + .../sdk/errors/server_error.go | 123 + .../signature_does_not_match_wrapper.go | 45 + .../aliyun/alibaba-cloud-sdk-go/sdk/logger.go | 116 + .../sdk/requests/acs_request.go | 378 ++ .../sdk/requests/common_request.go | 108 + .../sdk/requests/roa_request.go | 152 + .../sdk/requests/rpc_request.go | 79 + .../sdk/requests/types.go | 53 + .../sdk/responses/json_parser.go | 328 ++ .../sdk/responses/response.go | 152 + .../alibaba-cloud-sdk-go/sdk/utils/debug.go | 36 + .../alibaba-cloud-sdk-go/sdk/utils/utils.go | 141 + .../services/kms/cancel_key_deletion.go | 103 + .../services/kms/client.go | 81 + .../services/kms/create_alias.go | 104 + .../services/kms/create_key.go | 106 + .../services/kms/decrypt.go | 106 + .../services/kms/delete_alias.go | 103 + .../services/kms/delete_key_material.go | 103 + .../services/kms/describe_key.go | 104 + .../services/kms/describe_regions.go | 103 + .../services/kms/disable_key.go | 103 + .../services/kms/enable_key.go | 103 + .../services/kms/encrypt.go | 107 + .../services/kms/generate_data_key.go | 109 + .../services/kms/get_parameters_for_import.go | 109 + .../services/kms/import_key_material.go | 106 + .../services/kms/list_aliases.go | 108 + .../services/kms/list_aliases_by_key_id.go | 109 + .../services/kms/list_keys.go | 108 + .../services/kms/list_resource_tags.go | 104 + .../services/kms/schedule_key_deletion.go | 104 + .../services/kms/struct_alias.go | 23 + .../kms/struct_aliases_in_list_aliases.go | 21 + ...truct_aliases_in_list_aliases_by_key_id.go | 21 + .../services/kms/struct_key.go | 22 + .../services/kms/struct_key_metadata.go | 30 + .../services/kms/struct_keys.go | 21 + .../services/kms/struct_region.go | 21 + .../services/kms/struct_regions.go | 21 + .../services/kms/struct_tag.go | 23 + .../services/kms/struct_tags.go | 21 + .../services/kms/tag_resource.go | 104 + .../services/kms/untag_resource.go | 104 + .../services/kms/update_alias.go | 104 + .../jmespath/go-jmespath/.gitignore | 4 + .../jmespath/go-jmespath/.travis.yml | 9 + .../github.com/jmespath/go-jmespath/LICENSE | 13 + .../github.com/jmespath/go-jmespath/Makefile | 44 + .../github.com/jmespath/go-jmespath/README.md | 7 + vendor/github.com/jmespath/go-jmespath/api.go | 49 + .../go-jmespath/astnodetype_string.go | 16 + .../jmespath/go-jmespath/functions.go | 842 ++++ .../jmespath/go-jmespath/interpreter.go | 418 ++ .../github.com/jmespath/go-jmespath/lexer.go | 420 ++ .../github.com/jmespath/go-jmespath/parser.go | 603 +++ .../jmespath/go-jmespath/toktype_string.go | 16 + .../github.com/jmespath/go-jmespath/util.go | 185 + .../github.com/json-iterator/go/.codecov.yml | 3 + vendor/github.com/json-iterator/go/.gitignore | 4 + .../github.com/json-iterator/go/.travis.yml | 14 + vendor/github.com/json-iterator/go/Gopkg.lock | 21 + vendor/github.com/json-iterator/go/Gopkg.toml | 26 + vendor/github.com/json-iterator/go/LICENSE | 21 + vendor/github.com/json-iterator/go/README.md | 87 + vendor/github.com/json-iterator/go/adapter.go | 150 + vendor/github.com/json-iterator/go/any.go | 325 ++ .../github.com/json-iterator/go/any_array.go | 278 ++ .../github.com/json-iterator/go/any_bool.go | 137 + .../github.com/json-iterator/go/any_float.go | 83 + .../github.com/json-iterator/go/any_int32.go | 74 + .../github.com/json-iterator/go/any_int64.go | 74 + .../json-iterator/go/any_invalid.go | 82 + vendor/github.com/json-iterator/go/any_nil.go | 69 + .../github.com/json-iterator/go/any_number.go | 123 + .../github.com/json-iterator/go/any_object.go | 374 ++ vendor/github.com/json-iterator/go/any_str.go | 166 + .../github.com/json-iterator/go/any_uint32.go | 74 + .../github.com/json-iterator/go/any_uint64.go | 74 + vendor/github.com/json-iterator/go/build.sh | 12 + vendor/github.com/json-iterator/go/config.go | 375 ++ .../go/fuzzy_mode_convert_table.md | 7 + vendor/github.com/json-iterator/go/iter.go | 322 ++ .../github.com/json-iterator/go/iter_array.go | 58 + .../github.com/json-iterator/go/iter_float.go | 339 ++ .../github.com/json-iterator/go/iter_int.go | 345 ++ .../json-iterator/go/iter_object.go | 251 + .../github.com/json-iterator/go/iter_skip.go | 129 + .../json-iterator/go/iter_skip_sloppy.go | 144 + .../json-iterator/go/iter_skip_strict.go | 99 + .../github.com/json-iterator/go/iter_str.go | 215 + .../github.com/json-iterator/go/jsoniter.go | 18 + vendor/github.com/json-iterator/go/pool.go | 42 + vendor/github.com/json-iterator/go/reflect.go | 332 ++ .../json-iterator/go/reflect_array.go | 104 + .../json-iterator/go/reflect_dynamic.go | 70 + .../json-iterator/go/reflect_extension.go | 483 ++ .../json-iterator/go/reflect_json_number.go | 112 + .../go/reflect_json_raw_message.go | 60 + .../json-iterator/go/reflect_map.go | 338 ++ .../json-iterator/go/reflect_marshaler.go | 217 + .../json-iterator/go/reflect_native.go | 451 ++ .../json-iterator/go/reflect_optional.go | 133 + .../json-iterator/go/reflect_slice.go | 99 + .../go/reflect_struct_decoder.go | 1048 +++++ .../go/reflect_struct_encoder.go | 210 + vendor/github.com/json-iterator/go/stream.go | 211 + .../json-iterator/go/stream_float.go | 94 + .../github.com/json-iterator/go/stream_int.go | 190 + .../github.com/json-iterator/go/stream_str.go | 372 ++ vendor/github.com/json-iterator/go/test.sh | 12 + .../lestrrat/go-file-rotatelogs/.gitignore | 22 + .../lestrrat/go-file-rotatelogs/.travis.yml | 5 + .../lestrrat/go-file-rotatelogs/LICENSE | 20 + .../lestrrat/go-file-rotatelogs/README.md | 170 + .../lestrrat/go-file-rotatelogs/interface.go | 49 + .../lestrrat/go-file-rotatelogs/rotatelogs.go | 313 ++ .../lestrrat/go-strftime/.gitignore | 24 + .../lestrrat/go-strftime/.travis.yml | 5 + .../github.com/lestrrat/go-strftime/LICENSE | 21 + .../github.com/lestrrat/go-strftime/README.md | 155 + .../lestrrat/go-strftime/strftime.go | 219 + .../github.com/lestrrat/go-strftime/writer.go | 168 + .../modern-go/concurrent/.gitignore | 1 + .../modern-go/concurrent/.travis.yml | 14 + .../github.com/modern-go/concurrent/LICENSE | 201 + .../github.com/modern-go/concurrent/README.md | 49 + .../modern-go/concurrent/executor.go | 14 + .../modern-go/concurrent/go_above_19.go | 15 + .../modern-go/concurrent/go_below_19.go | 33 + vendor/github.com/modern-go/concurrent/log.go | 13 + .../github.com/modern-go/concurrent/test.sh | 12 + .../concurrent/unbounded_executor.go | 119 + .../github.com/modern-go/reflect2/.gitignore | 2 + .../github.com/modern-go/reflect2/.travis.yml | 15 + .../github.com/modern-go/reflect2/Gopkg.lock | 15 + .../github.com/modern-go/reflect2/Gopkg.toml | 35 + vendor/github.com/modern-go/reflect2/LICENSE | 201 + .../github.com/modern-go/reflect2/README.md | 71 + .../modern-go/reflect2/go_above_17.go | 8 + .../modern-go/reflect2/go_above_19.go | 14 + .../modern-go/reflect2/go_below_17.go | 9 + .../modern-go/reflect2/go_below_19.go | 14 + .../github.com/modern-go/reflect2/reflect2.go | 298 ++ .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 + .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 + .../github.com/modern-go/reflect2/safe_map.go | 101 + .../modern-go/reflect2/safe_slice.go | 92 + .../modern-go/reflect2/safe_struct.go | 29 + .../modern-go/reflect2/safe_type.go | 78 + vendor/github.com/modern-go/reflect2/test.sh | 12 + .../github.com/modern-go/reflect2/type_map.go | 103 + .../modern-go/reflect2/unsafe_array.go | 65 + .../modern-go/reflect2/unsafe_eface.go | 59 + .../modern-go/reflect2/unsafe_field.go | 74 + .../modern-go/reflect2/unsafe_iface.go | 64 + .../modern-go/reflect2/unsafe_link.go | 70 + .../modern-go/reflect2/unsafe_map.go | 138 + .../modern-go/reflect2/unsafe_ptr.go | 46 + .../modern-go/reflect2/unsafe_slice.go | 177 + .../modern-go/reflect2/unsafe_struct.go | 59 + .../modern-go/reflect2/unsafe_type.go | 85 + vendor/gopkg.in/ini.v1/.gitignore | 6 + vendor/gopkg.in/ini.v1/.travis.yml | 18 + vendor/gopkg.in/ini.v1/LICENSE | 191 + vendor/gopkg.in/ini.v1/Makefile | 15 + vendor/gopkg.in/ini.v1/README.md | 46 + vendor/gopkg.in/ini.v1/error.go | 34 + vendor/gopkg.in/ini.v1/file.go | 418 ++ vendor/gopkg.in/ini.v1/ini.go | 223 + vendor/gopkg.in/ini.v1/key.go | 753 +++ vendor/gopkg.in/ini.v1/parser.go | 487 ++ vendor/gopkg.in/ini.v1/section.go | 256 + vendor/gopkg.in/ini.v1/struct.go | 548 +++ vo/service_param.go | 6 + 246 files changed, 30612 insertions(+), 106 deletions(-) delete mode 100644 .gitignore create mode 100644 common/constant/preserved_metadata_keys.go delete mode 100644 go.mod delete mode 100644 go.sum create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/cancel_key_deletion.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/client.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_alias.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/decrypt.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_alias.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_key_material.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_regions.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/disable_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/enable_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/encrypt.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/generate_data_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/get_parameters_for_import.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/import_key_material.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases_by_key_id.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_keys.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_resource_tags.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/schedule_key_deletion.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_alias.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases_by_key_id.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key_metadata.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_keys.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_region.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_regions.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tag.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tags.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/tag_resource.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/untag_resource.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/update_alias.go create mode 100644 vendor/github.com/jmespath/go-jmespath/.gitignore create mode 100644 vendor/github.com/jmespath/go-jmespath/.travis.yml create mode 100644 vendor/github.com/jmespath/go-jmespath/LICENSE create mode 100644 vendor/github.com/jmespath/go-jmespath/Makefile create mode 100644 vendor/github.com/jmespath/go-jmespath/README.md create mode 100644 vendor/github.com/jmespath/go-jmespath/api.go create mode 100644 vendor/github.com/jmespath/go-jmespath/astnodetype_string.go create mode 100644 vendor/github.com/jmespath/go-jmespath/functions.go create mode 100644 vendor/github.com/jmespath/go-jmespath/interpreter.go create mode 100644 vendor/github.com/jmespath/go-jmespath/lexer.go create mode 100644 vendor/github.com/jmespath/go-jmespath/parser.go create mode 100644 vendor/github.com/jmespath/go-jmespath/toktype_string.go create mode 100644 vendor/github.com/jmespath/go-jmespath/util.go create mode 100644 vendor/github.com/json-iterator/go/.codecov.yml create mode 100644 vendor/github.com/json-iterator/go/.gitignore create mode 100644 vendor/github.com/json-iterator/go/.travis.yml create mode 100644 vendor/github.com/json-iterator/go/Gopkg.lock create mode 100644 vendor/github.com/json-iterator/go/Gopkg.toml create mode 100644 vendor/github.com/json-iterator/go/LICENSE create mode 100644 vendor/github.com/json-iterator/go/README.md create mode 100644 vendor/github.com/json-iterator/go/adapter.go create mode 100644 vendor/github.com/json-iterator/go/any.go create mode 100644 vendor/github.com/json-iterator/go/any_array.go create mode 100644 vendor/github.com/json-iterator/go/any_bool.go create mode 100644 vendor/github.com/json-iterator/go/any_float.go create mode 100644 vendor/github.com/json-iterator/go/any_int32.go create mode 100644 vendor/github.com/json-iterator/go/any_int64.go create mode 100644 vendor/github.com/json-iterator/go/any_invalid.go create mode 100644 vendor/github.com/json-iterator/go/any_nil.go create mode 100644 vendor/github.com/json-iterator/go/any_number.go create mode 100644 vendor/github.com/json-iterator/go/any_object.go create mode 100644 vendor/github.com/json-iterator/go/any_str.go create mode 100644 vendor/github.com/json-iterator/go/any_uint32.go create mode 100644 vendor/github.com/json-iterator/go/any_uint64.go create mode 100755 vendor/github.com/json-iterator/go/build.sh create mode 100644 vendor/github.com/json-iterator/go/config.go create mode 100644 vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md create mode 100644 vendor/github.com/json-iterator/go/iter.go create mode 100644 vendor/github.com/json-iterator/go/iter_array.go create mode 100644 vendor/github.com/json-iterator/go/iter_float.go create mode 100644 vendor/github.com/json-iterator/go/iter_int.go create mode 100644 vendor/github.com/json-iterator/go/iter_object.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_sloppy.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_strict.go create mode 100644 vendor/github.com/json-iterator/go/iter_str.go create mode 100644 vendor/github.com/json-iterator/go/jsoniter.go create mode 100644 vendor/github.com/json-iterator/go/pool.go create mode 100644 vendor/github.com/json-iterator/go/reflect.go create mode 100644 vendor/github.com/json-iterator/go/reflect_array.go create mode 100644 vendor/github.com/json-iterator/go/reflect_dynamic.go create mode 100644 vendor/github.com/json-iterator/go/reflect_extension.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_number.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_raw_message.go create mode 100644 vendor/github.com/json-iterator/go/reflect_map.go create mode 100644 vendor/github.com/json-iterator/go/reflect_marshaler.go create mode 100644 vendor/github.com/json-iterator/go/reflect_native.go create mode 100644 vendor/github.com/json-iterator/go/reflect_optional.go create mode 100644 vendor/github.com/json-iterator/go/reflect_slice.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_decoder.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_encoder.go create mode 100644 vendor/github.com/json-iterator/go/stream.go create mode 100644 vendor/github.com/json-iterator/go/stream_float.go create mode 100644 vendor/github.com/json-iterator/go/stream_int.go create mode 100644 vendor/github.com/json-iterator/go/stream_str.go create mode 100755 vendor/github.com/json-iterator/go/test.sh create mode 100644 vendor/github.com/lestrrat/go-file-rotatelogs/.gitignore create mode 100644 vendor/github.com/lestrrat/go-file-rotatelogs/.travis.yml create mode 100644 vendor/github.com/lestrrat/go-file-rotatelogs/LICENSE create mode 100644 vendor/github.com/lestrrat/go-file-rotatelogs/README.md create mode 100644 vendor/github.com/lestrrat/go-file-rotatelogs/interface.go create mode 100644 vendor/github.com/lestrrat/go-file-rotatelogs/rotatelogs.go create mode 100644 vendor/github.com/lestrrat/go-strftime/.gitignore create mode 100644 vendor/github.com/lestrrat/go-strftime/.travis.yml create mode 100644 vendor/github.com/lestrrat/go-strftime/LICENSE create mode 100644 vendor/github.com/lestrrat/go-strftime/README.md create mode 100644 vendor/github.com/lestrrat/go-strftime/strftime.go create mode 100644 vendor/github.com/lestrrat/go-strftime/writer.go create mode 100644 vendor/github.com/modern-go/concurrent/.gitignore create mode 100644 vendor/github.com/modern-go/concurrent/.travis.yml create mode 100644 vendor/github.com/modern-go/concurrent/LICENSE create mode 100644 vendor/github.com/modern-go/concurrent/README.md create mode 100644 vendor/github.com/modern-go/concurrent/executor.go create mode 100644 vendor/github.com/modern-go/concurrent/go_above_19.go create mode 100644 vendor/github.com/modern-go/concurrent/go_below_19.go create mode 100644 vendor/github.com/modern-go/concurrent/log.go create mode 100755 vendor/github.com/modern-go/concurrent/test.sh create mode 100644 vendor/github.com/modern-go/concurrent/unbounded_executor.go create mode 100644 vendor/github.com/modern-go/reflect2/.gitignore create mode 100644 vendor/github.com/modern-go/reflect2/.travis.yml create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.lock create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.toml create mode 100644 vendor/github.com/modern-go/reflect2/LICENSE create mode 100644 vendor/github.com/modern-go/reflect2/README.md create mode 100644 vendor/github.com/modern-go/reflect2/go_above_17.go create mode 100644 vendor/github.com/modern-go/reflect2/go_above_19.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_17.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_19.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_amd64.s create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_kind.go create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_386.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm64.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mips64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mipsx.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_s390x.s create mode 100644 vendor/github.com/modern-go/reflect2/safe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_type.go create mode 100755 vendor/github.com/modern-go/reflect2/test.sh create mode 100644 vendor/github.com/modern-go/reflect2/type_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_array.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_eface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_iface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_link.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_ptr.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_type.go create mode 100644 vendor/gopkg.in/ini.v1/.gitignore create mode 100644 vendor/gopkg.in/ini.v1/.travis.yml create mode 100644 vendor/gopkg.in/ini.v1/LICENSE create mode 100644 vendor/gopkg.in/ini.v1/Makefile create mode 100644 vendor/gopkg.in/ini.v1/README.md create mode 100644 vendor/gopkg.in/ini.v1/error.go create mode 100644 vendor/gopkg.in/ini.v1/file.go create mode 100644 vendor/gopkg.in/ini.v1/ini.go create mode 100644 vendor/gopkg.in/ini.v1/key.go create mode 100644 vendor/gopkg.in/ini.v1/parser.go create mode 100644 vendor/gopkg.in/ini.v1/section.go create mode 100644 vendor/gopkg.in/ini.v1/struct.go diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 9f11b755..00000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.idea/ diff --git a/Gopkg.lock b/Gopkg.lock index 236cd6e4..cff67273 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,6 +1,23 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. +[[projects]] + name = "github.com/aliyun/alibaba-cloud-sdk-go" + packages = [ + "sdk", + "sdk/auth", + "sdk/auth/credentials", + "sdk/auth/credentials/provider", + "sdk/auth/signers", + "sdk/endpoints", + "sdk/errors", + "sdk/requests", + "sdk/responses", + "sdk/utils", + "services/kms" + ] + revision = "e6958b522d6f315a3585561bca1f87f6a41fd0c3" + [[projects]] branch = "master" name = "github.com/buger/jsonparser" @@ -25,6 +42,41 @@ revision = "9fa652df1129bef0e734c9cf9bf6dbae9ef3b9fa" version = "1.3.1" +[[projects]] + name = "github.com/jmespath/go-jmespath" + packages = ["."] + revision = "c2b33e84" + +[[projects]] + name = "github.com/json-iterator/go" + packages = ["."] + revision = "0ff49de124c6f76f8494e194af75bde0f1a49a29" + version = "v1.1.6" + +[[projects]] + branch = "master" + name = "github.com/lestrrat/go-file-rotatelogs" + packages = ["."] + revision = "d3151e2a480fdcd05fb97102f5310a47d96274c4" + +[[projects]] + branch = "master" + name = "github.com/lestrrat/go-strftime" + packages = ["."] + revision = "ba3bf9c1d0421aa146564a632931730344f1f9f1" + +[[projects]] + name = "github.com/modern-go/concurrent" + packages = ["."] + revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" + version = "1.0.3" + +[[projects]] + name = "github.com/modern-go/reflect2" + packages = ["."] + revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" + version = "1.0.1" + [[projects]] name = "github.com/pkg/errors" packages = ["."] @@ -55,9 +107,15 @@ packages = ["semaphore"] revision = "a4371d70e3e308db0d5f90c2b1f5efaa84add725" +[[projects]] + name = "gopkg.in/ini.v1" + packages = ["."] + revision = "8659100d2d9ecf3760a41838b1886db49426d001" + version = "v1.44.0" + [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "40dd585edc77fad2a9636d1fc439a840d18f8eca529eebbabb679d681f4950ed" + inputs-digest = "5f9193892ff6610740b5d7993fe17737c26a52df0ed97a9ed0d4b662aa71455e" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index e2322bae..2a3873d4 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -49,6 +49,10 @@ branch = "master" name = "github.com/toolkits/concurrent" +[[constraint]] + name = "github.com/aliyun/alibaba-cloud-sdk-go" + revision = "e6958b522d6f315a3585561bca1f87f6a41fd0c3" + [prune] go-tests = true unused-packages = true diff --git a/README.md b/README.md index 055bdd9e..ca592cd9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ - -# nacos-sdk-go - +## nacos-go go语言版本的nacos client,支持服务发现和配置管理 ### 客户端配置 @@ -225,5 +223,4 @@ configClient.ListenConfig(vo.ConfigParam{ }, }) -``` - +``` \ No newline at end of file diff --git a/clients/client_factory.go b/clients/client_factory.go index 28324090..61a62c35 100644 --- a/clients/client_factory.go +++ b/clients/client_factory.go @@ -69,8 +69,12 @@ func setConfig(properties map[string]interface{}) (iClient nacos_client.INacosCl } } } else { - err = errors.New("server configs not found in properties") - return + clientConfig, _ := client.GetClientConfig() + if len(clientConfig.Endpoint) <= 0 { + err = errors.New("server configs not found in properties") + return + } + client.SetServerConfig([]constant.ServerConfig{}) } iClient = &client diff --git a/clients/config_client/config_client.go b/clients/config_client/config_client.go index 780f5224..0553e1e6 100644 --- a/clients/config_client/config_client.go +++ b/clients/config_client/config_client.go @@ -11,6 +11,8 @@ import ( "github.com/nacos-group/nacos-sdk-go/common/util" "github.com/nacos-group/nacos-sdk-go/utils" "github.com/nacos-group/nacos-sdk-go/vo" + + "github.com/aliyun/alibaba-cloud-sdk-go/services/kms" "io/ioutil" "log" "net/http" @@ -23,6 +25,7 @@ import ( type ConfigClient struct { nacos_client.INacosClient + kmsClient *kms.Client localConfigs []vo.ConfigParam mutex sync.Mutex configProxy ConfigProxy @@ -50,6 +53,14 @@ func NewConfigClient(nc nacos_client.INacosClient) (ConfigClient, error) { } config.configCacheDir = clientConfig.CacheDir + string(os.PathSeparator) + "config" config.configProxy, err = NewConfigProxy(serverConfig, clientConfig, httpAgent) + if clientConfig.OpenKMS { + kmsClient, err := kms.NewClientWithAccessKey(clientConfig.RegionId, clientConfig.AccessKey, clientConfig.SecretKey) + if err != nil { + return config, err + } + config.kmsClient = kmsClient + } + return config, err } @@ -75,29 +86,65 @@ func (client *ConfigClient) sync() (clientConfig constant.ClientConfig, } func (client *ConfigClient) GetConfig(param vo.ConfigParam) (content string, err error) { + content, err = client.getConfigInner(param) + + if err != nil { + return "", err + } + + return client.decrypt(param.DataId, content) +} + +func (client *ConfigClient) decrypt(dataId, content string) (string, error) { + if strings.HasPrefix(dataId, "cipher-") && client.kmsClient != nil { + request := kms.CreateDecryptRequest() + request.Method = "POST" + request.Scheme = "https" + request.AcceptFormat = "json" + request.CiphertextBlob = content + response, err := client.kmsClient.Decrypt(request) + if err != nil { + return "", errors.New("ksm decrypt failed") + } + content = response.Plaintext + } + + return content, nil +} + +func (client *ConfigClient) getConfigInner(param vo.ConfigParam) (content string, err error) { if len(param.DataId) <= 0 { err = errors.New("[client.GetConfig] param.dataId can not be empty") } if len(param.Group) <= 0 { err = errors.New("[client.GetConfig] param.group can not be empty") } - clientConfig, _ := client.GetClientConfig() cacheKey := utils.GetConfigCacheKey(param.DataId, param.Group, clientConfig.NamespaceId) - content, err = client.configProxy.GetConfigProxy(param, clientConfig.NamespaceId) + content, err = client.configProxy.GetConfigProxy(param, clientConfig.NamespaceId, clientConfig.AccessKey, clientConfig.SecretKey) + if err != nil { log.Printf("[ERROR] get config from server error:%s ", err.Error()) + if _, ok := err.(*nacos_error.NacosError); ok { + nacosErr := err.(*nacos_error.NacosError) + if nacosErr.ErrorCode() == "404" { + cache.WriteConfigToFile(cacheKey, client.configCacheDir, "") + return "", errors.New("config not found") + } + if nacosErr.ErrorCode() == "403" { + return "", errors.New("get config forbidden") + } + } content, err = cache.ReadConfigFromFile(cacheKey, client.configCacheDir) if err != nil { log.Printf("[ERROR] get config from cache error:%s ", err.Error()) return "", errors.New("read config from both server and cache fail") } - return content, nil + } else { cache.WriteConfigToFile(cacheKey, client.configCacheDir, content) - return content, nil } - + return content, nil } func (client *ConfigClient) PublishConfig(param vo.ConfigParam) (published bool, @@ -112,7 +159,7 @@ func (client *ConfigClient) PublishConfig(param vo.ConfigParam) (published bool, err = errors.New("[client.PublishConfig] param.content can not be empty") } clientConfig, _ := client.GetClientConfig() - return client.configProxy.PublishConfigProxy(param, clientConfig.NamespaceId) + return client.configProxy.PublishConfigProxy(param, clientConfig.NamespaceId, clientConfig.AccessKey, clientConfig.SecretKey) } func (client *ConfigClient) DeleteConfig(param vo.ConfigParam) (deleted bool, @@ -125,7 +172,7 @@ func (client *ConfigClient) DeleteConfig(param vo.ConfigParam) (deleted bool, } clientConfig, _ := client.GetClientConfig() - return client.configProxy.DeleteConfigProxy(param, clientConfig.NamespaceId) + return client.configProxy.DeleteConfigProxy(param, clientConfig.NamespaceId, clientConfig.AccessKey, clientConfig.SecretKey) } func (client *ConfigClient) AddConfigToListen(params []vo.ConfigParam) (err error) { @@ -196,15 +243,21 @@ func (client *ConfigClient) listenConfigTask(clientConfig constant.ClientConfig, if len(param.Content) > 0 { md5 = util.Md5(param.Content) } - listeningConfigs += param.DataId + constant.SPLIT_CONFIG_INNER + param.Group + constant.SPLIT_CONFIG_INNER + - md5 + constant.SPLIT_CONFIG_INNER + tenant + constant.SPLIT_CONFIG - client.mutex.Unlock() + if len(tenant) > 0 { + listeningConfigs += param.DataId + constant.SPLIT_CONFIG_INNER + param.Group + constant.SPLIT_CONFIG_INNER + + md5 + constant.SPLIT_CONFIG_INNER + tenant + constant.SPLIT_CONFIG + } else { + listeningConfigs += param.DataId + constant.SPLIT_CONFIG_INNER + param.Group + constant.SPLIT_CONFIG_INNER + + md5 + constant.SPLIT_CONFIG + } + client.mutex.Unlock() // http 请求 params := make(map[string]string) params[constant.KEY_LISTEN_CONFIGS] = listeningConfigs var changed string - for _, serverConfig := range serverConfigs { + + for _, serverConfig := range client.configProxy.GetServerList() { path := client.buildBasePath(serverConfig) + "/listener" changedTmp, err := listen(agent, path, clientConfig.TimeoutMs, clientConfig.ListenInterval, params) if err == nil { @@ -247,9 +300,7 @@ func listen(agent http_agent.IHttpAgent, path string, if response.StatusCode == 200 { changed = string(bytes) } else { - err = &nacos_error.NacosError{ - ErrMsg: "[" + strconv.Itoa(response.StatusCode) + "]" + string(bytes), - } + err = nacos_error.NewNacosError(strconv.Itoa(response.StatusCode), string(bytes), nil) } } } @@ -263,7 +314,7 @@ func (client *ConfigClient) updateLocalConfig(changed string, param vo.ConfigPar for _, config := range changedConfigs { attrs := strings.Split(config, "%02") if len(attrs) == 2 { - content, err := client.GetConfig(vo.ConfigParam{ + content, err := client.getConfigInner(vo.ConfigParam{ DataId: attrs[0], Group: attrs[1], }) @@ -277,11 +328,12 @@ func (client *ConfigClient) updateLocalConfig(changed string, param vo.ConfigPar }) // call listener: - param.OnChange("", attrs[1], attrs[0], content) + decrept, _ := client.decrypt(attrs[0], content) + param.OnChange("", attrs[1], attrs[0], decrept) } } else if len(attrs) == 3 { - content, err := client.GetConfig(vo.ConfigParam{ + content, err := client.getConfigInner(vo.ConfigParam{ DataId: attrs[0], Group: attrs[1], }) @@ -295,7 +347,8 @@ func (client *ConfigClient) updateLocalConfig(changed string, param vo.ConfigPar }) // call listener: - param.OnChange(attrs[2], attrs[1], attrs[0], content) + decrept, _ := client.decrypt(attrs[0], content) + param.OnChange(attrs[2], attrs[1], attrs[0], decrept) } } } diff --git a/clients/config_client/config_client_test.go b/clients/config_client/config_client_test.go index ea464dba..43326475 100644 --- a/clients/config_client/config_client_test.go +++ b/clients/config_client/config_client_test.go @@ -134,7 +134,7 @@ func Test_GetConfig(t *testing.T) { assert.Equal(t, "hello world!222222", content) } -func Test_GetConfigWithErrorResponse(t *testing.T) { +func Test_GetConfigWithErrorResponse_401(t *testing.T) { controller := gomock.NewController(t) defer controller.Finish() mockHttpAgent := mock.NewMockIHttpAgent(controller) @@ -145,8 +145,43 @@ func Test_GetConfigWithErrorResponse(t *testing.T) { gomock.Eq(clientConfigTest.TimeoutMs), gomock.Eq(configParamMapTest), ).Times(3).Return(http_agent.FakeHttpResponse(401, "no auth"), nil) - _, err := client.GetConfig(configParamTest) + result, err := client.GetConfig(configParamTest) + assert.Nil(t, err) + fmt.Printf("result:%s \n", result) +} + +func Test_GetConfigWithErrorResponse_404(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + mockHttpAgent := mock.NewMockIHttpAgent(controller) + client := cretateConfigClientHttpTest(mockHttpAgent) + mockHttpAgent.EXPECT().Request(gomock.Eq(http.MethodGet), + gomock.Eq("http://console.nacos.io:80/nacos/v1/cs/configs"), + gomock.AssignableToTypeOf(http.Header{}), + gomock.Eq(clientConfigTest.TimeoutMs), + gomock.Eq(configParamMapTest), + ).Times(3).Return(http_agent.FakeHttpResponse(404, ""), nil) + reslut, err := client.GetConfig(configParamTest) + assert.NotNil(t, err) + assert.Equal(t, "", reslut) + fmt.Println(err.Error()) +} + +func Test_GetConfigWithErrorResponse_403(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + mockHttpAgent := mock.NewMockIHttpAgent(controller) + client := cretateConfigClientHttpTest(mockHttpAgent) + mockHttpAgent.EXPECT().Request(gomock.Eq(http.MethodGet), + gomock.Eq("http://console.nacos.io:80/nacos/v1/cs/configs"), + gomock.AssignableToTypeOf(http.Header{}), + gomock.Eq(clientConfigTest.TimeoutMs), + gomock.Eq(configParamMapTest), + ).Times(3).Return(http_agent.FakeHttpResponse(403, ""), nil) + reslut, err := client.GetConfig(configParamTest) assert.NotNil(t, err) + assert.Equal(t, "", reslut) + fmt.Println(err.Error()) } func Test_GetConfigWithCache(t *testing.T) { diff --git a/clients/config_client/config_proxy.go b/clients/config_client/config_proxy.go index ffc43bfc..f09053cd 100644 --- a/clients/config_client/config_proxy.go +++ b/clients/config_client/config_proxy.go @@ -23,21 +23,34 @@ func NewConfigProxy(serverConfig []constant.ServerConfig, clientConfig constant. } -func (cp *ConfigProxy) GetConfigProxy(param vo.ConfigParam, tenant string) (string, error) { +func (cp *ConfigProxy) GetServerList() []constant.ServerConfig { + return cp.nacosServer.GetServerList() +} + +func (cp *ConfigProxy) GetConfigProxy(param vo.ConfigParam, tenant, accessKey, secretKey string) (string, error) { params := util.TransformObject2Param(param) if len(tenant) > 0 { params["tenant"] = tenant } - result, err := cp.nacosServer.ReqApi(constant.CONFIG_PATH, params, http.MethodGet) + + var headers = map[string]string{} + headers["accessKey"] = accessKey + headers["secretKey"] = secretKey + + result, err := cp.nacosServer.ReqConfigApi(constant.CONFIG_PATH, params, headers, http.MethodGet) return result, err } -func (cp *ConfigProxy) PublishConfigProxy(param vo.ConfigParam, tenant string) (bool, error) { +func (cp *ConfigProxy) PublishConfigProxy(param vo.ConfigParam, tenant, accessKey, secretKey string) (bool, error) { params := util.TransformObject2Param(param) if len(tenant) > 0 { params["tenant"] = tenant } - result, err := cp.nacosServer.ReqApi(constant.CONFIG_PATH, params, http.MethodPost) + + var headers = map[string]string{} + headers["accessKey"] = accessKey + headers["secretKey"] = secretKey + result, err := cp.nacosServer.ReqConfigApi(constant.CONFIG_PATH, params, headers, http.MethodPost) if err != nil { return false, errors.New("[client.PublishConfig] publish config failed:" + err.Error()) } @@ -48,12 +61,15 @@ func (cp *ConfigProxy) PublishConfigProxy(param vo.ConfigParam, tenant string) ( } } -func (cp *ConfigProxy) DeleteConfigProxy(param vo.ConfigParam, tenant string) (bool, error) { +func (cp *ConfigProxy) DeleteConfigProxy(param vo.ConfigParam, tenant, accessKey, secretKey string) (bool, error) { params := util.TransformObject2Param(param) if len(tenant) > 0 { params["tenant"] = tenant } - result, err := cp.nacosServer.ReqApi(constant.CONFIG_PATH, params, http.MethodDelete) + var headers = map[string]string{} + headers["accessKey"] = accessKey + headers["secretKey"] = secretKey + result, err := cp.nacosServer.ReqConfigApi(constant.CONFIG_PATH, params, headers, http.MethodDelete) if err != nil { return false, errors.New("[client.DeleteConfig] deleted config failed:" + err.Error()) } diff --git a/clients/nacos_client/nacos_client.go b/clients/nacos_client/nacos_client.go index ecb8a8f3..731719e8 100644 --- a/clients/nacos_client/nacos_client.go +++ b/clients/nacos_client/nacos_client.go @@ -33,8 +33,8 @@ func (client *NacosClient) SetClientConfig(config constant.ClientConfig) (err er err = errors.New("[client.SetClientConfig] config.TimeoutMs should > 0") return } - if config.TimeoutMs <= config.ListenInterval { - err = errors.New("[client.SetClientConfig] config.TimeoutMs should > config.ListenInterval") + if config.TimeoutMs >= config.ListenInterval { + err = errors.New("[client.SetClientConfig] config.TimeoutMs should < config.ListenInterval") return } @@ -65,7 +65,8 @@ func (client *NacosClient) SetClientConfig(config constant.ClientConfig) (err er // 设置 serverConfigs func (client *NacosClient) SetServerConfig(configs []constant.ServerConfig) (err error) { if len(configs) <= 0 { - err = errors.New("[client.SetServerConfig] configs can not be empty") + client.serverConfigsValid = true + //err = errors.New("[client.SetServerConfig] configs can not be empty") return } diff --git a/clients/naming_client/beat_reactor.go b/clients/naming_client/beat_reactor.go index 4942f505..493cb865 100644 --- a/clients/naming_client/beat_reactor.go +++ b/clients/naming_client/beat_reactor.go @@ -12,14 +12,15 @@ import ( ) type BeatReactor struct { - beatMap cache.ConcurrentMap - serviceProxy NamingProxy - clientBeatInterval int64 - beatThreadCount int - beatRecordMap cache.ConcurrentMap + beatMap cache.ConcurrentMap + serviceProxy NamingProxy + clientBeatInterval int64 + beatThreadCount int + beatThreadSemaphore *nsema.Semaphore + beatRecordMap cache.ConcurrentMap } -const Default_Bead_Thread_Num = 20 +const Default_Beat_Thread_Num = 20 func NewBeatReactor(serviceProxy NamingProxy, clientBeatInterval int64) BeatReactor { br := BeatReactor{} @@ -29,9 +30,9 @@ func NewBeatReactor(serviceProxy NamingProxy, clientBeatInterval int64) BeatReac br.beatMap = cache.NewConcurrentMap() br.serviceProxy = serviceProxy br.clientBeatInterval = clientBeatInterval - br.beatThreadCount = Default_Bead_Thread_Num + br.beatThreadCount = Default_Beat_Thread_Num br.beatRecordMap = cache.NewConcurrentMap() - go br.sendBeat() + br.beatThreadSemaphore = nsema.NewSemaphore(br.beatThreadCount) return br } @@ -41,51 +42,49 @@ func buildKey(serviceName string, ip string, port uint64) string { func (br *BeatReactor) AddBeatInfo(serviceName string, beatInfo model.BeatInfo) { log.Printf("[INFO] adding beat: <%s> to beat map.\n", utils.ToJsonString(beatInfo)) - br.beatMap.Set(buildKey(serviceName, beatInfo.Ip, beatInfo.Port), beatInfo) + k := buildKey(serviceName, beatInfo.Ip, beatInfo.Port) + br.beatMap.Set(k, beatInfo) + go br.sendInstanceBeat(k, &beatInfo) } func (br *BeatReactor) RemoveBeatInfo(serviceName string, ip string, port uint64) { log.Printf("[INFO] remove beat: %s@%s:%d from beat map.\n", serviceName, ip, port) - br.beatMap.Remove(buildKey(serviceName, ip, port)) + k := buildKey(serviceName, ip, port) + data, exist := br.beatMap.Get(k) + if exist { + beatInfo := data.(*model.BeatInfo) + beatInfo.Stopped = true + } + br.beatMap.Remove(k) } -func (br *BeatReactor) sendBeat() { - sema := nsema.NewSemaphore(br.beatThreadCount) +func (br *BeatReactor) sendInstanceBeat(k string, beatInfo *model.BeatInfo) { for { - if br.beatMap.Count() > 0 { - for k, item := range br.beatMap.Items() { - var lastBeatTime int64 - beatInfo := item.(model.BeatInfo) - store, ok := br.beatRecordMap.Get(k) - if !ok { - lastBeatTime = 0 - } else { - lastBeatTime = store.(int64) - } - if utils.CurrentMillis()-lastBeatTime > br.clientBeatInterval && !beatInfo.Scheduled { - sema.Acquire() - beatInfo.Scheduled = true - br.beatMap.Set(k, beatInfo) - go func(k string, beatInfo model.BeatInfo) { - defer sema.Release() - beatInterval, err := br.serviceProxy.SendBeat(beatInfo) - if err != nil { - log.Printf("[ERROR]:beat to server return error:%s \n", err.Error()) - beatInfo.Scheduled = false - br.beatMap.Set(k, beatInfo) - return - } - if beatInterval > 0 { - br.clientBeatInterval = beatInterval - } - beatInfo.Scheduled = false - br.beatMap.Set(k, beatInfo) - br.beatRecordMap.Set(k, utils.CurrentMillis()) - }(k, beatInfo) - } - } + br.beatThreadSemaphore.Acquire() + //进行心跳通信 + beatInterval, err := br.serviceProxy.SendBeat(*beatInfo) + if err != nil { + log.Printf("[ERROR]:beat to server return error:%s \n", err.Error()) + br.beatThreadSemaphore.Release() + t := time.NewTimer(beatInfo.Period) + <-t.C + continue + } + if beatInterval > 0 { + beatInfo.Period = time.Duration(time.Millisecond.Nanoseconds() * beatInterval) } - time.Sleep(200 * time.Millisecond) - } + //如果当前实例注销,则进行停止心跳 + if beatInfo.Stopped { + log.Printf("[INFO] intance[%s] stop heartBeating\n", k) + br.beatThreadSemaphore.Release() + return + } + + br.beatRecordMap.Set(k, utils.CurrentMillis()) + br.beatThreadSemaphore.Release() + + t := time.NewTimer(beatInfo.Period) + <-t.C + } } diff --git a/clients/naming_client/host_reator.go b/clients/naming_client/host_reator.go index bee23daf..1839a3bd 100644 --- a/clients/naming_client/host_reator.go +++ b/clients/naming_client/host_reator.go @@ -1,6 +1,7 @@ package naming_client import ( + "encoding/json" "github.com/nacos-group/nacos-sdk-go/clients/cache" "github.com/nacos-group/nacos-sdk-go/model" "github.com/nacos-group/nacos-sdk-go/utils" @@ -96,6 +97,26 @@ func (hr *HostReactor) GetServiceInfo(serviceName string, clusters string) model return newService.(model.Service) } +func (hr *HostReactor) GetAllServiceInfo(nameSpace string, groupName string, clusters string) []model.Service { + result, err := hr.serviceProxy.GetAllServiceInfoList(nameSpace, groupName, clusters) + if err != nil { + log.Printf("[ERROR]:query all services info return error!nameSpace:%s cluster:%s groupName:%s err:%s \n", nameSpace, clusters, groupName, err.Error()) + return nil + } + if result == "" { + log.Printf("[ERROR]:query all services info is empty!nameSpace:%s cluster:%s groupName:%s \n", nameSpace, clusters, groupName) + return nil + } + + var data []model.Service + err = json.Unmarshal([]byte(result), &data) + if err != nil { + log.Printf("[ERROR]: the result of quering all services info json.Unmarshal error !nameSpace:%s cluster:%s groupName:%s \n", nameSpace, clusters, groupName) + return nil + } + return data +} + func (hr *HostReactor) updateServiceNow(serviceName string, clusters string) { result, err := hr.serviceProxy.QueryList(serviceName, clusters, hr.pushReceiver.port, false) if err != nil { diff --git a/clients/naming_client/naming_client.go b/clients/naming_client/naming_client.go index f24f8f7d..93833eb7 100644 --- a/clients/naming_client/naming_client.go +++ b/clients/naming_client/naming_client.go @@ -13,6 +13,7 @@ import ( "math/rand" "os" "strings" + "time" ) type NamingClient struct { @@ -78,6 +79,7 @@ func (sc *NamingClient) RegisterInstance(param vo.RegisterInstanceParam) (bool, ServiceName: utils.GetGroupName(param.ServiceName, param.GroupName), Cluster: param.ClusterName, Weight: param.Weight, + Period: utils.GetDurationWithDefault(param.Metadata, constant.HEART_BEAT_INTERVAL, time.Second*5), } _, err := sc.serviceProxy.RegisterInstance(utils.GetGroupName(param.ServiceName, param.GroupName), param.GroupName, instance) if err != nil { @@ -112,6 +114,17 @@ func (sc *NamingClient) GetService(param vo.GetServiceParam) (model.Service, err return service, nil } +func (sc *NamingClient) GetAllServicesInfo(param vo.GetAllServiceInfoParam) ([]model.Service, error) { + if param.GroupName == "" { + param.GroupName = constant.DEFAULT_GROUP + } + if param.NameSpace == "" { + param.NameSpace = constant.DEFAULT_NAMESPACE_ID + } + service := sc.hostReactor.GetAllServiceInfo(param.NameSpace, param.GroupName, strings.Join(param.Clusters, ",")) + return service, nil +} + func (sc *NamingClient) SelectAllInstances(param vo.SelectAllInstancesParam) ([]model.Instance, error) { if param.GroupName == "" { param.GroupName = constant.DEFAULT_GROUP diff --git a/clients/naming_client/naming_client_interface.go b/clients/naming_client/naming_client_interface.go index 1058118c..8f86e423 100644 --- a/clients/naming_client/naming_client_interface.go +++ b/clients/naming_client/naming_client_interface.go @@ -33,4 +33,7 @@ type INamingClient interface { Subscribe(param *vo.SubscribeParam) error //取消监听 Unsubscribe(param *vo.SubscribeParam) error + + //获取全部服务信息 + GetAllServicesInfo(param vo.GetAllServiceInfoParam) ([]model.Service, error) } diff --git a/clients/naming_client/naming_proxy.go b/clients/naming_client/naming_proxy.go index cf3a6f79..eeb9cf59 100644 --- a/clients/naming_client/naming_proxy.go +++ b/clients/naming_client/naming_proxy.go @@ -155,3 +155,12 @@ func (proxy *NamingProxy) QueryList(serviceName string, clusters string, udpPort api := constant.SERVICE_PATH + "/list" return proxy.nacosServer.ReqApi(api, param, http.MethodGet) } + +func (proxy *NamingProxy) GetAllServiceInfoList(namespace string, groupName string, clusters string) (string, error) { + param := make(map[string]string) + param["namespaceId"] = proxy.clientConfig.NamespaceId + param["clusters"] = clusters + param["groupName"] = groupName + api := constant.SERVICE_INFO_PATH + "/getAll" + return proxy.nacosServer.ReqApi(api, param, http.MethodGet) +} diff --git a/common/constant/config.go b/common/constant/config.go index a77bb592..e9d64967 100644 --- a/common/constant/config.go +++ b/common/constant/config.go @@ -21,9 +21,13 @@ type ClientConfig struct { BeatInterval int64 NamespaceId string Endpoint string + AccessKey string + SecretKey string CacheDir string LogDir string UpdateThreadNum int NotLoadCacheAtStart bool UpdateCacheWhenEmpty bool + OpenKMS bool + RegionId string } diff --git a/common/constant/const.go b/common/constant/const.go index 620ce666..1c5d6673 100644 --- a/common/constant/const.go +++ b/common/constant/const.go @@ -33,6 +33,7 @@ const ( CONFIG_LISTEN_PATH = CONFIG_BASE_PATH + "/configs/listener" SERVICE_BASE_PATH = "/v1/ns" SERVICE_PATH = SERVICE_BASE_PATH + "/instance" + SERVICE_INFO_PATH = SERVICE_BASE_PATH + "/service" SERVICE_SUBSCRIBE_PATH = SERVICE_PATH + "/list" NAMESPACE_PATH = "/v1/console/namespaces" SPLIT_CONFIG = string(rune(1)) @@ -57,4 +58,5 @@ const ( DEFAULT_NAMESPACE_ID = "public" DEFAULT_GROUP = "DEFAULT_GROUP" NAMING_INSTANCE_ID_SPLITTER = "#" + DefaultClientErrorCode = "SDK.NacosError" ) diff --git a/common/constant/preserved_metadata_keys.go b/common/constant/preserved_metadata_keys.go new file mode 100644 index 00000000..14dd9d56 --- /dev/null +++ b/common/constant/preserved_metadata_keys.go @@ -0,0 +1,7 @@ +package constant + +const ( + HEART_BEAT_TIMEOUT = "preserved.heart.beat.timeout" + IP_DELETE_TIMEOUT = "preserved.ip.delete.timeout" + HEART_BEAT_INTERVAL = "preserved.heart.beat.interval" +) diff --git a/common/http_agent/get.go b/common/http_agent/get.go index 4c3d65a9..bf0fc82d 100644 --- a/common/http_agent/get.go +++ b/common/http_agent/get.go @@ -19,12 +19,14 @@ func get(path string, header http.Header, timeoutMs uint64, params map[string]st if !strings.HasSuffix(path, "?") { path = path + "?" } + for key, value := range params { path = path + key + "=" + value + "&" } if strings.HasSuffix(path, "&") { path = path[:len(path)-1] } + client := http.Client{} client.Timeout = time.Millisecond * time.Duration(timeoutMs) request, errNew := http.NewRequest(http.MethodGet, path, nil) @@ -34,6 +36,7 @@ func get(path string, header http.Header, timeoutMs uint64, params map[string]st } request.Header = header resp, errDo := client.Do(request) + if errDo != nil { err = errDo } else { diff --git a/common/nacos_error/nacos_error.go b/common/nacos_error/nacos_error.go index 5919a7c5..d04fc328 100644 --- a/common/nacos_error/nacos_error.go +++ b/common/nacos_error/nacos_error.go @@ -1,5 +1,10 @@ package nacos_error +import ( + "fmt" + "github.com/nacos-group/nacos-sdk-go/common/constant" +) + /** * * @description : @@ -10,9 +15,32 @@ package nacos_error **/ type NacosError struct { - ErrMsg string + errorCode string + errMsg string + originError error +} + +func NewNacosError(errorCode string, errMsg string, originError error) *NacosError { + return &NacosError{ + errorCode: errorCode, + errMsg: errMsg, + originError: originError, + } + } func (err *NacosError) Error() (str string) { - return err.ErrMsg + nacosErrMsg := fmt.Sprintf("[%s] %s", err.ErrorCode(), err.errMsg) + if err.originError != nil { + return nacosErrMsg + "\ncaused by:\n" + err.originError.Error() + } + return nacosErrMsg +} + +func (err *NacosError) ErrorCode() string { + if err.errorCode == "" { + return constant.DefaultClientErrorCode + } else { + return err.errorCode + } } diff --git a/common/nacos_server/nacos_server.go b/common/nacos_server/nacos_server.go index ae8f5602..185fddf2 100644 --- a/common/nacos_server/nacos_server.go +++ b/common/nacos_server/nacos_server.go @@ -1,10 +1,14 @@ package nacos_server import ( + "crypto/hmac" + "crypto/sha1" + "encoding/base64" "errors" "fmt" "github.com/nacos-group/nacos-sdk-go/common/constant" "github.com/nacos-group/nacos-sdk-go/common/http_agent" + "github.com/nacos-group/nacos-sdk-go/common/nacos_error" "github.com/nacos-group/nacos-sdk-go/utils" "github.com/satori/go.uuid" "io/ioutil" @@ -43,10 +47,52 @@ func NewNacosServer(serverList []constant.ServerConfig, httpAgent http_agent.IHt return ns, nil } +func (server *NacosServer) callConfigServer(api string, params map[string]string, newHeaders map[string]string, method string, curServer string, contextPath string) (result string, err error) { + if contextPath == "" { + contextPath = constant.WEB_CONTEXT + } + + signHeaders := getSignHeaders(params, newHeaders) + + url := "http://" + curServer + contextPath + api + headers := map[string][]string{} + headers["Client-Version"] = []string{constant.CLIENT_VERSION} + headers["User-Agent"] = []string{constant.CLIENT_VERSION} + //headers["Accept-Encoding"] = []string{"gzip,deflate,sdch"} + headers["Connection"] = []string{"Keep-Alive"} + headers["exConfigInfo"] = []string{"true"} + headers["RequestId"] = []string{uuid.NewV4().String()} + headers["Request-Module"] = []string{"Naming"} + headers["Content-Type"] = []string{"application/x-www-form-urlencoded;charset=GBK"} + headers["Spas-AccessKey"] = []string{newHeaders["accessKey"]} + headers["Timestamp"] = []string{signHeaders["timeStamp"]} + headers["Spas-Signature"] = []string{signHeaders["Spas-Signature"]} + + var response *http.Response + response, err = server.httpAgent.Request(method, url, headers, server.timeoutMs, params) + if err != nil { + return + } + var bytes []byte + bytes, err = ioutil.ReadAll(response.Body) + defer response.Body.Close() + if err != nil { + return + } + result = string(bytes) + if response.StatusCode == 200 { + return + } else { + err = nacos_error.NewNacosError(strconv.Itoa(response.StatusCode), string(bytes), nil) + return + } +} + func (server *NacosServer) callServer(api string, params map[string]string, method string, curServer string, contextPath string) (result string, err error) { if contextPath == "" { contextPath = constant.WEB_CONTEXT } + url := "http://" + curServer + contextPath + api headers := map[string][]string{} headers["Client-Version"] = []string{constant.CLIENT_VERSION} @@ -55,7 +101,8 @@ func (server *NacosServer) callServer(api string, params map[string]string, meth headers["Connection"] = []string{"Keep-Alive"} headers["RequestId"] = []string{uuid.NewV4().String()} headers["Request-Module"] = []string{"Naming"} - headers["Content-Type"] = []string{"application/x-www-form-urlencoded"} + headers["Content-Type"] = []string{"application/x-www-form-urlencoded;charset=GBK"} + var response *http.Response response, err = server.httpAgent.Request(method, url, headers, server.timeoutMs, params) if err != nil { @@ -76,6 +123,38 @@ func (server *NacosServer) callServer(api string, params map[string]string, meth } } +func (server *NacosServer) ReqConfigApi(api string, params map[string]string, headers map[string]string, method string) (string, error) { + srvs := server.serverList + if srvs == nil || len(srvs) == 0 { + return "", errors.New("server list is empty") + } + //only one server,retry request when error + var err error + var result string + if len(srvs) == 1 { + for i := 0; i < constant.REQUEST_DOMAIN_RETRY_TIME; i++ { + result, err = server.callConfigServer(api, params, headers, method, getAddress(srvs[0]), srvs[0].ContextPath) + if err == nil { + return result, nil + } + log.Printf("[ERROR] api<%s>,method:<%s>, params:<%s>, call domain error:<%s> , result:<%s> \n", api, method, utils.ToJsonString(params), err.Error(), result) + } + return "", err + } else { + index := rand.Intn(len(srvs)) + for i := 1; i <= len(srvs); i++ { + curServer := srvs[index] + result, err = server.callConfigServer(api, params, headers, method, getAddress(curServer), curServer.ContextPath) + if err == nil { + return result, nil + } + log.Printf("[ERROR] api<%s>,method:<%s>, params:<%s>, call domain error:<%s> , result:<%s> \n", api, method, utils.ToJsonString(params), err.Error(), result) + index = (index + i) % len(srvs) + } + return "", err + } +} + func (server *NacosServer) ReqApi(api string, params map[string]string, method string) (string, error) { srvs := server.serverList if srvs == nil || len(srvs) == 0 { @@ -133,7 +212,7 @@ func (server *NacosServer) refreshServerSrvIfNeed() { for _, line := range list { if line != "" { splitLine := strings.Split(strings.TrimSpace(line), ":") - port := 80 + port := 8848 var err error if len(splitLine) == 2 { port, err = strconv.Atoi(splitLine[1]) @@ -145,20 +224,60 @@ func (server *NacosServer) refreshServerSrvIfNeed() { servers = append(servers, constant.ServerConfig{IpAddr: splitLine[0], Port: uint64(port), ContextPath: constant.WEB_CONTEXT}) } } - if len(servers) > 0 { - server.Lock() if !reflect.DeepEqual(server.serverList, servers) { + server.Lock() log.Printf("[info] server list is updated, old: <%v>,new:<%v> \n", server.serverList, servers) + server.serverList = servers + server.lastSrvRefTime = utils.CurrentMillis() + server.Unlock() } - server.serverList = servers - server.lastSrvRefTime = utils.CurrentMillis() - server.Unlock() + } return } +func (server *NacosServer) GetServerList() []constant.ServerConfig { + return server.serverList +} + func getAddress(cfg constant.ServerConfig) string { return cfg.IpAddr + ":" + strconv.Itoa(int(cfg.Port)) } + +func getSignHeaders(params map[string]string, newHeaders map[string]string) map[string]string { + resource := "" + + if len(params["tenant"]) != 0 { + resource = params["tenant"] + "+" + params["group"] + } else { + resource = params["group"] + } + + headers := map[string]string{} + + timeStamp := strconv.FormatInt(time.Now().UnixNano()/1e6, 10) + headers["timeStamp"] = timeStamp + + signature := "" + + if resource == "" { + signature = signWithhmacSHA1Encrypt(timeStamp, newHeaders["secretKey"]) + } else { + signature = signWithhmacSHA1Encrypt(resource+"+"+timeStamp, newHeaders["secretKey"]) + } + + headers["Spas-Signature"] = signature + + return headers +} + +func signWithhmacSHA1Encrypt(encryptText, encryptKey string) string { + //hmac ,use sha1 + key := []byte(encryptKey) + mac := hmac.New(sha1.New, key) + mac.Write([]byte(encryptText)) + + return base64.StdEncoding.EncodeToString(mac.Sum(nil)) +} diff --git a/example/main/main.go b/example/main/main.go index 5eceb86e..b8397c0f 100644 --- a/example/main/main.go +++ b/example/main/main.go @@ -12,7 +12,6 @@ import ( ) func main() { - client, _ := clients.CreateNamingClient(map[string]interface{}{ "serverConfigs": []constant.ServerConfig{ { diff --git a/go.mod b/go.mod deleted file mode 100644 index fde0f15d..00000000 --- a/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/nacos-group/nacos-sdk-go - -go 1.12 - -require github.com/stretchr/testify v1.3.0 diff --git a/go.sum b/go.sum deleted file mode 100644 index 4347755a..00000000 --- a/go.sum +++ /dev/null @@ -1,7 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/model/service.go b/model/service.go index cecb6d91..6678aa54 100644 --- a/model/service.go +++ b/model/service.go @@ -1,5 +1,7 @@ package model +import "time" + /** * * @description : @@ -104,6 +106,8 @@ type BeatInfo struct { Cluster string `json:"cluster"` Metadata map[string]string `json:"metadata"` Scheduled bool `json:"scheduled"` + Period time.Duration `json:"-"` + Stopped bool `json:"-"` } type ExpressionSelector struct { diff --git a/utils/common.go b/utils/common.go index 7a2704da..adaf5d57 100644 --- a/utils/common.go +++ b/utils/common.go @@ -12,6 +12,7 @@ import ( "net" "os" "path/filepath" + "strconv" "time" ) @@ -124,3 +125,16 @@ func LocalIP() string { } return localIP } + +func GetDurationWithDefault(metadata map[string]string, key string, defaultDuration time.Duration) time.Duration { + data, ok := metadata[key] + if ok { + value, err := strconv.ParseInt(data, 10, 64) + if err != nil { + log.Printf("key:%s is not a number \n", key) + return defaultDuration + } + return time.Duration(value) + } + return defaultDuration +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go new file mode 100644 index 00000000..7f20b7a4 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go @@ -0,0 +1,18 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package auth + +type Credential interface { +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go new file mode 100644 index 00000000..68f82263 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go @@ -0,0 +1,34 @@ +package credentials + +// Deprecated: Use AccessKeyCredential in this package instead. +type BaseCredential struct { + AccessKeyId string + AccessKeySecret string +} + +type AccessKeyCredential struct { + AccessKeyId string + AccessKeySecret string +} + +// Deprecated: Use NewAccessKeyCredential in this package instead. +func NewBaseCredential(accessKeyId, accessKeySecret string) *BaseCredential { + return &BaseCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + } +} + +func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential { + return &AccessKeyCredential{ + AccessKeyId: baseCred.AccessKeyId, + AccessKeySecret: baseCred.AccessKeySecret, + } +} + +func NewAccessKeyCredential(accessKeyId, accessKeySecret string) *AccessKeyCredential { + return &AccessKeyCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go new file mode 100644 index 00000000..6d4763e6 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go @@ -0,0 +1,12 @@ +package credentials + +type BearerTokenCredential struct { + BearerToken string +} + +// NewBearerTokenCredential return a BearerTokenCredential object +func NewBearerTokenCredential(token string) *BearerTokenCredential { + return &BearerTokenCredential{ + BearerToken: token, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go new file mode 100644 index 00000000..55a5c2da --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go @@ -0,0 +1,29 @@ +package credentials + +func (oldCred *StsRoleNameOnEcsCredential) ToEcsRamRoleCredential() *EcsRamRoleCredential { + return &EcsRamRoleCredential{ + RoleName: oldCred.RoleName, + } +} + +type EcsRamRoleCredential struct { + RoleName string +} + +func NewEcsRamRoleCredential(roleName string) *EcsRamRoleCredential { + return &EcsRamRoleCredential{ + RoleName: roleName, + } +} + +// Deprecated: Use EcsRamRoleCredential in this package instead. +type StsRoleNameOnEcsCredential struct { + RoleName string +} + +// Deprecated: Use NewEcsRamRoleCredential in this package instead. +func NewStsRoleNameOnEcsCredential(roleName string) *StsRoleNameOnEcsCredential { + return &StsRoleNameOnEcsCredential{ + RoleName: roleName, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go new file mode 100644 index 00000000..3cd0d020 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go @@ -0,0 +1,30 @@ +package provider + +import ( + "errors" + "os" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" +) + +type EnvProvider struct{} + +var ProviderEnv = new(EnvProvider) + +func NewEnvProvider() Provider { + return &EnvProvider{} +} + +func (p *EnvProvider) Resolve() (auth.Credential, error) { + accessKeyID, ok1 := os.LookupEnv(ENVAccessKeyID) + accessKeySecret, ok2 := os.LookupEnv(ENVAccessKeySecret) + if !ok1 || !ok2 { + return nil, nil + } + if accessKeyID == "" || accessKeySecret == "" { + return nil, errors.New("Environmental variable (ALIBABACLOUD_ACCESS_KEY_ID or ALIBABACLOUD_ACCESS_KEY_SECRET) is empty") + } + return credentials.NewAccessKeyCredential(accessKeyID, accessKeySecret), nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go new file mode 100644 index 00000000..1906d21f --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go @@ -0,0 +1,92 @@ +package provider + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/" + +type InstanceCredentialsProvider struct{} + +var ProviderInstance = new(InstanceCredentialsProvider) + +var HookGet = func(fn func(string) (int, []byte, error)) func(string) (int, []byte, error) { + return fn +} + +func NewInstanceCredentialsProvider() Provider { + return &InstanceCredentialsProvider{} +} + +func (p *InstanceCredentialsProvider) Resolve() (auth.Credential, error) { + roleName, ok := os.LookupEnv(ENVEcsMetadata) + if !ok { + return nil, nil + } + if roleName == "" { + return nil, errors.New("Environmental variable 'ALIBABA_CLOUD_ECS_METADATA' are empty") + } + status, content, err := HookGet(get)(securityCredURL + roleName) + if err != nil { + return nil, err + } + if status != 200 { + if status == 404 { + return nil, fmt.Errorf("The role was not found in the instance") + } + return nil, fmt.Errorf("Received %d when getting security credentials for %s", status, roleName) + } + body := make(map[string]interface{}) + + if err := json.Unmarshal(content, &body); err != nil { + return nil, err + } + + accessKeyID, err := extractString(body, "AccessKeyId") + if err != nil { + return nil, err + } + accessKeySecret, err := extractString(body, "AccessKeySecret") + if err != nil { + return nil, err + } + securityToken, err := extractString(body, "SecurityToken") + if err != nil { + return nil, err + } + + return credentials.NewStsTokenCredential(accessKeyID, accessKeySecret, securityToken), nil +} + +func get(url string) (status int, content []byte, err error) { + httpClient := http.DefaultClient + httpClient.Timeout = time.Second * 1 + resp, err := httpClient.Get(url) + if err != nil { + return + } + defer resp.Body.Close() + content, err = ioutil.ReadAll(resp.Body) + return resp.StatusCode, content, err +} + +func extractString(m map[string]interface{}, key string) (string, error) { + raw, ok := m[key] + if !ok { + return "", fmt.Errorf("%s not in map", key) + } + str, ok := raw.(string) + if !ok { + return "", fmt.Errorf("%s is not a string in map", key) + } + return str, nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go new file mode 100644 index 00000000..8d525c37 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go @@ -0,0 +1,158 @@ +package provider + +import ( + "bufio" + "errors" + "os" + "runtime" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + + ini "gopkg.in/ini.v1" +) + +type ProfileProvider struct { + Profile string +} + +var ProviderProfile = NewProfileProvider() + +// NewProfileProvider receive zero or more parameters, +// when length of name is 0, the value of field Profile will be "default", +// and when there are multiple inputs, the function will take the +// first one and discard the other values. +func NewProfileProvider(name ...string) Provider { + p := new(ProfileProvider) + if len(name) == 0 { + p.Profile = "default" + } else { + p.Profile = name[0] + } + return p +} + +// Resolve implements the Provider interface +// when credential type is rsa_key_pair, the content of private_key file +// must be able to be parsed directly into the required string +// that NewRsaKeyPairCredential function needed +func (p *ProfileProvider) Resolve() (auth.Credential, error) { + path, ok := os.LookupEnv(ENVCredentialFile) + if !ok { + path, err := checkDefaultPath() + if err != nil { + return nil, err + } + if path == "" { + return nil, nil + } + } else if path == "" { + return nil, errors.New("Environment variable '" + ENVCredentialFile + "' cannot be empty") + } + + ini, err := ini.Load(path) + if err != nil { + return nil, errors.New("ERROR: Can not open file" + err.Error()) + } + + section, err := ini.GetSection(p.Profile) + if err != nil { + return nil, errors.New("ERROR: Can not load section" + err.Error()) + } + + value, err := section.GetKey("type") + if err != nil { + return nil, errors.New("ERROR: Can not find credential type" + err.Error()) + } + + switch value.String() { + case "access_key": + value1, err1 := section.GetKey("access_key_id") + value2, err2 := section.GetKey("access_key_secret") + if err1 != nil || err2 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" || value2.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + return credentials.NewAccessKeyCredential(value1.String(), value2.String()), nil + case "ecs_ram_role": + value1, err1 := section.GetKey("role_name") + if err1 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + return credentials.NewEcsRamRoleCredential(value1.String()), nil + case "ram_role_arn": + value1, err1 := section.GetKey("access_key_id") + value2, err2 := section.GetKey("access_key_secret") + value3, err3 := section.GetKey("role_arn") + value4, err4 := section.GetKey("role_session_name") + if err1 != nil || err2 != nil || err3 != nil || err4 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" || value2.String() == "" || value3.String() == "" || value4.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + return credentials.NewRamRoleArnCredential(value1.String(), value2.String(), value3.String(), value4.String(), 3600), nil + case "rsa_key_pair": + value1, err1 := section.GetKey("public_key_id") + value2, err2 := section.GetKey("private_key_file") + if err1 != nil || err2 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" || value2.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + file, err := os.Open(value2.String()) + if err != nil { + return nil, errors.New("ERROR: Can not get private_key") + } + defer file.Close() + var privateKey string + scan := bufio.NewScanner(file) + var data string + for scan.Scan() { + if strings.HasPrefix(scan.Text(), "----") { + continue + } + data += scan.Text() + "\n" + } + return credentials.NewRsaKeyPairCredential(privateKey, value1.String(), 3600), nil + default: + return nil, errors.New("ERROR: Failed to get credential") + } +} + +// GetHomePath return home directory according to the system. +// if the environmental virables does not exist, will return empty +func GetHomePath() string { + if runtime.GOOS == "windows" { + path, ok := os.LookupEnv("USERPROFILE") + if !ok { + return "" + } + return path + } + path, ok := os.LookupEnv("HOME") + if !ok { + return "" + } + return path +} + +func checkDefaultPath() (path string, err error) { + path = GetHomePath() + if path == "" { + return "", errors.New("The default credential file path is invalid") + } + path = strings.Replace("~/.alibabacloud/credentials", "~", path, 1) + _, err = os.Stat(path) + if err != nil { + return "", nil + } + return path, nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go new file mode 100644 index 00000000..ae4e168e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go @@ -0,0 +1,19 @@ +package provider + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" +) + +//Environmental virables that may be used by the provider +const ( + ENVAccessKeyID = "ALIBABA_CLOUD_ACCESS_KEY_ID" + ENVAccessKeySecret = "ALIBABA_CLOUD_ACCESS_KEY_SECRET" + ENVCredentialFile = "ALIBABA_CLOUD_CREDENTIALS_FILE" + ENVEcsMetadata = "ALIBABA_CLOUD_ECS_METADATA" + PATHCredentialFile = "~/.alibabacloud/credentials" +) + +// When you want to customize the provider, you only need to implement the method of the interface. +type Provider interface { + Resolve() (auth.Credential, error) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go new file mode 100644 index 00000000..3f9315d1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go @@ -0,0 +1,34 @@ +package provider + +import ( + "errors" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" +) + +type ProviderChain struct { + Providers []Provider +} + +var defaultproviders = []Provider{ProviderEnv, ProviderProfile, ProviderInstance} +var DefaultChain = NewProviderChain(defaultproviders) + +func NewProviderChain(providers []Provider) Provider { + return &ProviderChain{ + Providers: providers, + } +} + +func (p *ProviderChain) Resolve() (auth.Credential, error) { + for _, provider := range p.Providers { + creds, err := provider.Resolve() + if err != nil { + return nil, err + } else if err == nil && creds == nil { + continue + } + return creds, err + } + return nil, errors.New("No credential found") + +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go new file mode 100644 index 00000000..00d688eb --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go @@ -0,0 +1,15 @@ +package credentials + +type RsaKeyPairCredential struct { + PrivateKey string + PublicKeyId string + SessionExpiration int +} + +func NewRsaKeyPairCredential(privateKey, publicKeyId string, sessionExpiration int) *RsaKeyPairCredential { + return &RsaKeyPairCredential{ + PrivateKey: privateKey, + PublicKeyId: publicKeyId, + SessionExpiration: sessionExpiration, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go new file mode 100644 index 00000000..554431ff --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go @@ -0,0 +1,15 @@ +package credentials + +type StsTokenCredential struct { + AccessKeyId string + AccessKeySecret string + AccessKeyStsToken string +} + +func NewStsTokenCredential(accessKeyId, accessKeySecret, accessKeyStsToken string) *StsTokenCredential { + return &StsTokenCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + AccessKeyStsToken: accessKeyStsToken, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go new file mode 100644 index 00000000..27602fd7 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go @@ -0,0 +1,61 @@ +package credentials + +// Deprecated: Use RamRoleArnCredential in this package instead. +type StsRoleArnCredential struct { + AccessKeyId string + AccessKeySecret string + RoleArn string + RoleSessionName string + RoleSessionExpiration int +} + +type RamRoleArnCredential struct { + AccessKeyId string + AccessKeySecret string + RoleArn string + RoleSessionName string + RoleSessionExpiration int + Policy string +} + +// Deprecated: Use RamRoleArnCredential in this package instead. +func NewStsRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *StsRoleArnCredential { + return &StsRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + RoleSessionExpiration: roleSessionExpiration, + } +} + +func (oldCred *StsRoleArnCredential) ToRamRoleArnCredential() *RamRoleArnCredential { + return &RamRoleArnCredential{ + AccessKeyId: oldCred.AccessKeyId, + AccessKeySecret: oldCred.AccessKeySecret, + RoleArn: oldCred.RoleArn, + RoleSessionName: oldCred.RoleSessionName, + RoleSessionExpiration: oldCred.RoleSessionExpiration, + } +} + +func NewRamRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *RamRoleArnCredential { + return &RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + RoleSessionExpiration: roleSessionExpiration, + } +} + +func NewRamRoleArnWithPolicyCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string, roleSessionExpiration int) *RamRoleArnCredential { + return &RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + RoleSessionExpiration: roleSessionExpiration, + Policy: policy, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go new file mode 100644 index 00000000..8b4037a0 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go @@ -0,0 +1,136 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package auth + +import ( + "bytes" + "sort" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var debug utils.Debug + +var hookGetDate = func(fn func() string) string { + return fn() +} + +func init() { + debug = utils.Init("sdk") +} + +func signRoaRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) { + completeROASignParams(request, signer, regionId) + stringToSign := buildRoaStringToSign(request) + request.SetStringToSign(stringToSign) + accessKeyId, err := signer.GetAccessKeyId() + if err != nil { + return err + } + + signature := signer.Sign(stringToSign, "") + request.GetHeaders()["Authorization"] = "acs " + accessKeyId + ":" + signature + + return +} + +func completeROASignParams(request requests.AcsRequest, signer Signer, regionId string) { + headerParams := request.GetHeaders() + + // complete query params + queryParams := request.GetQueryParams() + //if _, ok := queryParams["RegionId"]; !ok { + // queryParams["RegionId"] = regionId + //} + if extraParam := signer.GetExtraParam(); extraParam != nil { + for key, value := range extraParam { + if key == "SecurityToken" { + headerParams["x-acs-security-token"] = value + continue + } + if key == "BearerToken" { + headerParams["x-acs-bearer-token"] = value + continue + } + queryParams[key] = value + } + } + + // complete header params + headerParams["Date"] = hookGetDate(utils.GetTimeInFormatRFC2616) + headerParams["x-acs-signature-method"] = signer.GetName() + headerParams["x-acs-signature-version"] = signer.GetVersion() + if request.GetFormParams() != nil && len(request.GetFormParams()) > 0 { + formString := utils.GetUrlFormedMap(request.GetFormParams()) + request.SetContent([]byte(formString)) + headerParams["Content-Type"] = requests.Form + } + contentMD5 := utils.GetMD5Base64(request.GetContent()) + headerParams["Content-MD5"] = contentMD5 + if _, contains := headerParams["Content-Type"]; !contains { + headerParams["Content-Type"] = requests.Raw + } + switch format := request.GetAcceptFormat(); format { + case "JSON": + headerParams["Accept"] = requests.Json + case "XML": + headerParams["Accept"] = requests.Xml + default: + headerParams["Accept"] = requests.Raw + } +} + +func buildRoaStringToSign(request requests.AcsRequest) (stringToSign string) { + + headers := request.GetHeaders() + + stringToSignBuilder := bytes.Buffer{} + stringToSignBuilder.WriteString(request.GetMethod()) + stringToSignBuilder.WriteString(requests.HeaderSeparator) + + // append header keys for sign + appendIfContain(headers, &stringToSignBuilder, "Accept", requests.HeaderSeparator) + appendIfContain(headers, &stringToSignBuilder, "Content-MD5", requests.HeaderSeparator) + appendIfContain(headers, &stringToSignBuilder, "Content-Type", requests.HeaderSeparator) + appendIfContain(headers, &stringToSignBuilder, "Date", requests.HeaderSeparator) + + // sort and append headers witch starts with 'x-acs-' + var acsHeaders []string + for key := range headers { + if strings.HasPrefix(key, "x-acs-") { + acsHeaders = append(acsHeaders, key) + } + } + sort.Strings(acsHeaders) + for _, key := range acsHeaders { + stringToSignBuilder.WriteString(key + ":" + headers[key]) + stringToSignBuilder.WriteString(requests.HeaderSeparator) + } + + // append query params + stringToSignBuilder.WriteString(request.BuildQueries()) + stringToSign = stringToSignBuilder.String() + debug("stringToSign: %s", stringToSign) + return +} + +func appendIfContain(sourceMap map[string]string, target *bytes.Buffer, key, separator string) { + if value, contain := sourceMap[key]; contain && len(value) > 0 { + target.WriteString(sourceMap[key]) + target.WriteString(separator) + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go new file mode 100644 index 00000000..33967b9e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go @@ -0,0 +1,94 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package auth + +import ( + "net/url" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var hookGetNonce = func(fn func() string) string { + return fn() +} + +func signRpcRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) { + err = completeRpcSignParams(request, signer, regionId) + if err != nil { + return + } + // remove while retry + if _, containsSign := request.GetQueryParams()["Signature"]; containsSign { + delete(request.GetQueryParams(), "Signature") + } + stringToSign := buildRpcStringToSign(request) + request.SetStringToSign(stringToSign) + signature := signer.Sign(stringToSign, "&") + request.GetQueryParams()["Signature"] = signature + + return +} + +func completeRpcSignParams(request requests.AcsRequest, signer Signer, regionId string) (err error) { + queryParams := request.GetQueryParams() + queryParams["Version"] = request.GetVersion() + queryParams["Action"] = request.GetActionName() + queryParams["Format"] = request.GetAcceptFormat() + queryParams["Timestamp"] = hookGetDate(utils.GetTimeInFormatISO8601) + queryParams["SignatureMethod"] = signer.GetName() + queryParams["SignatureType"] = signer.GetType() + queryParams["SignatureVersion"] = signer.GetVersion() + queryParams["SignatureNonce"] = hookGetNonce(utils.GetUUID) + queryParams["AccessKeyId"], err = signer.GetAccessKeyId() + + if err != nil { + return + } + + if _, contains := queryParams["RegionId"]; !contains { + queryParams["RegionId"] = regionId + } + if extraParam := signer.GetExtraParam(); extraParam != nil { + for key, value := range extraParam { + queryParams[key] = value + } + } + + request.GetHeaders()["Content-Type"] = requests.Form + formString := utils.GetUrlFormedMap(request.GetFormParams()) + request.SetContent([]byte(formString)) + + return +} + +func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) { + signParams := make(map[string]string) + for key, value := range request.GetQueryParams() { + signParams[key] = value + } + for key, value := range request.GetFormParams() { + signParams[key] = value + } + + stringToSign = utils.GetUrlFormedMap(signParams) + stringToSign = strings.Replace(stringToSign, "+", "%20", -1) + stringToSign = strings.Replace(stringToSign, "*", "%2A", -1) + stringToSign = strings.Replace(stringToSign, "%7E", "~", -1) + stringToSign = url.QueryEscape(stringToSign) + stringToSign = request.GetMethod() + "&%2F&" + stringToSign + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go new file mode 100644 index 00000000..cbbc3cef --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go @@ -0,0 +1,98 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package auth + +import ( + "fmt" + "reflect" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +type Signer interface { + GetName() string + GetType() string + GetVersion() string + GetAccessKeyId() (string, error) + GetExtraParam() map[string]string + Sign(stringToSign, secretSuffix string) string +} + +func NewSignerWithCredential(credential Credential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer Signer, err error) { + switch instance := credential.(type) { + case *credentials.AccessKeyCredential: + { + signer = signers.NewAccessKeySigner(instance) + } + case *credentials.StsTokenCredential: + { + signer = signers.NewStsTokenSigner(instance) + } + case *credentials.BearerTokenCredential: + { + signer = signers.NewBearerTokenSigner(instance) + } + case *credentials.RamRoleArnCredential: + { + signer, err = signers.NewRamRoleArnSigner(instance, commonApi) + } + case *credentials.RsaKeyPairCredential: + { + signer, err = signers.NewSignerKeyPair(instance, commonApi) + } + case *credentials.EcsRamRoleCredential: + { + signer = signers.NewEcsRamRoleSigner(instance, commonApi) + } + case *credentials.BaseCredential: // deprecated user interface + { + signer = signers.NewAccessKeySigner(instance.ToAccessKeyCredential()) + } + case *credentials.StsRoleArnCredential: // deprecated user interface + { + signer, err = signers.NewRamRoleArnSigner(instance.ToRamRoleArnCredential(), commonApi) + } + case *credentials.StsRoleNameOnEcsCredential: // deprecated user interface + { + signer = signers.NewEcsRamRoleSigner(instance.ToEcsRamRoleCredential(), commonApi) + } + default: + message := fmt.Sprintf(errors.UnsupportedCredentialErrorMessage, reflect.TypeOf(credential)) + err = errors.NewClientError(errors.UnsupportedCredentialErrorCode, message, nil) + } + return +} + +func Sign(request requests.AcsRequest, signer Signer, regionId string) (err error) { + switch request.GetStyle() { + case requests.ROA: + { + err = signRoaRequest(request, signer, regionId) + } + case requests.RPC: + { + err = signRpcRequest(request, signer, regionId) + } + default: + message := fmt.Sprintf(errors.UnknownRequestTypeErrorMessage, reflect.TypeOf(request)) + err = errors.NewClientError(errors.UnknownRequestTypeErrorCode, message, nil) + } + + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go new file mode 100644 index 00000000..887f5020 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go @@ -0,0 +1,57 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "crypto" + "crypto/hmac" + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "encoding/base64" +) + +func ShaHmac1(source, secret string) string { + key := []byte(secret) + hmac := hmac.New(sha1.New, key) + hmac.Write([]byte(source)) + signedBytes := hmac.Sum(nil) + signedString := base64.StdEncoding.EncodeToString(signedBytes) + return signedString +} + +func Sha256WithRsa(source, secret string) string { + // block, _ := pem.Decode([]byte(secret)) + decodeString, err := base64.StdEncoding.DecodeString(secret) + if err != nil { + panic(err) + } + private, err := x509.ParsePKCS8PrivateKey(decodeString) + if err != nil { + panic(err) + } + + h := crypto.Hash.New(crypto.SHA256) + h.Write([]byte(source)) + hashed := h.Sum(nil) + signature, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), + crypto.SHA256, hashed) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(signature) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go new file mode 100644 index 00000000..ba291a41 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go @@ -0,0 +1,54 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +const defaultInAdvanceScale = 0.95 + +type credentialUpdater struct { + credentialExpiration int + lastUpdateTimestamp int64 + inAdvanceScale float64 + buildRequestMethod func() (*requests.CommonRequest, error) + responseCallBack func(response *responses.CommonResponse) error + refreshApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) +} + +func (updater *credentialUpdater) needUpdateCredential() (result bool) { + if updater.inAdvanceScale == 0 { + updater.inAdvanceScale = defaultInAdvanceScale + } + return time.Now().Unix()-updater.lastUpdateTimestamp >= int64(float64(updater.credentialExpiration)*updater.inAdvanceScale) +} + +func (updater *credentialUpdater) updateCredential() (err error) { + request, err := updater.buildRequestMethod() + if err != nil { + return + } + response, err := updater.refreshApi(request) + if err != nil { + return + } + updater.lastUpdateTimestamp = time.Now().Unix() + err = updater.responseCallBack(response) + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go new file mode 100644 index 00000000..99c624c8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go @@ -0,0 +1,7 @@ +package signers + +type SessionCredential struct { + AccessKeyId string + AccessKeySecret string + StsToken string +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go new file mode 100644 index 00000000..bc4f35b8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go @@ -0,0 +1,54 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type AccessKeySigner struct { + credential *credentials.AccessKeyCredential +} + +func (signer *AccessKeySigner) GetExtraParam() map[string]string { + return nil +} + +func NewAccessKeySigner(credential *credentials.AccessKeyCredential) *AccessKeySigner { + return &AccessKeySigner{ + credential: credential, + } +} + +func (*AccessKeySigner) GetName() string { + return "HMAC-SHA1" +} + +func (*AccessKeySigner) GetType() string { + return "" +} + +func (*AccessKeySigner) GetVersion() string { + return "1.0" +} + +func (signer *AccessKeySigner) GetAccessKeyId() (accessKeyId string, err error) { + return signer.credential.AccessKeyId, nil +} + +func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.credential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go new file mode 100644 index 00000000..75b78433 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go @@ -0,0 +1,35 @@ +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type BearerTokenSigner struct { + credential *credentials.BearerTokenCredential +} + +func NewBearerTokenSigner(credential *credentials.BearerTokenCredential) *BearerTokenSigner { + return &BearerTokenSigner{ + credential: credential, + } +} + +func (signer *BearerTokenSigner) GetExtraParam() map[string]string { + return map[string]string{"BearerToken": signer.credential.BearerToken} +} + +func (*BearerTokenSigner) GetName() string { + return "" +} +func (*BearerTokenSigner) GetType() string { + return "BEARERTOKEN" +} +func (*BearerTokenSigner) GetVersion() string { + return "1.0" +} +func (signer *BearerTokenSigner) GetAccessKeyId() (accessKeyId string, err error) { + return "", nil +} +func (signer *BearerTokenSigner) Sign(stringToSign, secretSuffix string) string { + return "" +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go new file mode 100644 index 00000000..73788429 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go @@ -0,0 +1,167 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + jmespath "github.com/jmespath/go-jmespath" +) + +var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/" + +type EcsRamRoleSigner struct { + *credentialUpdater + sessionCredential *SessionCredential + credential *credentials.EcsRamRoleCredential + commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error) +} + +func NewEcsRamRoleSigner(credential *credentials.EcsRamRoleCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *EcsRamRoleSigner) { + signer = &EcsRamRoleSigner{ + credential: credential, + commonApi: commonApi, + } + + signer.credentialUpdater = &credentialUpdater{ + credentialExpiration: defaultDurationSeconds / 60, + buildRequestMethod: signer.buildCommonRequest, + responseCallBack: signer.refreshCredential, + refreshApi: signer.refreshApi, + } + + return signer +} + +func (*EcsRamRoleSigner) GetName() string { + return "HMAC-SHA1" +} + +func (*EcsRamRoleSigner) GetType() string { + return "" +} + +func (*EcsRamRoleSigner) GetVersion() string { + return "1.0" +} + +func (signer *EcsRamRoleSigner) GetAccessKeyId() (accessKeyId string, err error) { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + err = signer.updateCredential() + if err != nil { + return + } + } + if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 { + return "", nil + } + return signer.sessionCredential.AccessKeyId, nil +} + +func (signer *EcsRamRoleSigner) GetExtraParam() map[string]string { + if signer.sessionCredential == nil { + return make(map[string]string) + } + if len(signer.sessionCredential.StsToken) <= 0 { + return make(map[string]string) + } + return map[string]string{"SecurityToken": signer.sessionCredential.StsToken} +} + +func (signer *EcsRamRoleSigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.sessionCredential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} + +func (signer *EcsRamRoleSigner) buildCommonRequest() (request *requests.CommonRequest, err error) { + return +} + +func (signer *EcsRamRoleSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + requestUrl := securityCredURL + signer.credential.RoleName + httpRequest, err := http.NewRequest(requests.GET, requestUrl, strings.NewReader("")) + if err != nil { + err = fmt.Errorf("refresh Ecs sts token err: %s", err.Error()) + return + } + httpClient := &http.Client{} + httpResponse, err := httpClient.Do(httpRequest) + if err != nil { + err = fmt.Errorf("refresh Ecs sts token err: %s", err.Error()) + return + } + + response = responses.NewCommonResponse() + err = responses.Unmarshal(response, httpResponse, "") + return +} + +func (signer *EcsRamRoleSigner) refreshCredential(response *responses.CommonResponse) (err error) { + if response.GetHttpStatus() != http.StatusOK { + return fmt.Errorf("refresh Ecs sts token err, httpStatus: %d, message = %s", response.GetHttpStatus(), response.GetHttpContentString()) + } + var data interface{} + err = json.Unmarshal(response.GetHttpContentBytes(), &data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, json.Unmarshal fail: %s", err.Error()) + } + code, err := jmespath.Search("Code", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get Code: %s", err.Error()) + } + if code.(string) != "Success" { + return fmt.Errorf("refresh Ecs sts token err, Code is not Success") + } + accessKeyId, err := jmespath.Search("AccessKeyId", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeyId: %s", err.Error()) + } + accessKeySecret, err := jmespath.Search("AccessKeySecret", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeySecret: %s", err.Error()) + } + securityToken, err := jmespath.Search("SecurityToken", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get SecurityToken: %s", err.Error()) + } + expiration, err := jmespath.Search("Expiration", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get Expiration: %s", err.Error()) + } + if accessKeyId == nil || accessKeySecret == nil || securityToken == nil || expiration == nil { + return + } + + expirationTime, err := time.Parse("2006-01-02T15:04:05Z", expiration.(string)) + signer.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix()) + signer.sessionCredential = &SessionCredential{ + AccessKeyId: accessKeyId.(string), + AccessKeySecret: accessKeySecret.(string), + StsToken: securityToken.(string), + } + + return +} + +func (signer *EcsRamRoleSigner) GetSessionCredential() *SessionCredential { + return signer.sessionCredential +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go new file mode 100644 index 00000000..19273d5a --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go @@ -0,0 +1,148 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + jmespath "github.com/jmespath/go-jmespath" +) + +type SignerKeyPair struct { + *credentialUpdater + sessionCredential *SessionCredential + credential *credentials.RsaKeyPairCredential + commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error) +} + +func NewSignerKeyPair(credential *credentials.RsaKeyPairCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerKeyPair, err error) { + signer = &SignerKeyPair{ + credential: credential, + commonApi: commonApi, + } + + signer.credentialUpdater = &credentialUpdater{ + credentialExpiration: credential.SessionExpiration, + buildRequestMethod: signer.buildCommonRequest, + responseCallBack: signer.refreshCredential, + refreshApi: signer.refreshApi, + } + + if credential.SessionExpiration > 0 { + if credential.SessionExpiration >= 900 && credential.SessionExpiration <= 3600 { + signer.credentialExpiration = credential.SessionExpiration + } else { + err = errors.NewClientError(errors.InvalidParamErrorCode, "Key Pair session duration should be in the range of 15min - 1Hr", nil) + } + } else { + signer.credentialExpiration = defaultDurationSeconds + } + return +} + +func (*SignerKeyPair) GetName() string { + return "HMAC-SHA1" +} + +func (*SignerKeyPair) GetType() string { + return "" +} + +func (*SignerKeyPair) GetVersion() string { + return "1.0" +} + +func (signer *SignerKeyPair) ensureCredential() error { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + return signer.updateCredential() + } + return nil +} + +func (signer *SignerKeyPair) GetAccessKeyId() (accessKeyId string, err error) { + err = signer.ensureCredential() + if err != nil { + return + } + if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 { + accessKeyId = "" + return + } + + accessKeyId = signer.sessionCredential.AccessKeyId + return +} + +func (signer *SignerKeyPair) GetExtraParam() map[string]string { + return make(map[string]string) +} + +func (signer *SignerKeyPair) Sign(stringToSign, secretSuffix string) string { + secret := signer.sessionCredential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} + +func (signer *SignerKeyPair) buildCommonRequest() (request *requests.CommonRequest, err error) { + request = requests.NewCommonRequest() + request.Product = "Sts" + request.Version = "2015-04-01" + request.ApiName = "GenerateSessionAccessKey" + request.Scheme = requests.HTTPS + request.SetDomain("sts.ap-northeast-1.aliyuncs.com") + request.QueryParams["PublicKeyId"] = signer.credential.PublicKeyId + request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration) + return +} + +func (signer *SignerKeyPair) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + signerV2 := NewSignerV2(signer.credential) + return signer.commonApi(request, signerV2) +} + +func (signer *SignerKeyPair) refreshCredential(response *responses.CommonResponse) (err error) { + if response.GetHttpStatus() != http.StatusOK { + message := "refresh session AccessKey failed" + err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message) + return + } + var data interface{} + err = json.Unmarshal(response.GetHttpContentBytes(), &data) + if err != nil { + return fmt.Errorf("refresh KeyPair err, json.Unmarshal fail: %s", err.Error()) + } + accessKeyId, err := jmespath.Search("SessionAccessKey.SessionAccessKeyId", data) + if err != nil { + return fmt.Errorf("refresh KeyPair err, fail to get SessionAccessKeyId: %s", err.Error()) + } + accessKeySecret, err := jmespath.Search("SessionAccessKey.SessionAccessKeySecret", data) + if err != nil { + return fmt.Errorf("refresh KeyPair err, fail to get SessionAccessKeySecret: %s", err.Error()) + } + if accessKeyId == nil || accessKeySecret == nil { + return + } + signer.sessionCredential = &SessionCredential{ + AccessKeyId: accessKeyId.(string), + AccessKeySecret: accessKeySecret.(string), + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go new file mode 100644 index 00000000..c945c8ae --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go @@ -0,0 +1,175 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + jmespath "github.com/jmespath/go-jmespath" +) + +const ( + defaultDurationSeconds = 3600 +) + +type RamRoleArnSigner struct { + *credentialUpdater + roleSessionName string + sessionCredential *SessionCredential + credential *credentials.RamRoleArnCredential + commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error) +} + +func NewRamRoleArnSigner(credential *credentials.RamRoleArnCredential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer *RamRoleArnSigner, err error) { + signer = &RamRoleArnSigner{ + credential: credential, + commonApi: commonApi, + } + + signer.credentialUpdater = &credentialUpdater{ + credentialExpiration: credential.RoleSessionExpiration, + buildRequestMethod: signer.buildCommonRequest, + responseCallBack: signer.refreshCredential, + refreshApi: signer.refreshApi, + } + + if len(credential.RoleSessionName) > 0 { + signer.roleSessionName = credential.RoleSessionName + } else { + signer.roleSessionName = "aliyun-go-sdk-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10) + } + if credential.RoleSessionExpiration > 0 { + if credential.RoleSessionExpiration >= 900 && credential.RoleSessionExpiration <= 3600 { + signer.credentialExpiration = credential.RoleSessionExpiration + } else { + err = errors.NewClientError(errors.InvalidParamErrorCode, "Assume Role session duration should be in the range of 15min - 1Hr", nil) + } + } else { + signer.credentialExpiration = defaultDurationSeconds + } + return +} + +func (*RamRoleArnSigner) GetName() string { + return "HMAC-SHA1" +} + +func (*RamRoleArnSigner) GetType() string { + return "" +} + +func (*RamRoleArnSigner) GetVersion() string { + return "1.0" +} + +func (signer *RamRoleArnSigner) GetAccessKeyId() (accessKeyId string, err error) { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + err = signer.updateCredential() + if err != nil { + return + } + } + + if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 { + return "", err + } + + return signer.sessionCredential.AccessKeyId, nil +} + +func (signer *RamRoleArnSigner) GetExtraParam() map[string]string { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + signer.updateCredential() + } + if signer.sessionCredential == nil || len(signer.sessionCredential.StsToken) <= 0 { + return make(map[string]string) + } + return map[string]string{"SecurityToken": signer.sessionCredential.StsToken} +} + +func (signer *RamRoleArnSigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.sessionCredential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} + +func (signer *RamRoleArnSigner) buildCommonRequest() (request *requests.CommonRequest, err error) { + request = requests.NewCommonRequest() + request.Product = "Sts" + request.Version = "2015-04-01" + request.ApiName = "AssumeRole" + request.Scheme = requests.HTTPS + request.QueryParams["RoleArn"] = signer.credential.RoleArn + if signer.credential.Policy != "" { + request.QueryParams["Policy"] = signer.credential.Policy + } + request.QueryParams["RoleSessionName"] = signer.credential.RoleSessionName + request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration) + return +} + +func (signer *RamRoleArnSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + credential := &credentials.AccessKeyCredential{ + AccessKeyId: signer.credential.AccessKeyId, + AccessKeySecret: signer.credential.AccessKeySecret, + } + signerV1 := NewAccessKeySigner(credential) + return signer.commonApi(request, signerV1) +} + +func (signer *RamRoleArnSigner) refreshCredential(response *responses.CommonResponse) (err error) { + if response.GetHttpStatus() != http.StatusOK { + message := "refresh session token failed" + err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message) + return + } + var data interface{} + err = json.Unmarshal(response.GetHttpContentBytes(), &data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, json.Unmarshal fail: %s", err.Error()) + } + accessKeyId, err := jmespath.Search("Credentials.AccessKeyId", data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, fail to get AccessKeyId: %s", err.Error()) + } + accessKeySecret, err := jmespath.Search("Credentials.AccessKeySecret", data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, fail to get AccessKeySecret: %s", err.Error()) + } + securityToken, err := jmespath.Search("Credentials.SecurityToken", data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, fail to get SecurityToken: %s", err.Error()) + } + if accessKeyId == nil || accessKeySecret == nil || securityToken == nil { + return + } + signer.sessionCredential = &SessionCredential{ + AccessKeyId: accessKeyId.(string), + AccessKeySecret: accessKeySecret.(string), + StsToken: securityToken.(string), + } + return +} + +func (signer *RamRoleArnSigner) GetSessionCredential() *SessionCredential { + return signer.sessionCredential +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go new file mode 100644 index 00000000..d0ce36c3 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go @@ -0,0 +1,54 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type StsTokenSigner struct { + credential *credentials.StsTokenCredential +} + +func NewStsTokenSigner(credential *credentials.StsTokenCredential) *StsTokenSigner { + return &StsTokenSigner{ + credential: credential, + } +} + +func (*StsTokenSigner) GetName() string { + return "HMAC-SHA1" +} + +func (*StsTokenSigner) GetType() string { + return "" +} + +func (*StsTokenSigner) GetVersion() string { + return "1.0" +} + +func (signer *StsTokenSigner) GetAccessKeyId() (accessKeyId string, err error) { + return signer.credential.AccessKeyId, nil +} + +func (signer *StsTokenSigner) GetExtraParam() map[string]string { + return map[string]string{"SecurityToken": signer.credential.AccessKeyStsToken} +} + +func (signer *StsTokenSigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.credential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go new file mode 100644 index 00000000..97348529 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go @@ -0,0 +1,54 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type SignerV2 struct { + credential *credentials.RsaKeyPairCredential +} + +func (signer *SignerV2) GetExtraParam() map[string]string { + return nil +} + +func NewSignerV2(credential *credentials.RsaKeyPairCredential) *SignerV2 { + return &SignerV2{ + credential: credential, + } +} + +func (*SignerV2) GetName() string { + return "SHA256withRSA" +} + +func (*SignerV2) GetType() string { + return "PRIVATEKEY" +} + +func (*SignerV2) GetVersion() string { + return "1.0" +} + +func (signer *SignerV2) GetAccessKeyId() (accessKeyId string, err error) { + return signer.credential.PublicKeyId, err +} + +func (signer *SignerV2) Sign(stringToSign, secretSuffix string) string { + secret := signer.credential.PrivateKey + return Sha256WithRsa(stringToSign, secret) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go new file mode 100644 index 00000000..01c2f93b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go @@ -0,0 +1,725 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sdk + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "net/http" + "net/url" + "os" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var debug utils.Debug + +func init() { + debug = utils.Init("sdk") +} + +// Version this value will be replaced while build: -ldflags="-X sdk.version=x.x.x" +var Version = "0.0.1" +var defaultConnectTimeout = 5 * time.Second +var defaultReadTimeout = 10 * time.Second + +var DefaultUserAgent = fmt.Sprintf("AlibabaCloud (%s; %s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version) + +var hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) { + return fn +} + +// Client the type Client +type Client struct { + isInsecure bool + regionId string + config *Config + httpProxy string + httpsProxy string + noProxy string + logger *Logger + userAgent map[string]string + signer auth.Signer + httpClient *http.Client + asyncTaskQueue chan func() + readTimeout time.Duration + connectTimeout time.Duration + + debug bool + isRunning bool + // void "panic(write to close channel)" cause of addAsync() after Shutdown() + asyncChanLock *sync.RWMutex +} + +func (client *Client) Init() (err error) { + panic("not support yet") +} + +func (client *Client) SetHTTPSInsecure(isInsecure bool) { + client.isInsecure = isInsecure +} + +func (client *Client) GetHTTPSInsecure() bool { + return client.isInsecure +} + +func (client *Client) SetHttpsProxy(httpsProxy string) { + client.httpsProxy = httpsProxy +} + +func (client *Client) GetHttpsProxy() string { + return client.httpsProxy +} + +func (client *Client) SetHttpProxy(httpProxy string) { + client.httpProxy = httpProxy +} + +func (client *Client) GetHttpProxy() string { + return client.httpProxy +} + +func (client *Client) SetNoProxy(noProxy string) { + client.noProxy = noProxy +} + +func (client *Client) GetNoProxy() string { + return client.noProxy +} + +// InitWithProviderChain will get credential from the providerChain, +// the RsaKeyPairCredential Only applicable to regionID `ap-northeast-1`, +// if your providerChain may return a credential type with RsaKeyPairCredential, +// please ensure your regionID is `ap-northeast-1`. +func (client *Client) InitWithProviderChain(regionId string, provider provider.Provider) (err error) { + config := client.InitClientConfig() + credential, err := provider.Resolve() + if err != nil { + return + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithOptions(regionId string, config *Config, credential auth.Credential) (err error) { + client.isRunning = true + client.asyncChanLock = new(sync.RWMutex) + client.regionId = regionId + client.config = config + client.httpClient = &http.Client{} + + if config.HttpTransport != nil { + client.httpClient.Transport = config.HttpTransport + } + + if config.Timeout > 0 { + client.httpClient.Timeout = config.Timeout + } + + if config.EnableAsync { + client.EnableAsync(config.GoRoutinePoolSize, config.MaxTaskQueueSize) + } + + client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner) + + return +} + +func (client *Client) SetReadTimeout(readTimeout time.Duration) { + client.readTimeout = readTimeout +} + +func (client *Client) SetConnectTimeout(connectTimeout time.Duration) { + client.connectTimeout = connectTimeout +} + +func (client *Client) GetReadTimeout() time.Duration { + return client.readTimeout +} + +func (client *Client) GetConnectTimeout() time.Duration { + return client.connectTimeout +} + +func (client *Client) getHttpProxy(scheme string) (proxy *url.URL, err error) { + if scheme == "https" { + if client.GetHttpsProxy() != "" { + proxy, err = url.Parse(client.httpsProxy) + } else if rawurl := os.Getenv("HTTPS_PROXY"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } else if rawurl := os.Getenv("https_proxy"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } + } else { + if client.GetHttpProxy() != "" { + proxy, err = url.Parse(client.httpProxy) + } else if rawurl := os.Getenv("HTTP_PROXY"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } else if rawurl := os.Getenv("http_proxy"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } + } + + return proxy, err +} + +func (client *Client) getNoProxy(scheme string) []string { + var urls []string + if client.GetNoProxy() != "" { + urls = strings.Split(client.noProxy, ",") + } else if rawurl := os.Getenv("NO_PROXY"); rawurl != "" { + urls = strings.Split(rawurl, ",") + } else if rawurl := os.Getenv("no_proxy"); rawurl != "" { + urls = strings.Split(rawurl, ",") + } + + return urls +} + +// EnableAsync enable the async task queue +func (client *Client) EnableAsync(routinePoolSize, maxTaskQueueSize int) { + client.asyncTaskQueue = make(chan func(), maxTaskQueueSize) + for i := 0; i < routinePoolSize; i++ { + go func() { + for client.isRunning { + select { + case task, notClosed := <-client.asyncTaskQueue: + if notClosed { + task() + } + } + } + }() + } +} + +func (client *Client) InitWithAccessKey(regionId, accessKeyId, accessKeySecret string) (err error) { + config := client.InitClientConfig() + credential := &credentials.BaseCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithStsToken(regionId, accessKeyId, accessKeySecret, securityToken string) (err error) { + config := client.InitClientConfig() + credential := &credentials.StsTokenCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + AccessKeyStsToken: securityToken, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (err error) { + config := client.InitClientConfig() + credential := &credentials.RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithRamRoleArnAndPolicy(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string) (err error) { + config := client.InitClientConfig() + credential := &credentials.RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + Policy: policy, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithRsaKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) { + config := client.InitClientConfig() + credential := &credentials.RsaKeyPairCredential{ + PrivateKey: privateKey, + PublicKeyId: publicKeyId, + SessionExpiration: sessionExpiration, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithEcsRamRole(regionId, roleName string) (err error) { + config := client.InitClientConfig() + credential := &credentials.EcsRamRoleCredential{ + RoleName: roleName, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithBearerToken(regionId, bearerToken string) (err error) { + config := client.InitClientConfig() + credential := &credentials.BearerTokenCredential{ + BearerToken: bearerToken, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitClientConfig() (config *Config) { + if client.config != nil { + return client.config + } else { + return NewConfig() + } +} + +func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) { + return client.DoActionWithSigner(request, response, nil) +} + +func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (httpRequest *http.Request, err error) { + // add clientVersion + request.GetHeaders()["x-sdk-core-version"] = Version + + regionId := client.regionId + if len(request.GetRegionId()) > 0 { + regionId = request.GetRegionId() + } + + // resolve endpoint + resolveParam := &endpoints.ResolveParam{ + Domain: request.GetDomain(), + Product: request.GetProduct(), + RegionId: regionId, + LocationProduct: request.GetLocationServiceCode(), + LocationEndpointType: request.GetLocationEndpointType(), + CommonApi: client.ProcessCommonRequest, + } + endpoint, err := endpoints.Resolve(resolveParam) + if err != nil { + return + } + request.SetDomain(endpoint) + if request.GetScheme() == "" { + request.SetScheme(client.config.Scheme) + } + // init request params + err = requests.InitParams(request) + if err != nil { + return + } + + // signature + var finalSigner auth.Signer + if signer != nil { + finalSigner = signer + } else { + finalSigner = client.signer + } + httpRequest, err = buildHttpRequest(request, finalSigner, regionId) + if err == nil { + userAgent := DefaultUserAgent + getSendUserAgent(client.config.UserAgent, client.userAgent, request.GetUserAgent()) + httpRequest.Header.Set("User-Agent", userAgent) + } + + return +} + +func getSendUserAgent(configUserAgent string, clientUserAgent, requestUserAgent map[string]string) string { + realUserAgent := "" + for key1, value1 := range clientUserAgent { + for key2, _ := range requestUserAgent { + if key1 == key2 { + key1 = "" + } + } + if key1 != "" { + realUserAgent += fmt.Sprintf(" %s/%s", key1, value1) + + } + } + for key, value := range requestUserAgent { + realUserAgent += fmt.Sprintf(" %s/%s", key, value) + } + if configUserAgent != "" { + return realUserAgent + fmt.Sprintf(" Extra/%s", configUserAgent) + } + return realUserAgent +} + +func (client *Client) AppendUserAgent(key, value string) { + newkey := true + + if client.userAgent == nil { + client.userAgent = make(map[string]string) + } + if strings.ToLower(key) != "core" && strings.ToLower(key) != "go" { + for tag, _ := range client.userAgent { + if tag == key { + client.userAgent[tag] = value + newkey = false + } + } + if newkey { + client.userAgent[key] = value + } + } +} + +func (client *Client) BuildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (err error) { + _, err = client.buildRequestWithSigner(request, signer) + return +} + +func (client *Client) getTimeout(request requests.AcsRequest) (time.Duration, time.Duration) { + readTimeout := defaultReadTimeout + connectTimeout := defaultConnectTimeout + + reqReadTimeout := request.GetReadTimeout() + reqConnectTimeout := request.GetConnectTimeout() + if reqReadTimeout != 0*time.Millisecond { + readTimeout = reqReadTimeout + } else if client.readTimeout != 0*time.Millisecond { + readTimeout = client.readTimeout + } else if client.httpClient.Timeout != 0 && client.httpClient.Timeout != 10000000000 { + readTimeout = client.httpClient.Timeout + } + + if reqConnectTimeout != 0*time.Millisecond { + connectTimeout = reqConnectTimeout + } else if client.connectTimeout != 0*time.Millisecond { + connectTimeout = client.connectTimeout + } + return readTimeout, connectTimeout +} + +func Timeout(connectTimeout time.Duration) func(cxt context.Context, net, addr string) (c net.Conn, err error) { + return func(ctx context.Context, network, address string) (net.Conn, error) { + return (&net.Dialer{ + Timeout: connectTimeout, + DualStack: true, + }).DialContext(ctx, network, address) + } +} + +func (client *Client) setTimeout(request requests.AcsRequest) { + readTimeout, connectTimeout := client.getTimeout(request) + client.httpClient.Timeout = readTimeout + if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil { + trans.DialContext = Timeout(connectTimeout) + client.httpClient.Transport = trans + } else { + client.httpClient.Transport = &http.Transport{ + DialContext: Timeout(connectTimeout), + } + } +} + +func (client *Client) getHTTPSInsecure(request requests.AcsRequest) (insecure bool) { + if request.GetHTTPSInsecure() != nil { + insecure = *request.GetHTTPSInsecure() + } else { + insecure = client.GetHTTPSInsecure() + } + return insecure +} + +func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) { + + fieldMap := make(map[string]string) + initLogMsg(fieldMap) + defer func() { + client.printLog(fieldMap, err) + }() + httpRequest, err := client.buildRequestWithSigner(request, signer) + if err != nil { + return + } + + client.setTimeout(request) + proxy, err := client.getHttpProxy(httpRequest.URL.Scheme) + if err != nil { + return err + } + + noProxy := client.getNoProxy(httpRequest.URL.Scheme) + + var flag bool + for _, value := range noProxy { + if value == httpRequest.Host { + flag = true + break + } + } + + // Set whether to ignore certificate validation. + // Default InsecureSkipVerify is false. + if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil { + trans.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: client.getHTTPSInsecure(request), + } + if proxy != nil && !flag { + trans.Proxy = http.ProxyURL(proxy) + } + client.httpClient.Transport = trans + } + + var httpResponse *http.Response + for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ { + if proxy != nil && proxy.User != nil { + if password, passwordSet := proxy.User.Password(); passwordSet { + httpRequest.SetBasicAuth(proxy.User.Username(), password) + } + } + if retryTimes > 0 { + client.printLog(fieldMap, err) + initLogMsg(fieldMap) + } + putMsgToMap(fieldMap, httpRequest) + debug("> %s %s %s", httpRequest.Method, httpRequest.URL.RequestURI(), httpRequest.Proto) + debug("> Host: %s", httpRequest.Host) + for key, value := range httpRequest.Header { + debug("> %s: %v", key, strings.Join(value, "")) + } + debug(">") + debug(" Retry Times: %d.", retryTimes) + + startTime := time.Now() + fieldMap["{start_time}"] = startTime.Format("2006-01-02 15:04:05") + httpResponse, err = hookDo(client.httpClient.Do)(httpRequest) + fieldMap["{cost}"] = time.Now().Sub(startTime).String() + if err == nil { + fieldMap["{code}"] = strconv.Itoa(httpResponse.StatusCode) + fieldMap["{res_headers}"] = TransToString(httpResponse.Header) + debug("< %s %s", httpResponse.Proto, httpResponse.Status) + for key, value := range httpResponse.Header { + debug("< %s: %v", key, strings.Join(value, "")) + } + } + debug("<") + // receive error + if err != nil { + debug(" Error: %s.", err.Error()) + if !client.config.AutoRetry { + return + } else if retryTimes >= client.config.MaxRetryTime { + // timeout but reached the max retry times, return + times := strconv.Itoa(retryTimes + 1) + timeoutErrorMsg := fmt.Sprintf(errors.TimeoutErrorMessage, times, times) + if strings.Contains(err.Error(), "Client.Timeout") { + timeoutErrorMsg += " Read timeout. Please set a valid ReadTimeout." + } else { + timeoutErrorMsg += " Connect timeout. Please set a valid ConnectTimeout." + } + err = errors.NewClientError(errors.TimeoutErrorCode, timeoutErrorMsg, err) + return + } + } + // if status code >= 500 or timeout, will trigger retry + if client.config.AutoRetry && (err != nil || isServerError(httpResponse)) { + client.setTimeout(request) + // rewrite signatureNonce and signature + httpRequest, err = client.buildRequestWithSigner(request, signer) + // buildHttpRequest(request, finalSigner, regionId) + if err != nil { + return + } + continue + } + break + } + + err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat()) + // wrap server errors + if serverErr, ok := err.(*errors.ServerError); ok { + var wrapInfo = map[string]string{} + wrapInfo["StringToSign"] = request.GetStringToSign() + err = errors.WrapServerError(serverErr, wrapInfo) + } + return +} + +func putMsgToMap(fieldMap map[string]string, request *http.Request) { + fieldMap["{host}"] = request.Host + fieldMap["{method}"] = request.Method + fieldMap["{uri}"] = request.URL.RequestURI() + fieldMap["{pid}"] = strconv.Itoa(os.Getpid()) + fieldMap["{version}"] = strings.Split(request.Proto, "/")[1] + hostname, _ := os.Hostname() + fieldMap["{hostname}"] = hostname + fieldMap["{req_headers}"] = TransToString(request.Header) + fieldMap["{target}"] = request.URL.Path + request.URL.RawQuery +} + +func buildHttpRequest(request requests.AcsRequest, singer auth.Signer, regionId string) (httpRequest *http.Request, err error) { + err = auth.Sign(request, singer, regionId) + if err != nil { + return + } + requestMethod := request.GetMethod() + requestUrl := request.BuildUrl() + body := request.GetBodyReader() + httpRequest, err = http.NewRequest(requestMethod, requestUrl, body) + if err != nil { + return + } + for key, value := range request.GetHeaders() { + httpRequest.Header[key] = []string{value} + } + // host is a special case + if host, containsHost := request.GetHeaders()["Host"]; containsHost { + httpRequest.Host = host + } + return +} + +func isServerError(httpResponse *http.Response) bool { + return httpResponse.StatusCode >= http.StatusInternalServerError +} + +/** +only block when any one of the following occurs: +1. the asyncTaskQueue is full, increase the queue size to avoid this +2. Shutdown() in progressing, the client is being closed +**/ +func (client *Client) AddAsyncTask(task func()) (err error) { + if client.asyncTaskQueue != nil { + client.asyncChanLock.RLock() + defer client.asyncChanLock.RUnlock() + if client.isRunning { + client.asyncTaskQueue <- task + } + } else { + err = errors.NewClientError(errors.AsyncFunctionNotEnabledCode, errors.AsyncFunctionNotEnabledMessage, nil) + } + return +} + +func (client *Client) GetConfig() *Config { + return client.config +} + +func NewClient() (client *Client, err error) { + client = &Client{} + err = client.Init() + return +} + +func NewClientWithProvider(regionId string, providers ...provider.Provider) (client *Client, err error) { + client = &Client{} + var pc provider.Provider + if len(providers) == 0 { + pc = provider.DefaultChain + } else { + pc = provider.NewProviderChain(providers) + } + err = client.InitWithProviderChain(regionId, pc) + return +} + +func NewClientWithOptions(regionId string, config *Config, credential auth.Credential) (client *Client, err error) { + client = &Client{} + err = client.InitWithOptions(regionId, config, credential) + return +} + +func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (client *Client, err error) { + client = &Client{} + err = client.InitWithAccessKey(regionId, accessKeyId, accessKeySecret) + return +} + +func NewClientWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken string) (client *Client, err error) { + client = &Client{} + err = client.InitWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken) + return +} + +func NewClientWithRamRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName) + return +} + +func NewClientWithRamRoleArnAndPolicy(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string) (client *Client, err error) { + client = &Client{} + err = client.InitWithRamRoleArnAndPolicy(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy) + return +} + +func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithEcsRamRole(regionId, roleName) + return +} + +func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, sessionExpiration int) (client *Client, err error) { + client = &Client{} + err = client.InitWithRsaKeyPair(regionId, publicKeyId, privateKey, sessionExpiration) + return +} + +func NewClientWithBearerToken(regionId, bearerToken string) (client *Client, err error) { + client = &Client{} + err = client.InitWithBearerToken(regionId, bearerToken) + return +} + +func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + request.TransToAcsRequest() + response = responses.NewCommonResponse() + err = client.DoAction(request, response) + return +} + +func (client *Client) ProcessCommonRequestWithSigner(request *requests.CommonRequest, signerInterface interface{}) (response *responses.CommonResponse, err error) { + if signer, isSigner := signerInterface.(auth.Signer); isSigner { + request.TransToAcsRequest() + response = responses.NewCommonResponse() + err = client.DoActionWithSigner(request, response, signer) + return + } + panic("should not be here") +} + +func (client *Client) Shutdown() { + // lock the addAsync() + client.asyncChanLock.Lock() + defer client.asyncChanLock.Unlock() + if client.asyncTaskQueue != nil { + close(client.asyncTaskQueue) + } + client.isRunning = false +} + +// Deprecated: Use NewClientWithRamRoleArn in this package instead. +func NewClientWithStsRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) { + return NewClientWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName) +} + +// Deprecated: Use NewClientWithEcsRamRole in this package instead. +func NewClientWithStsRoleNameOnEcs(regionId string, roleName string) (client *Client, err error) { + return NewClientWithEcsRamRole(regionId, roleName) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go new file mode 100644 index 00000000..e8862e0c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go @@ -0,0 +1,91 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sdk + +import ( + "net/http" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +type Config struct { + AutoRetry bool `default:"true"` + MaxRetryTime int `default:"3"` + UserAgent string `default:""` + Debug bool `default:"false"` + Timeout time.Duration `default:"10000000000"` + HttpTransport *http.Transport `default:""` + EnableAsync bool `default:"false"` + MaxTaskQueueSize int `default:"1000"` + GoRoutinePoolSize int `default:"5"` + Scheme string `default:"HTTP"` +} + +func NewConfig() (config *Config) { + config = &Config{} + utils.InitStructWithDefaultTag(config) + return +} + +func (c *Config) WithAutoRetry(isAutoRetry bool) *Config { + c.AutoRetry = isAutoRetry + return c +} + +func (c *Config) WithMaxRetryTime(maxRetryTime int) *Config { + c.MaxRetryTime = maxRetryTime + return c +} + +func (c *Config) WithUserAgent(userAgent string) *Config { + c.UserAgent = userAgent + return c +} + +func (c *Config) WithDebug(isDebug bool) *Config { + c.Debug = isDebug + return c +} + +func (c *Config) WithTimeout(timeout time.Duration) *Config { + c.Timeout = timeout + return c +} + +func (c *Config) WithHttpTransport(httpTransport *http.Transport) *Config { + c.HttpTransport = httpTransport + return c +} + +func (c *Config) WithEnableAsync(isEnableAsync bool) *Config { + c.EnableAsync = isEnableAsync + return c +} + +func (c *Config) WithMaxTaskQueueSize(maxTaskQueueSize int) *Config { + c.MaxTaskQueueSize = maxTaskQueueSize + return c +} + +func (c *Config) WithGoRoutinePoolSize(goRoutinePoolSize int) *Config { + c.GoRoutinePoolSize = goRoutinePoolSize + return c +} + +func (c *Config) WithScheme(scheme string) *Config { + c.Scheme = scheme + return c +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go new file mode 100644 index 00000000..d1409844 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go @@ -0,0 +1,4126 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "sync" +) + +const endpointsJson = `{ + "products": [ + { + "code": "emr", + "document_id": "28140", + "location_service_code": "emr", + "regional_endpoints": [ + { + "region": "cn-qingdao", + "endpoint": "emr.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "emr.eu-west-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "emr.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "emr.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "emr.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "emr.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "emr.ap-south-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "emr.us-east-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "emr.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "emr.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "emr.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "emr.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "emr.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "emr.aliyuncs.com" + } + ], + "global_endpoint": "emr.aliyuncs.com", + "regional_endpoint_pattern": "emr.[RegionId].aliyuncs.com" + }, + { + "code": "petadata", + "document_id": "", + "location_service_code": "petadata", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "petadata.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "petadata.ap-southeast-2.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "petadata.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "petadata.ap-southeast-5.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "petadata.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "petadata.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "petadata.aliyuncs.com" + } + ], + "global_endpoint": "petadata.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "dbs", + "document_id": "", + "location_service_code": "dbs", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dbs-api.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dbs-api.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alidnsgtm", + "document_id": "", + "location_service_code": "alidnsgtm", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "alidns.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "alidns.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "elasticsearch", + "document_id": "", + "location_service_code": "elasticsearch", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "elasticsearch.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "elasticsearch.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "elasticsearch.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "elasticsearch.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "elasticsearch.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "elasticsearch.ap-southeast-3.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "elasticsearch.us-west-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "elasticsearch.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "elasticsearch.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "elasticsearch.eu-central-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "elasticsearch.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "elasticsearch.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "elasticsearch.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "elasticsearch.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "elasticsearch.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "baas", + "document_id": "", + "location_service_code": "baas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "baas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "baas.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "baas.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "baas.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "baas.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "baas.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cr", + "document_id": "60716", + "location_service_code": "cr", + "regional_endpoints": null, + "global_endpoint": "cr.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudap", + "document_id": "", + "location_service_code": "cloudap", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudwf.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "imagesearch", + "document_id": "", + "location_service_code": "imagesearch", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "imagesearch.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "imagesearch.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "imagesearch.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "imagesearch.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "pts", + "document_id": "", + "location_service_code": "pts", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "pts.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ehs", + "document_id": "", + "location_service_code": "ehs", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "ehpc.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ehpc.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ehpc.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ehpc.cn-qingdao.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ehpc.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ehpc.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "ehpc.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ehpc.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ehpc.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ehpc.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ehpc.ap-southeast-2.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "polardb", + "document_id": "58764", + "location_service_code": "polardb", + "regional_endpoints": [ + { + "region": "ap-south-1", + "endpoint": "polardb.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "polardb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "polardb.ap-southeast-5.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "polardb.aliyuncs.com" + }, + { + "code": "r-kvstore", + "document_id": "60831", + "location_service_code": "redisa", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "r-kvstore.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "r-kvstore.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "r-kvstore.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "r-kvstore.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "r-kvstore.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "r-kvstore.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "r-kvstore.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "r-kvstore.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "r-kvstore.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "r-kvstore.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "r-kvstore.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "r-kvstore.ap-southeast-5.aliyuncs.com" + } + ], + "global_endpoint": "r-kvstore.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "xianzhi", + "document_id": "", + "location_service_code": "xianzhi", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "xianzhi.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "pcdn", + "document_id": "", + "location_service_code": "pcdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "pcdn.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cdn", + "document_id": "27148", + "location_service_code": "cdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cdn.aliyuncs.com" + } + ], + "global_endpoint": "cdn.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudauth", + "document_id": "60687", + "location_service_code": "cloudauth", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudauth.aliyuncs.com" + } + ], + "global_endpoint": "cloudauth.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "nas", + "document_id": "62598", + "location_service_code": "nas", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "nas.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "nas.ap-south-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "nas.eu-central-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "nas.us-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "nas.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "nas.cn-qingdao.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "nas.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "nas.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "nas.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "nas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "nas.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "nas.ap-northeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "nas.us-east-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "nas.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "nas.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "nas.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "nas.ap-southeast-3.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alidns", + "document_id": "29739", + "location_service_code": "alidns", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "alidns.aliyuncs.com" + } + ], + "global_endpoint": "alidns.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "dts", + "document_id": "", + "location_service_code": "dts", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dts.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "emas", + "document_id": "", + "location_service_code": "emas", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "mhub.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "mhub.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dysmsapi", + "document_id": "", + "location_service_code": "dysmsapi", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-chengdu", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dysmsapi.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudwf", + "document_id": "58111", + "location_service_code": "cloudwf", + "regional_endpoints": null, + "global_endpoint": "cloudwf.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "fc", + "document_id": "", + "location_service_code": "fc", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "cn-beijing.fc.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ap-southeast-2.fc.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "cn-huhehaote.fc.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "cn-shanghai.fc.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "cn-hangzhou.fc.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "cn-shenzhen.fc.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "saf", + "document_id": "", + "location_service_code": "saf", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "saf.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "saf.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "saf.cn-shenzhen.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "rds", + "document_id": "26223", + "location_service_code": "rds", + "regional_endpoints": [ + { + "region": "ap-northeast-1", + "endpoint": "rds.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "rds.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "rds.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "rds.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "rds.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "rds.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "rds.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "rds.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "rds.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "rds.me-east-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "rds.aliyuncs.com" + } + ], + "global_endpoint": "rds.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "vpc", + "document_id": "34962", + "location_service_code": "vpc", + "regional_endpoints": [ + { + "region": "ap-south-1", + "endpoint": "vpc.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "vpc.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "vpc.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "vpc.cn-huhehaote.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "vpc.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "vpc.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "vpc.ap-southeast-3.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "vpc.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "vpc.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "vpc.eu-west-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "vpc.aliyuncs.com" + } + ], + "global_endpoint": "vpc.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "gpdb", + "document_id": "", + "location_service_code": "gpdb", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "gpdb.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "gpdb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "gpdb.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "gpdb.ap-southeast-2.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "gpdb.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "gpdb.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "gpdb.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "gpdb.eu-west-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "gpdb.ap-south-1.aliyuncs.com" + } + ], + "global_endpoint": "gpdb.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "yunmarket", + "document_id": "", + "location_service_code": "yunmarket", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "market.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "pvtz", + "document_id": "", + "location_service_code": "pvtz", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "pvtz.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "pvtz.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "oss", + "document_id": "", + "location_service_code": "oss", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "oss-cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "oss-cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "oss-cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "oss-cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "oss-cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "oss-ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "oss-us-west-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "oss-cn-qingdao.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "foas", + "document_id": "", + "location_service_code": "foas", + "regional_endpoints": [ + { + "region": "cn-qingdao", + "endpoint": "foas.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "foas.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "foas.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "foas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "foas.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "foas.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "foas.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddos", + "document_id": "", + "location_service_code": "ddos", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ddospro.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ddospro.cn-hongkong.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cbn", + "document_id": "", + "location_service_code": "cbn", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "cbn.aliyuncs.com" + } + ], + "global_endpoint": "cbn.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "nlp", + "document_id": "", + "location_service_code": "nlp", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "nlp.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hsm", + "document_id": "", + "location_service_code": "hsm", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "hsm.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ons", + "document_id": "44416", + "location_service_code": "ons", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "ons.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "ons.cn-huhehaote.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ons.us-east-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ons.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ons.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ons.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ons.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ons.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ons.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "ons.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ons.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ons.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ons.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ons.eu-central-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ons.eu-west-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ons.us-west-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ons.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ons.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "kms", + "document_id": "", + "location_service_code": "kms", + "regional_endpoints": [ + { + "region": "cn-hongkong", + "endpoint": "kms.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "kms.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "kms.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "kms.cn-qingdao.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "kms.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "kms.us-east-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "kms.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "kms.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "kms.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "kms.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "kms.cn-huhehaote.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "kms.me-east-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "kms.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "kms.ap-southeast-3.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "kms.us-west-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "kms.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "kms.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "kms.eu-central-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "kms.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cps", + "document_id": "", + "location_service_code": "cps", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudpush.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ensdisk", + "document_id": "", + "location_service_code": "ensdisk", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ens.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudapi", + "document_id": "43590", + "location_service_code": "apigateway", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "apigateway.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "apigateway.ap-south-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "apigateway.us-east-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "apigateway.me-east-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "apigateway.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "apigateway.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "apigateway.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "apigateway.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "apigateway.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "apigateway.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "apigateway.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "apigateway.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "apigateway.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "apigateway.us-west-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "apigateway.cn-shenzhen.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "apigateway.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "apigateway.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "apigateway.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "apigateway.cn-hongkong.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "apigateway.[RegionId].aliyuncs.com" + }, + { + "code": "eci", + "document_id": "", + "location_service_code": "eci", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "eci.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "onsvip", + "document_id": "", + "location_service_code": "onsvip", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "ons.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ons.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ons.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ons.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ons.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ons.cn-qingdao.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "linkwan", + "document_id": "", + "location_service_code": "linkwan", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "linkwan.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "linkwan.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosdip", + "document_id": "", + "location_service_code": "ddosdip", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "ddosdip.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "batchcompute", + "document_id": "44717", + "location_service_code": "batchcompute", + "regional_endpoints": [ + { + "region": "us-west-1", + "endpoint": "batchcompute.us-west-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "batchcompute.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "batchcompute.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "batchcompute.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "batchcompute.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "batchcompute.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "batchcompute.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "batchcompute.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "batchcompute.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "batchcompute.[RegionId].aliyuncs.com" + }, + { + "code": "aegis", + "document_id": "28449", + "location_service_code": "vipaegis", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "aegis.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "aegis.ap-southeast-3.aliyuncs.com" + } + ], + "global_endpoint": "aegis.cn-hangzhou.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "arms", + "document_id": "42924", + "location_service_code": "arms", + "regional_endpoints": [ + { + "region": "cn-hongkong", + "endpoint": "arms.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "arms.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "arms.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "arms.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "arms.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "arms.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "arms.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "arms.[RegionId].aliyuncs.com" + }, + { + "code": "live", + "document_id": "48207", + "location_service_code": "live", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "live.aliyuncs.com" + } + ], + "global_endpoint": "live.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "alimt", + "document_id": "", + "location_service_code": "alimt", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "mt.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "actiontrail", + "document_id": "", + "location_service_code": "actiontrail", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "actiontrail.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "actiontrail.cn-qingdao.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "actiontrail.us-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "actiontrail.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "actiontrail.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "actiontrail.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "actiontrail.ap-south-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "actiontrail.me-east-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "actiontrail.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "actiontrail.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "actiontrail.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "actiontrail.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "actiontrail.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "actiontrail.ap-northeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "actiontrail.us-west-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "actiontrail.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "actiontrail.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "actiontrail.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "actiontrail.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "smartag", + "document_id": "", + "location_service_code": "smartag", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "smartag.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "smartag.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "smartag.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "smartag.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "smartag.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "smartag.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "smartag.ap-southeast-2.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "vod", + "document_id": "60574", + "location_service_code": "vod", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "vod.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "vod.eu-central-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "domain", + "document_id": "42875", + "location_service_code": "domain", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "domain-intl.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "domain.aliyuncs.com" + } + ], + "global_endpoint": "domain.aliyuncs.com", + "regional_endpoint_pattern": "domain.aliyuncs.com" + }, + { + "code": "ros", + "document_id": "28899", + "location_service_code": "ros", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ros.aliyuncs.com" + } + ], + "global_endpoint": "ros.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudphoto", + "document_id": "59902", + "location_service_code": "cloudphoto", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "cloudphoto.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "cloudphoto.[RegionId].aliyuncs.com" + }, + { + "code": "rtc", + "document_id": "", + "location_service_code": "rtc", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "rtc.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "odpsmayi", + "document_id": "", + "location_service_code": "odpsmayi", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "bsb.cloud.alipay.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "bsb.cloud.alipay.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ims", + "document_id": "", + "location_service_code": "ims", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ims.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "csb", + "document_id": "64837", + "location_service_code": "csb", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "csb.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "csb.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "csb.[RegionId].aliyuncs.com" + }, + { + "code": "cds", + "document_id": "62887", + "location_service_code": "codepipeline", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "cds.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "cds.cn-beijing.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosbgp", + "document_id": "", + "location_service_code": "ddosbgp", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ddosbgp.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ddosbgp.us-west-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dybaseapi", + "document_id": "", + "location_service_code": "dybaseapi", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-chengdu", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ecs", + "document_id": "25484", + "location_service_code": "ecs", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "ecs.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ecs.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ecs.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ecs.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ecs.ap-southeast-3.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ecs.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ecs.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ecs.eu-west-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "ecs.me-east-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "ecs.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "ecs-cn-hangzhou.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "ccc", + "document_id": "63027", + "location_service_code": "ccc", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ccc.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ccc.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "ccc.[RegionId].aliyuncs.com" + }, + { + "code": "cs", + "document_id": "26043", + "location_service_code": "cs", + "regional_endpoints": null, + "global_endpoint": "cs.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "drdspre", + "document_id": "", + "location_service_code": "drdspre", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "drds.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "drds.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "drds.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "drds.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "drds.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dcdn", + "document_id": "", + "location_service_code": "dcdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "dcdn.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dcdn.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "linkedmall", + "document_id": "", + "location_service_code": "linkedmall", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "linkedmall.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "linkedmall.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "trademark", + "document_id": "", + "location_service_code": "trademark", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "trademark.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "openanalytics", + "document_id": "", + "location_service_code": "openanalytics", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "openanalytics.cn-shenzhen.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "openanalytics.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "openanalytics.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "openanalytics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "openanalytics.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "openanalytics.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "openanalytics.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "openanalytics.cn-zhangjiakou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "sts", + "document_id": "28756", + "location_service_code": "sts", + "regional_endpoints": null, + "global_endpoint": "sts.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "waf", + "document_id": "62847", + "location_service_code": "waf", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "wafopenapi.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ots", + "document_id": "", + "location_service_code": "ots", + "regional_endpoints": [ + { + "region": "me-east-1", + "endpoint": "ots.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "ots.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ots.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "ots.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ots.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ots.ap-southeast-2.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ots.us-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ots.us-east-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ots.ap-south-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ots.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ots.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ots.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ots.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ots.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ots.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ots.ap-southeast-3.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudfirewall", + "document_id": "", + "location_service_code": "cloudfirewall", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudfw.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dm", + "document_id": "29434", + "location_service_code": "dm", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "dm.ap-southeast-2.aliyuncs.com" + } + ], + "global_endpoint": "dm.aliyuncs.com", + "regional_endpoint_pattern": "dm.[RegionId].aliyuncs.com" + }, + { + "code": "oas", + "document_id": "", + "location_service_code": "oas", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "cn-shenzhen.oas.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "cn-beijing.oas.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "cn-hangzhou.oas.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddoscoo", + "document_id": "", + "location_service_code": "ddoscoo", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ddoscoo.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "jaq", + "document_id": "35037", + "location_service_code": "jaq", + "regional_endpoints": null, + "global_endpoint": "jaq.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "iovcc", + "document_id": "", + "location_service_code": "iovcc", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "iovcc.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "sas-api", + "document_id": "28498", + "location_service_code": "sas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "sas.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "chatbot", + "document_id": "60760", + "location_service_code": "beebot", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "chatbot.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "chatbot.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "chatbot.[RegionId].aliyuncs.com" + }, + { + "code": "airec", + "document_id": "", + "location_service_code": "airec", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "airec.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "airec.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "airec.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dmsenterprise", + "document_id": "", + "location_service_code": "dmsenterprise", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dms-enterprise.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ivision", + "document_id": "", + "location_service_code": "ivision", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ivision.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ivision.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "odpsplusmayi", + "document_id": "", + "location_service_code": "odpsplusmayi", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "bsb.cloud.alipay.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "bsb.cloud.alipay.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "bsb.cloud.alipay.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "gameshield", + "document_id": "", + "location_service_code": "gameshield", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "gameshield.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "gameshield.cn-zhangjiakou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "scdn", + "document_id": "", + "location_service_code": "scdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "scdn.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hitsdb", + "document_id": "", + "location_service_code": "hitsdb", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "hitsdb.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hdm", + "document_id": "", + "location_service_code": "hdm", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "hdm-api.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "slb", + "document_id": "27565", + "location_service_code": "slb", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "slb.eu-west-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "slb.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "slb.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "slb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "slb.ap-south-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "slb.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "slb.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "slb.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "slb.me-east-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "slb.cn-zhangjiakou.aliyuncs.com" + } + ], + "global_endpoint": "slb.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "green", + "document_id": "28427", + "location_service_code": "green", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "green.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "green.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "green.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "green.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "green.us-west-1.aliyuncs.com" + } + ], + "global_endpoint": "green.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cccvn", + "document_id": "", + "location_service_code": "cccvn", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "voicenavigator.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosrewards", + "document_id": "", + "location_service_code": "ddosrewards", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ddosright.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "iot", + "document_id": "30557", + "location_service_code": "iot", + "regional_endpoints": [ + { + "region": "us-east-1", + "endpoint": "iot.us-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "iot.ap-northeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "iot.us-west-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "iot.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "iot.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "iot.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "iot.[RegionId].aliyuncs.com" + }, + { + "code": "bssopenapi", + "document_id": "", + "location_service_code": "bssopenapi", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "sca", + "document_id": "", + "location_service_code": "sca", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "qualitycheck.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "luban", + "document_id": "", + "location_service_code": "luban", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "luban.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "luban.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "drdspost", + "document_id": "", + "location_service_code": "drdspost", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "drds.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "drds.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "drds", + "document_id": "51111", + "location_service_code": "drds", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "drds.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "drds.aliyuncs.com", + "regional_endpoint_pattern": "drds.aliyuncs.com" + }, + { + "code": "httpdns", + "document_id": "52679", + "location_service_code": "httpdns", + "regional_endpoints": null, + "global_endpoint": "httpdns-api.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cas", + "document_id": "", + "location_service_code": "cas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cas.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "cas.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "cas.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "cas.eu-central-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "cas.me-east-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hpc", + "document_id": "35201", + "location_service_code": "hpc", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "hpc.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "hpc.aliyuncs.com" + } + ], + "global_endpoint": "hpc.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosbasic", + "document_id": "", + "location_service_code": "ddosbasic", + "regional_endpoints": [ + { + "region": "ap-south-1", + "endpoint": "antiddos-openapi.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "antiddos-openapi.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "antiddos-openapi.ap-southeast-3.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "antiddos-openapi.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "antiddos-openapi.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "antiddos-openapi.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "antiddos-openapi.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "antiddos-openapi.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "antiddos-openapi.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "antiddos-openapi.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "antiddos.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "clouddesktop", + "document_id": "", + "location_service_code": "clouddesktop", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "clouddesktop.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "clouddesktop.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "clouddesktop.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "clouddesktop.cn-shenzhen.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "uis", + "document_id": "", + "location_service_code": "uis", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "uis.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "imm", + "document_id": "", + "location_service_code": "imm", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "imm.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "imm.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "imm.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "imm.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "imm.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "imm.cn-shenzhen.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ens", + "document_id": "", + "location_service_code": "ens", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ens.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ram", + "document_id": "28672", + "location_service_code": "ram", + "regional_endpoints": null, + "global_endpoint": "ram.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "hcs_mgw", + "document_id": "", + "location_service_code": "hcs_mgw", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "mgw.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "mgw.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "mgw.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "itaas", + "document_id": "55759", + "location_service_code": "itaas", + "regional_endpoints": null, + "global_endpoint": "itaas.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "qualitycheck", + "document_id": "50807", + "location_service_code": "qualitycheck", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "qualitycheck.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alikafka", + "document_id": "", + "location_service_code": "alikafka", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "alikafka.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "alikafka.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "alikafka.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "alikafka.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "alikafka.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "alikafka.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "alikafka.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "alikafka.cn-qingdao.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "faas", + "document_id": "", + "location_service_code": "faas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "faas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "faas.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "faas.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "faas.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alidfs", + "document_id": "", + "location_service_code": "alidfs", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "dfs.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dfs.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cms", + "document_id": "28615", + "location_service_code": "cms", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "metrics.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "metrics.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "metrics.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "metrics.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "metrics.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "metrics.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "metrics.cn-hangzhou.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "domain-intl", + "document_id": "", + "location_service_code": "domain-intl", + "regional_endpoints": null, + "global_endpoint": "domain-intl.aliyuncs.com", + "regional_endpoint_pattern": "domain-intl.aliyuncs.com" + }, + { + "code": "kvstore", + "document_id": "", + "location_service_code": "kvstore", + "regional_endpoints": [ + { + "region": "ap-northeast-1", + "endpoint": "r-kvstore.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ccs", + "document_id": "", + "location_service_code": "ccs", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ccs.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ess", + "document_id": "25925", + "location_service_code": "ess", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "ess.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ess.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ess.eu-west-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "ess.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ess.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ess.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "ess.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ess.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ess.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ess.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ess.aliyuncs.com" + } + ], + "global_endpoint": "ess.aliyuncs.com", + "regional_endpoint_pattern": "ess.[RegionId].aliyuncs.com" + }, + { + "code": "dds", + "document_id": "61715", + "location_service_code": "dds", + "regional_endpoints": [ + { + "region": "me-east-1", + "endpoint": "mongodb.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "mongodb.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "mongodb.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "mongodb.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "mongodb.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "mongodb.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "mongodb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "mongodb.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "mongodb.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "mongodb.ap-south-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "mongodb.aliyuncs.com" + } + ], + "global_endpoint": "mongodb.aliyuncs.com", + "regional_endpoint_pattern": "mongodb.[RegionId].aliyuncs.com" + }, + { + "code": "mts", + "document_id": "29212", + "location_service_code": "mts", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "mts.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "mts.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "mts.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "mts.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "mts.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "mts.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "mts.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "mts.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "mts.us-west-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "mts.eu-central-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "mts.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "mts.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "push", + "document_id": "30074", + "location_service_code": "push", + "regional_endpoints": null, + "global_endpoint": "cloudpush.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "hcs_sgw", + "document_id": "", + "location_service_code": "hcs_sgw", + "regional_endpoints": [ + { + "region": "eu-central-1", + "endpoint": "sgw.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "sgw.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "sgw.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hbase", + "document_id": "", + "location_service_code": "hbase", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "hbase.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "hbase.ap-south-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "hbase.me-east-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "hbase.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "hbase.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "hbase.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "hbase.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "hbase.aliyuncs.com" + } + ], + "global_endpoint": "hbase.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "bastionhost", + "document_id": "", + "location_service_code": "bastionhost", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "yundun-bastionhost.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "vs", + "document_id": "", + "location_service_code": "vs", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "vs.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "vs.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + } + ] +}` + +var initOnce sync.Once +var data interface{} + +func getEndpointConfigData() interface{} { + initOnce.Do(func() { + err := json.Unmarshal([]byte(endpointsJson), &data) + if err != nil { + panic(fmt.Sprintf("init endpoint config data failed. %s", err)) + } + }) + return data +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go new file mode 100644 index 00000000..160e62cb --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go @@ -0,0 +1,43 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package endpoints + +import ( + "fmt" + "strings" + + "github.com/jmespath/go-jmespath" +) + +type LocalGlobalResolver struct { +} + +func (resolver *LocalGlobalResolver) GetName() (name string) { + name = "local global resolver" + return +} + +func (resolver *LocalGlobalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + // get the global endpoints configs + endpointExpression := fmt.Sprintf("products[?code=='%s'].global_endpoint", strings.ToLower(param.Product)) + endpointData, err := jmespath.Search(endpointExpression, getEndpointConfigData()) + if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 { + endpoint = endpointData.([]interface{})[0].(string) + support = len(endpoint) > 0 + return + } + support = false + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go new file mode 100644 index 00000000..7fee64d4 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go @@ -0,0 +1,48 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package endpoints + +import ( + "fmt" + "strings" + + "github.com/jmespath/go-jmespath" +) + +type LocalRegionalResolver struct { +} + +func (resolver *LocalRegionalResolver) GetName() (name string) { + name = "local regional resolver" + return +} + +func (resolver *LocalRegionalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + // get the regional endpoints configs + regionalExpression := fmt.Sprintf("products[?code=='%s'].regional_endpoints", strings.ToLower(param.Product)) + regionalData, err := jmespath.Search(regionalExpression, getEndpointConfigData()) + if err == nil && regionalData != nil && len(regionalData.([]interface{})) > 0 { + endpointExpression := fmt.Sprintf("[0][?region=='%s'].endpoint", strings.ToLower(param.RegionId)) + var endpointData interface{} + endpointData, err = jmespath.Search(endpointExpression, regionalData) + if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 { + endpoint = endpointData.([]interface{})[0].(string) + support = len(endpoint) > 0 + return + } + } + support = false + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go new file mode 100644 index 00000000..cc354cc4 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go @@ -0,0 +1,176 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package endpoints + +import ( + "encoding/json" + "sync" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" +) + +const ( + // EndpointCacheExpireTime ... + EndpointCacheExpireTime = 3600 //Seconds +) + +// Cache caches endpoint for specific product and region +type Cache struct { + sync.RWMutex + cache map[string]interface{} +} + +// Get ... +func (c *Cache) Get(k string) (v interface{}) { + c.RLock() + v = c.cache[k] + c.RUnlock() + return +} + +// Set ... +func (c *Cache) Set(k string, v interface{}) { + c.Lock() + c.cache[k] = v + c.Unlock() +} + +var lastClearTimePerProduct = &Cache{cache: make(map[string]interface{})} +var endpointCache = &Cache{cache: make(map[string]interface{})} + +// LocationResolver ... +type LocationResolver struct { +} + +func (resolver *LocationResolver) GetName() (name string) { + name = "location resolver" + return +} + +// TryResolve resolves endpoint giving product and region +func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + if len(param.LocationProduct) <= 0 { + support = false + return + } + + //get from cache + cacheKey := param.Product + "#" + param.RegionId + var ok bool + endpoint, ok = endpointCache.Get(cacheKey).(string) + + if ok && len(endpoint) > 0 && !CheckCacheIsExpire(cacheKey) { + support = true + return + } + + //get from remote + getEndpointRequest := requests.NewCommonRequest() + + getEndpointRequest.Product = "Location" + getEndpointRequest.Version = "2015-06-12" + getEndpointRequest.ApiName = "DescribeEndpoints" + getEndpointRequest.Domain = "location-readonly.aliyuncs.com" + getEndpointRequest.Method = "GET" + getEndpointRequest.Scheme = requests.HTTPS + + getEndpointRequest.QueryParams["Id"] = param.RegionId + getEndpointRequest.QueryParams["ServiceCode"] = param.LocationProduct + if len(param.LocationEndpointType) > 0 { + getEndpointRequest.QueryParams["Type"] = param.LocationEndpointType + } else { + getEndpointRequest.QueryParams["Type"] = "openAPI" + } + + response, err := param.CommonApi(getEndpointRequest) + if err != nil { + support = false + return + } + + if !response.IsSuccess() { + support = false + return + } + + var getEndpointResponse GetEndpointResponse + err = json.Unmarshal([]byte(response.GetHttpContentString()), &getEndpointResponse) + if err != nil { + support = false + return + } + + if !getEndpointResponse.Success || getEndpointResponse.Endpoints == nil { + support = false + return + } + if len(getEndpointResponse.Endpoints.Endpoint) <= 0 { + support = false + return + } + if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 { + endpoint = getEndpointResponse.Endpoints.Endpoint[0].Endpoint + endpointCache.Set(cacheKey, endpoint) + lastClearTimePerProduct.Set(cacheKey, time.Now().Unix()) + support = true + return + } + + support = false + return +} + +// CheckCacheIsExpire ... +func CheckCacheIsExpire(cacheKey string) bool { + lastClearTime, ok := lastClearTimePerProduct.Get(cacheKey).(int64) + if !ok { + return true + } + + if lastClearTime <= 0 { + lastClearTime = time.Now().Unix() + lastClearTimePerProduct.Set(cacheKey, lastClearTime) + } + + now := time.Now().Unix() + elapsedTime := now - lastClearTime + if elapsedTime > EndpointCacheExpireTime { + return true + } + + return false +} + +// GetEndpointResponse ... +type GetEndpointResponse struct { + Endpoints *EndpointsObj + RequestId string + Success bool +} + +// EndpointsObj ... +type EndpointsObj struct { + Endpoint []EndpointObj +} + +// EndpointObj ... +type EndpointObj struct { + // Protocols map[string]string + Type string + Namespace string + Id string + SerivceCode string + Endpoint string +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go new file mode 100644 index 00000000..e39f5336 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go @@ -0,0 +1,48 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package endpoints + +import ( + "fmt" + "strings" +) + +const keyFormatter = "%s::%s" + +var endpointMapping = make(map[string]string) + +// AddEndpointMapping Use product id and region id as key to store the endpoint into inner map +func AddEndpointMapping(regionId, productId, endpoint string) (err error) { + key := fmt.Sprintf(keyFormatter, strings.ToLower(regionId), strings.ToLower(productId)) + endpointMapping[key] = endpoint + return nil +} + +// MappingResolver the mapping resolver type +type MappingResolver struct { +} + +// GetName get the resolver name: "mapping resolver" +func (resolver *MappingResolver) GetName() (name string) { + name = "mapping resolver" + return +} + +// TryResolve use Product and RegionId as key to find endpoint from inner map +func (resolver *MappingResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + key := fmt.Sprintf(keyFormatter, strings.ToLower(param.RegionId), strings.ToLower(param.Product)) + endpoint, contains := endpointMapping[key] + return endpoint, contains, nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go new file mode 100644 index 00000000..5e1e3053 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go @@ -0,0 +1,98 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package endpoints + +import ( + "encoding/json" + "fmt" + "sync" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var debug utils.Debug + +func init() { + debug = utils.Init("sdk") +} + +const ( + ResolveEndpointUserGuideLink = "" +) + +var once sync.Once +var resolvers []Resolver + +type Resolver interface { + TryResolve(param *ResolveParam) (endpoint string, support bool, err error) + GetName() (name string) +} + +// Resolve resolve endpoint with params +// It will resolve with each supported resolver until anyone resolved +func Resolve(param *ResolveParam) (endpoint string, err error) { + supportedResolvers := getAllResolvers() + var lastErr error + for _, resolver := range supportedResolvers { + endpoint, supported, resolveErr := resolver.TryResolve(param) + if resolveErr != nil { + lastErr = resolveErr + } + + if supported { + debug("resolve endpoint with %s\n", param) + debug("\t%s by resolver(%s)\n", endpoint, resolver.GetName()) + return endpoint, nil + } + } + + // not support + errorMsg := fmt.Sprintf(errors.CanNotResolveEndpointErrorMessage, param, ResolveEndpointUserGuideLink) + err = errors.NewClientError(errors.CanNotResolveEndpointErrorCode, errorMsg, lastErr) + return +} + +func getAllResolvers() []Resolver { + once.Do(func() { + resolvers = []Resolver{ + &SimpleHostResolver{}, + &MappingResolver{}, + &LocationResolver{}, + &LocalRegionalResolver{}, + &LocalGlobalResolver{}, + } + }) + return resolvers +} + +type ResolveParam struct { + Domain string + Product string + RegionId string + LocationProduct string + LocationEndpointType string + CommonApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) `json:"-"` +} + +func (param *ResolveParam) String() string { + jsonBytes, err := json.Marshal(param) + if err != nil { + return fmt.Sprint("ResolveParam.String() process error:", err) + } + return string(jsonBytes) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go new file mode 100644 index 00000000..9ba2346c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go @@ -0,0 +1,33 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package endpoints + +// SimpleHostResolver the simple host resolver type +type SimpleHostResolver struct { +} + +// GetName get the resolver name: "simple host resolver" +func (resolver *SimpleHostResolver) GetName() (name string) { + name = "simple host resolver" + return +} + +// TryResolve if the Domain exist in param, use it as endpoint +func (resolver *SimpleHostResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + if support = len(param.Domain) > 0; support { + endpoint = param.Domain + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go new file mode 100644 index 00000000..1e2d9c00 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go @@ -0,0 +1,92 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package errors + +import "fmt" + +const ( + DefaultClientErrorStatus = 400 + DefaultClientErrorCode = "SDK.ClientError" + + UnsupportedCredentialErrorCode = "SDK.UnsupportedCredential" + UnsupportedCredentialErrorMessage = "Specified credential (type = %s) is not supported, please check" + + CanNotResolveEndpointErrorCode = "SDK.CanNotResolveEndpoint" + CanNotResolveEndpointErrorMessage = "Can not resolve endpoint(param = %s), please check your accessKey with secret, and read the user guide\n %s" + + UnsupportedParamPositionErrorCode = "SDK.UnsupportedParamPosition" + UnsupportedParamPositionErrorMessage = "Specified param position (%s) is not supported, please upgrade sdk and retry" + + AsyncFunctionNotEnabledCode = "SDK.AsyncFunctionNotEnabled" + AsyncFunctionNotEnabledMessage = "Async function is not enabled in client, please invoke 'client.EnableAsync' function" + + UnknownRequestTypeErrorCode = "SDK.UnknownRequestType" + UnknownRequestTypeErrorMessage = "Unknown Request Type: %s" + + MissingParamErrorCode = "SDK.MissingParam" + InvalidParamErrorCode = "SDK.InvalidParam" + + JsonUnmarshalErrorCode = "SDK.JsonUnmarshalError" + JsonUnmarshalErrorMessage = "Failed to unmarshal response, but you can get the data via response.GetHttpStatusCode() and response.GetHttpContentString()" + + TimeoutErrorCode = "SDK.TimeoutError" + TimeoutErrorMessage = "The request timed out %s times(%s for retry), perhaps we should have the threshold raised a little?" +) + +type ClientError struct { + errorCode string + message string + originError error +} + +func NewClientError(errorCode, message string, originErr error) Error { + return &ClientError{ + errorCode: errorCode, + message: message, + originError: originErr, + } +} + +func (err *ClientError) Error() string { + clientErrMsg := fmt.Sprintf("[%s] %s", err.ErrorCode(), err.message) + if err.originError != nil { + return clientErrMsg + "\ncaused by:\n" + err.originError.Error() + } + return clientErrMsg +} + +func (err *ClientError) OriginError() error { + return err.originError +} + +func (*ClientError) HttpStatus() int { + return DefaultClientErrorStatus +} + +func (err *ClientError) ErrorCode() string { + if err.errorCode == "" { + return DefaultClientErrorCode + } else { + return err.errorCode + } +} + +func (err *ClientError) Message() string { + return err.message +} + +func (err *ClientError) String() string { + return err.Error() +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go new file mode 100644 index 00000000..49962f3b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go @@ -0,0 +1,23 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package errors + +type Error interface { + error + HttpStatus() int + ErrorCode() string + Message() string + OriginError() error +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go new file mode 100644 index 00000000..1b781041 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go @@ -0,0 +1,123 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package errors + +import ( + "encoding/json" + "fmt" + + "github.com/jmespath/go-jmespath" +) + +var wrapperList = []ServerErrorWrapper{ + &SignatureDostNotMatchWrapper{}, +} + +type ServerError struct { + httpStatus int + requestId string + hostId string + errorCode string + recommend string + message string + comment string +} + +type ServerErrorWrapper interface { + tryWrap(error *ServerError, wrapInfo map[string]string) bool +} + +func (err *ServerError) Error() string { + return fmt.Sprintf("SDK.ServerError\nErrorCode: %s\nRecommend: %s\nRequestId: %s\nMessage: %s", + err.errorCode, err.comment+err.recommend, err.requestId, err.message) +} + +func NewServerError(httpStatus int, responseContent, comment string) Error { + result := &ServerError{ + httpStatus: httpStatus, + message: responseContent, + comment: comment, + } + + var data interface{} + err := json.Unmarshal([]byte(responseContent), &data) + if err == nil { + requestId, _ := jmespath.Search("RequestId", data) + hostId, _ := jmespath.Search("HostId", data) + errorCode, _ := jmespath.Search("Code", data) + recommend, _ := jmespath.Search("Recommend", data) + message, _ := jmespath.Search("Message", data) + + if requestId != nil { + result.requestId = requestId.(string) + } + if hostId != nil { + result.hostId = hostId.(string) + } + if errorCode != nil { + result.errorCode = errorCode.(string) + } + if recommend != nil { + result.recommend = recommend.(string) + } + if message != nil { + result.message = message.(string) + } + } + + return result +} + +func WrapServerError(originError *ServerError, wrapInfo map[string]string) *ServerError { + for _, wrapper := range wrapperList { + ok := wrapper.tryWrap(originError, wrapInfo) + if ok { + return originError + } + } + return originError +} + +func (err *ServerError) HttpStatus() int { + return err.httpStatus +} + +func (err *ServerError) ErrorCode() string { + return err.errorCode +} + +func (err *ServerError) Message() string { + return err.message +} + +func (err *ServerError) OriginError() error { + return nil +} + +func (err *ServerError) HostId() string { + return err.hostId +} + +func (err *ServerError) RequestId() string { + return err.requestId +} + +func (err *ServerError) Recommend() string { + return err.recommend +} + +func (err *ServerError) Comment() string { + return err.comment +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go new file mode 100644 index 00000000..4b09d7d7 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go @@ -0,0 +1,45 @@ +package errors + +import ( + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +const SignatureDostNotMatchErrorCode = "SignatureDoesNotMatch" +const IncompleteSignatureErrorCode = "IncompleteSignature" +const MessageContain = "server string to sign is:" + +var debug utils.Debug + +func init() { + debug = utils.Init("sdk") +} + +type SignatureDostNotMatchWrapper struct { +} + +func (*SignatureDostNotMatchWrapper) tryWrap(error *ServerError, wrapInfo map[string]string) (ok bool) { + clientStringToSign := wrapInfo["StringToSign"] + if (error.errorCode == SignatureDostNotMatchErrorCode || error.errorCode == IncompleteSignatureErrorCode) && clientStringToSign != "" { + message := error.message + if strings.Contains(message, MessageContain) { + str := strings.Split(message, MessageContain) + serverStringToSign := str[1] + + if clientStringToSign == serverStringToSign { + // user secret is error + error.recommend = "InvalidAccessKeySecret: Please check you AccessKeySecret" + } else { + debug("Client StringToSign: %s", clientStringToSign) + debug("Server StringToSign: %s", serverStringToSign) + error.recommend = "This may be a bug with the SDK and we hope you can submit this question in the " + + "github issue(https://github.com/aliyun/alibaba-cloud-sdk-go/issues), thanks very much" + } + } + ok = true + return + } + ok = false + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go new file mode 100644 index 00000000..04f03393 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go @@ -0,0 +1,116 @@ +package sdk + +import ( + "encoding/json" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" + "io" + "log" + "os" + "strings" + "time" +) + +var logChannel string +var defaultChannel = "AlibabaCloud" + +type Logger struct { + *log.Logger + formatTemplate string + isOpen bool + lastLogMsg string +} + +var defaultLoggerTemplate = `{time} {channel}: "{method} {uri} HTTP/{version}" {code} {cost} {hostname}` +var loggerParam = []string{"{time}", "{start_time}", "{ts}", "{channel}", "{pid}", "{host}", "{method}", "{uri}", "{version}", "{target}", "{hostname}", "{code}", "{error}", "{req_headers}", "{res_headers}", "{cost}"} + +func initLogMsg(fieldMap map[string]string) { + for _, value := range loggerParam { + fieldMap[value] = "" + } +} + +func (client *Client) GetLogger() *Logger { + return client.logger +} + +func (client *Client) GetLoggerMsg() string { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + return client.logger.lastLogMsg +} + +func (client *Client) SetLogger(level string, channel string, out io.Writer, template string) { + if level == "" { + level = "info" + } + + logChannel = "AlibabaCloud" + if channel != "" { + logChannel = channel + } + log := log.New(out, "["+strings.ToUpper(level)+"]", log.Lshortfile) + if template == "" { + template = defaultLoggerTemplate + } + + client.logger = &Logger{ + Logger: log, + formatTemplate: template, + isOpen: true, + } +} + +func (client *Client) OpenLogger() { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + client.logger.isOpen = true +} + +func (client *Client) CloseLogger() { + if client.logger != nil { + client.logger.isOpen = false + } +} + +func (client *Client) SetTemplate(template string) { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + client.logger.formatTemplate = template +} + +func (client *Client) GetTemplate() string { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + return client.logger.formatTemplate +} + +func TransToString(object interface{}) string { + byt, err := json.Marshal(object) + if err != nil { + return "" + } + return string(byt) +} + +func (client *Client) printLog(fieldMap map[string]string, err error) { + if err != nil { + fieldMap["{error}"] = err.Error() + } + fieldMap["{time}"] = time.Now().Format("2006-01-02 15:04:05") + fieldMap["{ts}"] = utils.GetTimeInFormatISO8601() + fieldMap["{channel}"] = logChannel + if client.logger != nil { + logMsg := client.logger.formatTemplate + for key, value := range fieldMap { + logMsg = strings.Replace(logMsg, key, value, -1) + } + client.logger.lastLogMsg = logMsg + if client.logger.isOpen == true { + client.logger.Output(2, logMsg) + } + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go new file mode 100644 index 00000000..fa22db1f --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go @@ -0,0 +1,378 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package requests + +import ( + "encoding/json" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" +) + +const ( + RPC = "RPC" + ROA = "ROA" + + HTTP = "HTTP" + HTTPS = "HTTPS" + + DefaultHttpPort = "80" + + GET = "GET" + PUT = "PUT" + POST = "POST" + DELETE = "DELETE" + HEAD = "HEAD" + OPTIONS = "OPTIONS" + + Json = "application/json" + Xml = "application/xml" + Raw = "application/octet-stream" + Form = "application/x-www-form-urlencoded" + + Header = "Header" + Query = "Query" + Body = "Body" + Path = "Path" + + HeaderSeparator = "\n" +) + +// interface +type AcsRequest interface { + GetScheme() string + GetMethod() string + GetDomain() string + GetPort() string + GetRegionId() string + GetHeaders() map[string]string + GetQueryParams() map[string]string + GetFormParams() map[string]string + GetContent() []byte + GetBodyReader() io.Reader + GetStyle() string + GetProduct() string + GetVersion() string + SetVersion(version string) + GetActionName() string + GetAcceptFormat() string + GetLocationServiceCode() string + GetLocationEndpointType() string + GetReadTimeout() time.Duration + GetConnectTimeout() time.Duration + SetReadTimeout(readTimeout time.Duration) + SetConnectTimeout(connectTimeout time.Duration) + SetHTTPSInsecure(isInsecure bool) + GetHTTPSInsecure() *bool + + GetUserAgent() map[string]string + + SetStringToSign(stringToSign string) + GetStringToSign() string + + SetDomain(domain string) + SetContent(content []byte) + SetScheme(scheme string) + BuildUrl() string + BuildQueries() string + + addHeaderParam(key, value string) + addQueryParam(key, value string) + addFormParam(key, value string) + addPathParam(key, value string) +} + +// base class +type baseRequest struct { + Scheme string + Method string + Domain string + Port string + RegionId string + ReadTimeout time.Duration + ConnectTimeout time.Duration + isInsecure *bool + + userAgent map[string]string + product string + version string + + actionName string + + AcceptFormat string + + QueryParams map[string]string + Headers map[string]string + FormParams map[string]string + Content []byte + + locationServiceCode string + locationEndpointType string + + queries string + + stringToSign string +} + +func (request *baseRequest) GetQueryParams() map[string]string { + return request.QueryParams +} + +func (request *baseRequest) GetFormParams() map[string]string { + return request.FormParams +} + +func (request *baseRequest) GetReadTimeout() time.Duration { + return request.ReadTimeout +} + +func (request *baseRequest) GetConnectTimeout() time.Duration { + return request.ConnectTimeout +} + +func (request *baseRequest) SetReadTimeout(readTimeout time.Duration) { + request.ReadTimeout = readTimeout +} + +func (request *baseRequest) SetConnectTimeout(connectTimeout time.Duration) { + request.ConnectTimeout = connectTimeout +} + +func (request *baseRequest) GetHTTPSInsecure() *bool { + return request.isInsecure +} + +func (request *baseRequest) SetHTTPSInsecure(isInsecure bool) { + request.isInsecure = &isInsecure +} + +func (request *baseRequest) GetContent() []byte { + return request.Content +} + +func (request *baseRequest) SetVersion(version string) { + request.version = version +} + +func (request *baseRequest) GetVersion() string { + return request.version +} + +func (request *baseRequest) GetActionName() string { + return request.actionName +} + +func (request *baseRequest) SetContent(content []byte) { + request.Content = content +} + +func (request *baseRequest) GetUserAgent() map[string]string { + return request.userAgent +} + +func (request *baseRequest) AppendUserAgent(key, value string) { + newkey := true + if request.userAgent == nil { + request.userAgent = make(map[string]string) + } + if strings.ToLower(key) != "core" && strings.ToLower(key) != "go" { + for tag, _ := range request.userAgent { + if tag == key { + request.userAgent[tag] = value + newkey = false + } + } + if newkey { + request.userAgent[key] = value + } + } +} + +func (request *baseRequest) addHeaderParam(key, value string) { + request.Headers[key] = value +} + +func (request *baseRequest) addQueryParam(key, value string) { + request.QueryParams[key] = value +} + +func (request *baseRequest) addFormParam(key, value string) { + request.FormParams[key] = value +} + +func (request *baseRequest) GetAcceptFormat() string { + return request.AcceptFormat +} + +func (request *baseRequest) GetLocationServiceCode() string { + return request.locationServiceCode +} + +func (request *baseRequest) GetLocationEndpointType() string { + return request.locationEndpointType +} + +func (request *baseRequest) GetProduct() string { + return request.product +} + +func (request *baseRequest) GetScheme() string { + return request.Scheme +} + +func (request *baseRequest) SetScheme(scheme string) { + request.Scheme = scheme +} + +func (request *baseRequest) GetMethod() string { + return request.Method +} + +func (request *baseRequest) GetDomain() string { + return request.Domain +} + +func (request *baseRequest) SetDomain(host string) { + request.Domain = host +} + +func (request *baseRequest) GetPort() string { + return request.Port +} + +func (request *baseRequest) GetRegionId() string { + return request.RegionId +} + +func (request *baseRequest) GetHeaders() map[string]string { + return request.Headers +} + +func (request *baseRequest) SetContentType(contentType string) { + request.addHeaderParam("Content-Type", contentType) +} + +func (request *baseRequest) GetContentType() (contentType string, contains bool) { + contentType, contains = request.Headers["Content-Type"] + return +} + +func (request *baseRequest) SetStringToSign(stringToSign string) { + request.stringToSign = stringToSign +} + +func (request *baseRequest) GetStringToSign() string { + return request.stringToSign +} + +func defaultBaseRequest() (request *baseRequest) { + request = &baseRequest{ + Scheme: "", + AcceptFormat: "JSON", + Method: GET, + QueryParams: make(map[string]string), + Headers: map[string]string{ + "x-sdk-client": "golang/1.0.0", + "x-sdk-invoke-type": "normal", + "Accept-Encoding": "identity", + }, + FormParams: make(map[string]string), + } + return +} + +func InitParams(request AcsRequest) (err error) { + requestValue := reflect.ValueOf(request).Elem() + err = flatRepeatedList(requestValue, request, "", "") + return +} + +func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, prefix string) (err error) { + dataType := dataValue.Type() + for i := 0; i < dataType.NumField(); i++ { + field := dataType.Field(i) + name, containsNameTag := field.Tag.Lookup("name") + fieldPosition := position + if fieldPosition == "" { + fieldPosition, _ = field.Tag.Lookup("position") + } + typeTag, containsTypeTag := field.Tag.Lookup("type") + if containsNameTag { + if !containsTypeTag { + // simple param + key := prefix + name + value := dataValue.Field(i).String() + if dataValue.Field(i).Kind().String() == "map" { + byt, _ := json.Marshal(dataValue.Field(i).Interface()) + value = string(byt) + } + err = addParam(request, fieldPosition, key, value) + if err != nil { + return + } + } else if typeTag == "Repeated" { + // repeated param + repeatedFieldValue := dataValue.Field(i) + if repeatedFieldValue.Kind() != reflect.Slice { + // possible value: {"[]string", "*[]struct"}, we must call Elem() in the last condition + repeatedFieldValue = repeatedFieldValue.Elem() + } + if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() { + for m := 0; m < repeatedFieldValue.Len(); m++ { + elementValue := repeatedFieldValue.Index(m) + key := prefix + name + "." + strconv.Itoa(m+1) + if elementValue.Type().Kind().String() == "string" { + value := elementValue.String() + err = addParam(request, fieldPosition, key, value) + if err != nil { + return + } + } else { + err = flatRepeatedList(elementValue, request, fieldPosition, key+".") + if err != nil { + return + } + } + } + } + } + } + } + return +} + +func addParam(request AcsRequest, position, name, value string) (err error) { + if len(value) > 0 { + switch position { + case Header: + request.addHeaderParam(name, value) + case Query: + request.addQueryParam(name, value) + case Path: + request.addPathParam(name, value) + case Body: + request.addFormParam(name, value) + default: + errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position) + err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil) + } + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go new file mode 100644 index 00000000..80c17009 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go @@ -0,0 +1,108 @@ +package requests + +import ( + "bytes" + "fmt" + "io" + "sort" + "strings" +) + +type CommonRequest struct { + *baseRequest + + Version string + ApiName string + Product string + ServiceCode string + + // roa params + PathPattern string + PathParams map[string]string + + Ontology AcsRequest +} + +func NewCommonRequest() (request *CommonRequest) { + request = &CommonRequest{ + baseRequest: defaultBaseRequest(), + } + request.Headers["x-sdk-invoke-type"] = "common" + request.PathParams = make(map[string]string) + return +} + +func (request *CommonRequest) String() string { + request.TransToAcsRequest() + + resultBuilder := bytes.Buffer{} + + mapOutput := func(m map[string]string) { + if len(m) > 0 { + sortedKeys := make([]string, 0) + for k := range m { + sortedKeys = append(sortedKeys, k) + } + + // sort 'string' key in increasing order + sort.Strings(sortedKeys) + + for _, key := range sortedKeys { + resultBuilder.WriteString(key + ": " + m[key] + "\n") + } + } + } + + // Request Line + resultBuilder.WriteString(fmt.Sprintf("%s %s %s/1.1\n", request.Method, request.BuildQueries(), strings.ToUpper(request.Scheme))) + + // Headers + resultBuilder.WriteString("Host" + ": " + request.Domain + "\n") + mapOutput(request.Headers) + + resultBuilder.WriteString("\n") + // Body + if len(request.Content) > 0 { + resultBuilder.WriteString(string(request.Content) + "\n") + } else { + mapOutput(request.FormParams) + } + + return resultBuilder.String() +} + +func (request *CommonRequest) TransToAcsRequest() { + if len(request.PathPattern) > 0 { + roaRequest := &RoaRequest{} + roaRequest.initWithCommonRequest(request) + request.Ontology = roaRequest + } else { + rpcRequest := &RpcRequest{} + rpcRequest.baseRequest = request.baseRequest + rpcRequest.product = request.Product + rpcRequest.version = request.Version + rpcRequest.locationServiceCode = request.ServiceCode + rpcRequest.actionName = request.ApiName + request.Ontology = rpcRequest + } +} + +func (request *CommonRequest) BuildUrl() string { + return request.Ontology.BuildUrl() +} + +func (request *CommonRequest) BuildQueries() string { + return request.Ontology.BuildQueries() +} + +func (request *CommonRequest) GetBodyReader() io.Reader { + return request.Ontology.GetBodyReader() +} + +func (request *CommonRequest) GetStyle() string { + return request.Ontology.GetStyle() +} + +func (request *CommonRequest) addPathParam(key, value string) { + request.PathParams[key] = value +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go new file mode 100644 index 00000000..70b856e3 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go @@ -0,0 +1,152 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package requests + +import ( + "bytes" + "fmt" + "io" + "net/url" + "sort" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +type RoaRequest struct { + *baseRequest + pathPattern string + PathParams map[string]string +} + +func (*RoaRequest) GetStyle() string { + return ROA +} + +func (request *RoaRequest) GetBodyReader() io.Reader { + if request.FormParams != nil && len(request.FormParams) > 0 { + formString := utils.GetUrlFormedMap(request.FormParams) + return strings.NewReader(formString) + } else if len(request.Content) > 0 { + return bytes.NewReader(request.Content) + } else { + return nil + } +} + +// for sign method, need not url encoded +func (request *RoaRequest) BuildQueries() string { + return request.buildQueries() +} + +func (request *RoaRequest) buildPath() string { + path := request.pathPattern + for key, value := range request.PathParams { + path = strings.Replace(path, "["+key+"]", value, 1) + } + return path +} + +func (request *RoaRequest) buildQueries() string { + // replace path params with value + path := request.buildPath() + queryParams := request.QueryParams + // sort QueryParams by key + var queryKeys []string + for key := range queryParams { + queryKeys = append(queryKeys, key) + } + sort.Strings(queryKeys) + + // append urlBuilder + urlBuilder := bytes.Buffer{} + urlBuilder.WriteString(path) + if len(queryKeys) > 0 { + urlBuilder.WriteString("?") + } + for i := 0; i < len(queryKeys); i++ { + queryKey := queryKeys[i] + urlBuilder.WriteString(queryKey) + if value := queryParams[queryKey]; len(value) > 0 { + urlBuilder.WriteString("=") + urlBuilder.WriteString(value) + } + if i < len(queryKeys)-1 { + urlBuilder.WriteString("&") + } + } + result := urlBuilder.String() + result = popStandardUrlencode(result) + return result +} + +func (request *RoaRequest) buildQueryString() string { + queryParams := request.QueryParams + // sort QueryParams by key + q := url.Values{} + for key, value := range queryParams { + q.Add(key, value) + } + return q.Encode() +} + +func popStandardUrlencode(stringToSign string) (result string) { + result = strings.Replace(stringToSign, "+", "%20", -1) + result = strings.Replace(result, "*", "%2A", -1) + result = strings.Replace(result, "%7E", "~", -1) + return +} + +func (request *RoaRequest) BuildUrl() string { + // for network trans, need url encoded + scheme := strings.ToLower(request.Scheme) + domain := request.Domain + port := request.Port + path := request.buildPath() + url := fmt.Sprintf("%s://%s:%s%s", scheme, domain, port, path) + querystring := request.buildQueryString() + if len(querystring) > 0 { + url = fmt.Sprintf("%s?%s", url, querystring) + } + return url +} + +func (request *RoaRequest) addPathParam(key, value string) { + request.PathParams[key] = value +} + +func (request *RoaRequest) InitWithApiInfo(product, version, action, uriPattern, serviceCode, endpointType string) { + request.baseRequest = defaultBaseRequest() + request.PathParams = make(map[string]string) + request.Headers["x-acs-version"] = version + request.pathPattern = uriPattern + request.locationServiceCode = serviceCode + request.locationEndpointType = endpointType + request.product = product + //request.version = version + request.actionName = action +} + +func (request *RoaRequest) initWithCommonRequest(commonRequest *CommonRequest) { + request.baseRequest = commonRequest.baseRequest + request.PathParams = commonRequest.PathParams + request.product = commonRequest.Product + //request.version = commonRequest.Version + request.Headers["x-acs-version"] = commonRequest.Version + request.actionName = commonRequest.ApiName + request.pathPattern = commonRequest.PathPattern + request.locationServiceCode = commonRequest.ServiceCode + request.locationEndpointType = "" +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go new file mode 100644 index 00000000..01be6fd0 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go @@ -0,0 +1,79 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package requests + +import ( + "fmt" + "io" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +type RpcRequest struct { + *baseRequest +} + +func (request *RpcRequest) init() { + request.baseRequest = defaultBaseRequest() + request.Method = POST +} + +func (*RpcRequest) GetStyle() string { + return RPC +} + +func (request *RpcRequest) GetBodyReader() io.Reader { + if request.FormParams != nil && len(request.FormParams) > 0 { + formString := utils.GetUrlFormedMap(request.FormParams) + return strings.NewReader(formString) + } else { + return strings.NewReader("") + } +} + +func (request *RpcRequest) BuildQueries() string { + request.queries = "/?" + utils.GetUrlFormedMap(request.QueryParams) + return request.queries +} + +func (request *RpcRequest) BuildUrl() string { + url := fmt.Sprintf("%s://%s", strings.ToLower(request.Scheme), request.Domain) + if len(request.Port) > 0 { + url = fmt.Sprintf("%s:%s", url, request.Port) + } + return url + request.BuildQueries() +} + +func (request *RpcRequest) GetVersion() string { + return request.version +} + +func (request *RpcRequest) GetActionName() string { + return request.actionName +} + +func (request *RpcRequest) addPathParam(key, value string) { + panic("not support") +} + +func (request *RpcRequest) InitWithApiInfo(product, version, action, serviceCode, endpointType string) { + request.init() + request.product = product + request.version = version + request.actionName = action + request.locationServiceCode = serviceCode + request.locationEndpointType = endpointType +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go new file mode 100644 index 00000000..28af63ea --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go @@ -0,0 +1,53 @@ +package requests + +import "strconv" + +type Integer string + +func NewInteger(integer int) Integer { + return Integer(strconv.Itoa(integer)) +} + +func (integer Integer) HasValue() bool { + return integer != "" +} + +func (integer Integer) GetValue() (int, error) { + return strconv.Atoi(string(integer)) +} + +func NewInteger64(integer int64) Integer { + return Integer(strconv.FormatInt(integer, 10)) +} + +func (integer Integer) GetValue64() (int64, error) { + return strconv.ParseInt(string(integer), 10, 0) +} + +type Boolean string + +func NewBoolean(bool bool) Boolean { + return Boolean(strconv.FormatBool(bool)) +} + +func (boolean Boolean) HasValue() bool { + return boolean != "" +} + +func (boolean Boolean) GetValue() (bool, error) { + return strconv.ParseBool(string(boolean)) +} + +type Float string + +func NewFloat(f float64) Float { + return Float(strconv.FormatFloat(f, 'f', 6, 64)) +} + +func (float Float) HasValue() bool { + return float != "" +} + +func (float Float) GetValue() (float64, error) { + return strconv.ParseFloat(string(float), 64) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go new file mode 100644 index 00000000..36604fe8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go @@ -0,0 +1,328 @@ +package responses + +import ( + "encoding/json" + "io" + "math" + "strconv" + "strings" + "unsafe" + + jsoniter "github.com/json-iterator/go" +) + +const maxUint = ^uint(0) +const maxInt = int(maxUint >> 1) +const minInt = -maxInt - 1 + +var jsonParser jsoniter.API + +func init() { + registerBetterFuzzyDecoder() + jsonParser = jsoniter.Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, + CaseSensitive: true, + }.Froze() +} + +func registerBetterFuzzyDecoder() { + jsoniter.RegisterTypeDecoder("string", &nullableFuzzyStringDecoder{}) + jsoniter.RegisterTypeDecoder("bool", &fuzzyBoolDecoder{}) + jsoniter.RegisterTypeDecoder("float32", &nullableFuzzyFloat32Decoder{}) + jsoniter.RegisterTypeDecoder("float64", &nullableFuzzyFloat64Decoder{}) + jsoniter.RegisterTypeDecoder("int", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(maxInt) || val < float64(minInt) { + iter.ReportError("fuzzy decode int", "exceed range") + return + } + *((*int)(ptr)) = int(val) + } else { + *((*int)(ptr)) = iter.ReadInt() + } + }}) + jsoniter.RegisterTypeDecoder("uint", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(maxUint) || val < 0 { + iter.ReportError("fuzzy decode uint", "exceed range") + return + } + *((*uint)(ptr)) = uint(val) + } else { + *((*uint)(ptr)) = iter.ReadUint() + } + }}) + jsoniter.RegisterTypeDecoder("int8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt8) || val < float64(math.MinInt8) { + iter.ReportError("fuzzy decode int8", "exceed range") + return + } + *((*int8)(ptr)) = int8(val) + } else { + *((*int8)(ptr)) = iter.ReadInt8() + } + }}) + jsoniter.RegisterTypeDecoder("uint8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint8) || val < 0 { + iter.ReportError("fuzzy decode uint8", "exceed range") + return + } + *((*uint8)(ptr)) = uint8(val) + } else { + *((*uint8)(ptr)) = iter.ReadUint8() + } + }}) + jsoniter.RegisterTypeDecoder("int16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt16) || val < float64(math.MinInt16) { + iter.ReportError("fuzzy decode int16", "exceed range") + return + } + *((*int16)(ptr)) = int16(val) + } else { + *((*int16)(ptr)) = iter.ReadInt16() + } + }}) + jsoniter.RegisterTypeDecoder("uint16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint16) || val < 0 { + iter.ReportError("fuzzy decode uint16", "exceed range") + return + } + *((*uint16)(ptr)) = uint16(val) + } else { + *((*uint16)(ptr)) = iter.ReadUint16() + } + }}) + jsoniter.RegisterTypeDecoder("int32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt32) || val < float64(math.MinInt32) { + iter.ReportError("fuzzy decode int32", "exceed range") + return + } + *((*int32)(ptr)) = int32(val) + } else { + *((*int32)(ptr)) = iter.ReadInt32() + } + }}) + jsoniter.RegisterTypeDecoder("uint32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint32) || val < 0 { + iter.ReportError("fuzzy decode uint32", "exceed range") + return + } + *((*uint32)(ptr)) = uint32(val) + } else { + *((*uint32)(ptr)) = iter.ReadUint32() + } + }}) + jsoniter.RegisterTypeDecoder("int64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt64) || val < float64(math.MinInt64) { + iter.ReportError("fuzzy decode int64", "exceed range") + return + } + *((*int64)(ptr)) = int64(val) + } else { + *((*int64)(ptr)) = iter.ReadInt64() + } + }}) + jsoniter.RegisterTypeDecoder("uint64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint64) || val < 0 { + iter.ReportError("fuzzy decode uint64", "exceed range") + return + } + *((*uint64)(ptr)) = uint64(val) + } else { + *((*uint64)(ptr)) = iter.ReadUint64() + } + }}) +} + +type nullableFuzzyStringDecoder struct { +} + +func (decoder *nullableFuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + switch valueType { + case jsoniter.NumberValue: + var number json.Number + iter.ReadVal(&number) + *((*string)(ptr)) = string(number) + case jsoniter.StringValue: + *((*string)(ptr)) = iter.ReadString() + case jsoniter.BoolValue: + *((*string)(ptr)) = strconv.FormatBool(iter.ReadBool()) + case jsoniter.NilValue: + iter.ReadNil() + *((*string)(ptr)) = "" + default: + iter.ReportError("fuzzyStringDecoder", "not number or string or bool") + } +} + +type fuzzyBoolDecoder struct { +} + +func (decoder *fuzzyBoolDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + switch valueType { + case jsoniter.BoolValue: + *((*bool)(ptr)) = iter.ReadBool() + case jsoniter.NumberValue: + var number json.Number + iter.ReadVal(&number) + num, err := number.Int64() + if err != nil { + iter.ReportError("fuzzyBoolDecoder", "get value from json.number failed") + } + if num == 0 { + *((*bool)(ptr)) = false + } else { + *((*bool)(ptr)) = true + } + case jsoniter.StringValue: + strValue := strings.ToLower(iter.ReadString()) + if strValue == "true" { + *((*bool)(ptr)) = true + } else if strValue == "false" || strValue == "" { + *((*bool)(ptr)) = false + } else { + iter.ReportError("fuzzyBoolDecoder", "unsupported bool value: "+strValue) + } + case jsoniter.NilValue: + iter.ReadNil() + *((*bool)(ptr)) = false + default: + iter.ReportError("fuzzyBoolDecoder", "not number or string or nil") + } +} + +type nullableFuzzyIntegerDecoder struct { + fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) +} + +func (decoder *nullableFuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + var str string + switch valueType { + case jsoniter.NumberValue: + var number json.Number + iter.ReadVal(&number) + str = string(number) + case jsoniter.StringValue: + str = iter.ReadString() + // support empty string + if str == "" { + str = "0" + } + case jsoniter.BoolValue: + if iter.ReadBool() { + str = "1" + } else { + str = "0" + } + case jsoniter.NilValue: + iter.ReadNil() + str = "0" + default: + iter.ReportError("fuzzyIntegerDecoder", "not number or string") + } + newIter := iter.Pool().BorrowIterator([]byte(str)) + defer iter.Pool().ReturnIterator(newIter) + isFloat := strings.IndexByte(str, '.') != -1 + decoder.fun(isFloat, ptr, newIter) + if newIter.Error != nil && newIter.Error != io.EOF { + iter.Error = newIter.Error + } +} + +type nullableFuzzyFloat32Decoder struct { +} + +func (decoder *nullableFuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + var str string + switch valueType { + case jsoniter.NumberValue: + *((*float32)(ptr)) = iter.ReadFloat32() + case jsoniter.StringValue: + str = iter.ReadString() + // support empty string + if str == "" { + *((*float32)(ptr)) = 0 + return + } + newIter := iter.Pool().BorrowIterator([]byte(str)) + defer iter.Pool().ReturnIterator(newIter) + *((*float32)(ptr)) = newIter.ReadFloat32() + if newIter.Error != nil && newIter.Error != io.EOF { + iter.Error = newIter.Error + } + case jsoniter.BoolValue: + // support bool to float32 + if iter.ReadBool() { + *((*float32)(ptr)) = 1 + } else { + *((*float32)(ptr)) = 0 + } + case jsoniter.NilValue: + iter.ReadNil() + *((*float32)(ptr)) = 0 + default: + iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string") + } +} + +type nullableFuzzyFloat64Decoder struct { +} + +func (decoder *nullableFuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + var str string + switch valueType { + case jsoniter.NumberValue: + *((*float64)(ptr)) = iter.ReadFloat64() + case jsoniter.StringValue: + str = iter.ReadString() + // support empty string + if str == "" { + *((*float64)(ptr)) = 0 + return + } + newIter := iter.Pool().BorrowIterator([]byte(str)) + defer iter.Pool().ReturnIterator(newIter) + *((*float64)(ptr)) = newIter.ReadFloat64() + if newIter.Error != nil && newIter.Error != io.EOF { + iter.Error = newIter.Error + } + case jsoniter.BoolValue: + // support bool to float64 + if iter.ReadBool() { + *((*float64)(ptr)) = 1 + } else { + *((*float64)(ptr)) = 0 + } + case jsoniter.NilValue: + // support empty string + iter.ReadNil() + *((*float64)(ptr)) = 0 + default: + iter.ReportError("nullableFuzzyFloat64Decoder", "not number or string") + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go new file mode 100644 index 00000000..2b9eff1a --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go @@ -0,0 +1,152 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package responses + +import ( + "bytes" + "encoding/xml" + "fmt" + "io/ioutil" + "net/http" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +type AcsResponse interface { + IsSuccess() bool + GetHttpStatus() int + GetHttpHeaders() map[string][]string + GetHttpContentString() string + GetHttpContentBytes() []byte + GetOriginHttpResponse() *http.Response + parseFromHttpResponse(httpResponse *http.Response) error +} + +var debug utils.Debug + +func init() { + debug = utils.Init("sdk") +} + +// Unmarshal object from http response body to target Response +func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) { + err = response.parseFromHttpResponse(httpResponse) + if err != nil { + return + } + if !response.IsSuccess() { + err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), "") + return + } + + if _, isCommonResponse := response.(*CommonResponse); isCommonResponse { + // common response need not unmarshal + return + } + + if len(response.GetHttpContentBytes()) == 0 { + return + } + + if strings.ToUpper(format) == "JSON" { + err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response) + if err != nil { + err = errors.NewClientError(errors.JsonUnmarshalErrorCode, errors.JsonUnmarshalErrorMessage, err) + } + } else if strings.ToUpper(format) == "XML" { + err = xml.Unmarshal(response.GetHttpContentBytes(), response) + } + return +} + +type BaseResponse struct { + httpStatus int + httpHeaders map[string][]string + httpContentString string + httpContentBytes []byte + originHttpResponse *http.Response +} + +func (baseResponse *BaseResponse) GetHttpStatus() int { + return baseResponse.httpStatus +} + +func (baseResponse *BaseResponse) GetHttpHeaders() map[string][]string { + return baseResponse.httpHeaders +} + +func (baseResponse *BaseResponse) GetHttpContentString() string { + return baseResponse.httpContentString +} + +func (baseResponse *BaseResponse) GetHttpContentBytes() []byte { + return baseResponse.httpContentBytes +} + +func (baseResponse *BaseResponse) GetOriginHttpResponse() *http.Response { + return baseResponse.originHttpResponse +} + +func (baseResponse *BaseResponse) IsSuccess() bool { + if baseResponse.GetHttpStatus() >= 200 && baseResponse.GetHttpStatus() < 300 { + return true + } + + return false +} + +func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Response) (err error) { + defer httpResponse.Body.Close() + body, err := ioutil.ReadAll(httpResponse.Body) + if err != nil { + return + } + debug("%s", string(body)) + baseResponse.httpStatus = httpResponse.StatusCode + baseResponse.httpHeaders = httpResponse.Header + baseResponse.httpContentBytes = body + baseResponse.httpContentString = string(body) + baseResponse.originHttpResponse = httpResponse + return +} + +func (baseResponse *BaseResponse) String() string { + resultBuilder := bytes.Buffer{} + // statusCode + // resultBuilder.WriteString("\n") + resultBuilder.WriteString(fmt.Sprintf("%s %s\n", baseResponse.originHttpResponse.Proto, baseResponse.originHttpResponse.Status)) + // httpHeaders + //resultBuilder.WriteString("Headers:\n") + for key, value := range baseResponse.httpHeaders { + resultBuilder.WriteString(key + ": " + strings.Join(value, ";") + "\n") + } + resultBuilder.WriteString("\n") + // content + //resultBuilder.WriteString("Content:\n") + resultBuilder.WriteString(baseResponse.httpContentString + "\n") + return resultBuilder.String() +} + +type CommonResponse struct { + *BaseResponse +} + +func NewCommonResponse() (response *CommonResponse) { + return &CommonResponse{ + BaseResponse: &BaseResponse{}, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go new file mode 100644 index 00000000..09440d27 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go @@ -0,0 +1,36 @@ +package utils + +import ( + "fmt" + "os" + "strings" +) + +type Debug func(format string, v ...interface{}) + +var hookGetEnv = func() string { + return os.Getenv("DEBUG") +} + +var hookPrint = func(input string) { + fmt.Println(input) +} + +func Init(flag string) Debug { + enable := false + + env := hookGetEnv() + parts := strings.Split(env, ",") + for _, part := range parts { + if part == flag { + enable = true + break + } + } + + return func(format string, v ...interface{}) { + if enable { + hookPrint(fmt.Sprintf(format, v...)) + } + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go new file mode 100644 index 00000000..f8a3ad38 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go @@ -0,0 +1,141 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package utils + +import ( + "crypto/md5" + "crypto/rand" + "encoding/base64" + "encoding/hex" + "hash" + rand2 "math/rand" + "net/url" + "reflect" + "strconv" + "time" +) + +type UUID [16]byte + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func GetUUID() (uuidHex string) { + uuid := NewUUID() + uuidHex = hex.EncodeToString(uuid[:]) + return +} + +func RandStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand2.Intn(len(letterBytes))] + } + return string(b) +} + +func GetMD5Base64(bytes []byte) (base64Value string) { + md5Ctx := md5.New() + md5Ctx.Write(bytes) + md5Value := md5Ctx.Sum(nil) + base64Value = base64.StdEncoding.EncodeToString(md5Value) + return +} + +func GetTimeInFormatISO8601() (timeStr string) { + gmt := time.FixedZone("GMT", 0) + + return time.Now().In(gmt).Format("2006-01-02T15:04:05Z") +} + +func GetTimeInFormatRFC2616() (timeStr string) { + gmt := time.FixedZone("GMT", 0) + + return time.Now().In(gmt).Format("Mon, 02 Jan 2006 15:04:05 GMT") +} + +func GetUrlFormedMap(source map[string]string) (urlEncoded string) { + urlEncoder := url.Values{} + for key, value := range source { + urlEncoder.Add(key, value) + } + urlEncoded = urlEncoder.Encode() + return +} + +func InitStructWithDefaultTag(bean interface{}) { + configType := reflect.TypeOf(bean) + for i := 0; i < configType.Elem().NumField(); i++ { + field := configType.Elem().Field(i) + defaultValue := field.Tag.Get("default") + if defaultValue == "" { + continue + } + setter := reflect.ValueOf(bean).Elem().Field(i) + switch field.Type.String() { + case "int": + intValue, _ := strconv.ParseInt(defaultValue, 10, 64) + setter.SetInt(intValue) + case "time.Duration": + intValue, _ := strconv.ParseInt(defaultValue, 10, 64) + setter.SetInt(intValue) + case "string": + setter.SetString(defaultValue) + case "bool": + boolValue, _ := strconv.ParseBool(defaultValue) + setter.SetBool(boolValue) + } + } +} + +func NewUUID() UUID { + ns := UUID{} + safeRandom(ns[:]) + u := newFromHash(md5.New(), ns, RandStringBytes(16)) + u[6] = (u[6] & 0x0f) | (byte(2) << 4) + u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) + + return u +} + +func newFromHash(h hash.Hash, ns UUID, name string) UUID { + u := UUID{} + h.Write(ns[:]) + h.Write([]byte(name)) + copy(u[:], h.Sum(nil)) + + return u +} + +func safeRandom(dest []byte) { + if _, err := rand.Read(dest); err != nil { + panic(err) + } +} + +func (u UUID) String() string { + buf := make([]byte, 36) + + hex.Encode(buf[0:8], u[0:4]) + buf[8] = '-' + hex.Encode(buf[9:13], u[4:6]) + buf[13] = '-' + hex.Encode(buf[14:18], u[6:8]) + buf[18] = '-' + hex.Encode(buf[19:23], u[8:10]) + buf[23] = '-' + hex.Encode(buf[24:], u[10:]) + + return string(buf) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/cancel_key_deletion.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/cancel_key_deletion.go new file mode 100644 index 00000000..08ab80b5 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/cancel_key_deletion.go @@ -0,0 +1,103 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// CancelKeyDeletion invokes the kms.CancelKeyDeletion API synchronously +// api document: https://help.aliyun.com/api/kms/cancelkeydeletion.html +func (client *Client) CancelKeyDeletion(request *CancelKeyDeletionRequest) (response *CancelKeyDeletionResponse, err error) { + response = CreateCancelKeyDeletionResponse() + err = client.DoAction(request, response) + return +} + +// CancelKeyDeletionWithChan invokes the kms.CancelKeyDeletion API asynchronously +// api document: https://help.aliyun.com/api/kms/cancelkeydeletion.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CancelKeyDeletionWithChan(request *CancelKeyDeletionRequest) (<-chan *CancelKeyDeletionResponse, <-chan error) { + responseChan := make(chan *CancelKeyDeletionResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.CancelKeyDeletion(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// CancelKeyDeletionWithCallback invokes the kms.CancelKeyDeletion API asynchronously +// api document: https://help.aliyun.com/api/kms/cancelkeydeletion.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CancelKeyDeletionWithCallback(request *CancelKeyDeletionRequest, callback func(response *CancelKeyDeletionResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *CancelKeyDeletionResponse + var err error + defer close(result) + response, err = client.CancelKeyDeletion(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// CancelKeyDeletionRequest is the request struct for api CancelKeyDeletion +type CancelKeyDeletionRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` +} + +// CancelKeyDeletionResponse is the response struct for api CancelKeyDeletion +type CancelKeyDeletionResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateCancelKeyDeletionRequest creates a request to invoke CancelKeyDeletion API +func CreateCancelKeyDeletionRequest() (request *CancelKeyDeletionRequest) { + request = &CancelKeyDeletionRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "CancelKeyDeletion", "kms", "openAPI") + return +} + +// CreateCancelKeyDeletionResponse creates a response to parse from CancelKeyDeletion response +func CreateCancelKeyDeletionResponse() (response *CancelKeyDeletionResponse) { + response = &CancelKeyDeletionResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/client.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/client.go new file mode 100644 index 00000000..27631c12 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/client.go @@ -0,0 +1,81 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" +) + +// Client is the sdk client struct, each func corresponds to an OpenAPI +type Client struct { + sdk.Client +} + +// NewClient creates a sdk client with environment variables +func NewClient() (client *Client, err error) { + client = &Client{} + err = client.Init() + return +} + +// NewClientWithOptions creates a sdk client with regionId/sdkConfig/credential +// this is the common api to create a sdk client +func NewClientWithOptions(regionId string, config *sdk.Config, credential auth.Credential) (client *Client, err error) { + client = &Client{} + err = client.InitWithOptions(regionId, config, credential) + return +} + +// NewClientWithAccessKey is a shortcut to create sdk client with accesskey +// usage: https://help.aliyun.com/document_detail/66217.html +func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (client *Client, err error) { + client = &Client{} + err = client.InitWithAccessKey(regionId, accessKeyId, accessKeySecret) + return +} + +// NewClientWithStsToken is a shortcut to create sdk client with sts token +// usage: https://help.aliyun.com/document_detail/66222.html +func NewClientWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken string) (client *Client, err error) { + client = &Client{} + err = client.InitWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken) + return +} + +// NewClientWithRamRoleArn is a shortcut to create sdk client with ram roleArn +// usage: https://help.aliyun.com/document_detail/66222.html +func NewClientWithRamRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName) + return +} + +// NewClientWithEcsRamRole is a shortcut to create sdk client with ecs ram role +// usage: https://help.aliyun.com/document_detail/66223.html +func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithEcsRamRole(regionId, roleName) + return +} + +// NewClientWithRsaKeyPair is a shortcut to create sdk client with rsa key pair +// attention: rsa key pair auth is only Japan regions available +func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, sessionExpiration int) (client *Client, err error) { + client = &Client{} + err = client.InitWithRsaKeyPair(regionId, publicKeyId, privateKey, sessionExpiration) + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_alias.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_alias.go new file mode 100644 index 00000000..bc639317 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_alias.go @@ -0,0 +1,104 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// CreateAlias invokes the kms.CreateAlias API synchronously +// api document: https://help.aliyun.com/api/kms/createalias.html +func (client *Client) CreateAlias(request *CreateAliasRequest) (response *CreateAliasResponse, err error) { + response = CreateCreateAliasResponse() + err = client.DoAction(request, response) + return +} + +// CreateAliasWithChan invokes the kms.CreateAlias API asynchronously +// api document: https://help.aliyun.com/api/kms/createalias.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CreateAliasWithChan(request *CreateAliasRequest) (<-chan *CreateAliasResponse, <-chan error) { + responseChan := make(chan *CreateAliasResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.CreateAlias(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// CreateAliasWithCallback invokes the kms.CreateAlias API asynchronously +// api document: https://help.aliyun.com/api/kms/createalias.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CreateAliasWithCallback(request *CreateAliasRequest, callback func(response *CreateAliasResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *CreateAliasResponse + var err error + defer close(result) + response, err = client.CreateAlias(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// CreateAliasRequest is the request struct for api CreateAlias +type CreateAliasRequest struct { + *requests.RpcRequest + AliasName string `position:"Query" name:"AliasName"` + KeyId string `position:"Query" name:"KeyId"` +} + +// CreateAliasResponse is the response struct for api CreateAlias +type CreateAliasResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateCreateAliasRequest creates a request to invoke CreateAlias API +func CreateCreateAliasRequest() (request *CreateAliasRequest) { + request = &CreateAliasRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "CreateAlias", "kms", "openAPI") + return +} + +// CreateCreateAliasResponse creates a response to parse from CreateAlias response +func CreateCreateAliasResponse() (response *CreateAliasResponse) { + response = &CreateAliasResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_key.go new file mode 100644 index 00000000..cf513f2e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/create_key.go @@ -0,0 +1,106 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// CreateKey invokes the kms.CreateKey API synchronously +// api document: https://help.aliyun.com/api/kms/createkey.html +func (client *Client) CreateKey(request *CreateKeyRequest) (response *CreateKeyResponse, err error) { + response = CreateCreateKeyResponse() + err = client.DoAction(request, response) + return +} + +// CreateKeyWithChan invokes the kms.CreateKey API asynchronously +// api document: https://help.aliyun.com/api/kms/createkey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CreateKeyWithChan(request *CreateKeyRequest) (<-chan *CreateKeyResponse, <-chan error) { + responseChan := make(chan *CreateKeyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.CreateKey(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// CreateKeyWithCallback invokes the kms.CreateKey API asynchronously +// api document: https://help.aliyun.com/api/kms/createkey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CreateKeyWithCallback(request *CreateKeyRequest, callback func(response *CreateKeyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *CreateKeyResponse + var err error + defer close(result) + response, err = client.CreateKey(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// CreateKeyRequest is the request struct for api CreateKey +type CreateKeyRequest struct { + *requests.RpcRequest + KeyUsage string `position:"Query" name:"KeyUsage"` + Origin string `position:"Query" name:"Origin"` + Description string `position:"Query" name:"Description"` +} + +// CreateKeyResponse is the response struct for api CreateKey +type CreateKeyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + KeyMetadata KeyMetadata `json:"KeyMetadata" xml:"KeyMetadata"` +} + +// CreateCreateKeyRequest creates a request to invoke CreateKey API +func CreateCreateKeyRequest() (request *CreateKeyRequest) { + request = &CreateKeyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "CreateKey", "kms", "openAPI") + return +} + +// CreateCreateKeyResponse creates a response to parse from CreateKey response +func CreateCreateKeyResponse() (response *CreateKeyResponse) { + response = &CreateKeyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/decrypt.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/decrypt.go new file mode 100644 index 00000000..e0e4f51b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/decrypt.go @@ -0,0 +1,106 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// Decrypt invokes the kms.Decrypt API synchronously +// api document: https://help.aliyun.com/api/kms/decrypt.html +func (client *Client) Decrypt(request *DecryptRequest) (response *DecryptResponse, err error) { + response = CreateDecryptResponse() + err = client.DoAction(request, response) + return +} + +// DecryptWithChan invokes the kms.Decrypt API asynchronously +// api document: https://help.aliyun.com/api/kms/decrypt.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DecryptWithChan(request *DecryptRequest) (<-chan *DecryptResponse, <-chan error) { + responseChan := make(chan *DecryptResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.Decrypt(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DecryptWithCallback invokes the kms.Decrypt API asynchronously +// api document: https://help.aliyun.com/api/kms/decrypt.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DecryptWithCallback(request *DecryptRequest, callback func(response *DecryptResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DecryptResponse + var err error + defer close(result) + response, err = client.Decrypt(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DecryptRequest is the request struct for api Decrypt +type DecryptRequest struct { + *requests.RpcRequest + EncryptionContext string `position:"Query" name:"EncryptionContext"` + CiphertextBlob string `position:"Query" name:"CiphertextBlob"` +} + +// DecryptResponse is the response struct for api Decrypt +type DecryptResponse struct { + *responses.BaseResponse + Plaintext string `json:"Plaintext" xml:"Plaintext"` + KeyId string `json:"KeyId" xml:"KeyId"` + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateDecryptRequest creates a request to invoke Decrypt API +func CreateDecryptRequest() (request *DecryptRequest) { + request = &DecryptRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "Decrypt", "kms", "openAPI") + return +} + +// CreateDecryptResponse creates a response to parse from Decrypt response +func CreateDecryptResponse() (response *DecryptResponse) { + response = &DecryptResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_alias.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_alias.go new file mode 100644 index 00000000..591f11cb --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_alias.go @@ -0,0 +1,103 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteAlias invokes the kms.DeleteAlias API synchronously +// api document: https://help.aliyun.com/api/kms/deletealias.html +func (client *Client) DeleteAlias(request *DeleteAliasRequest) (response *DeleteAliasResponse, err error) { + response = CreateDeleteAliasResponse() + err = client.DoAction(request, response) + return +} + +// DeleteAliasWithChan invokes the kms.DeleteAlias API asynchronously +// api document: https://help.aliyun.com/api/kms/deletealias.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteAliasWithChan(request *DeleteAliasRequest) (<-chan *DeleteAliasResponse, <-chan error) { + responseChan := make(chan *DeleteAliasResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteAlias(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteAliasWithCallback invokes the kms.DeleteAlias API asynchronously +// api document: https://help.aliyun.com/api/kms/deletealias.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteAliasWithCallback(request *DeleteAliasRequest, callback func(response *DeleteAliasResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteAliasResponse + var err error + defer close(result) + response, err = client.DeleteAlias(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteAliasRequest is the request struct for api DeleteAlias +type DeleteAliasRequest struct { + *requests.RpcRequest + AliasName string `position:"Query" name:"AliasName"` +} + +// DeleteAliasResponse is the response struct for api DeleteAlias +type DeleteAliasResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateDeleteAliasRequest creates a request to invoke DeleteAlias API +func CreateDeleteAliasRequest() (request *DeleteAliasRequest) { + request = &DeleteAliasRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "DeleteAlias", "kms", "openAPI") + return +} + +// CreateDeleteAliasResponse creates a response to parse from DeleteAlias response +func CreateDeleteAliasResponse() (response *DeleteAliasResponse) { + response = &DeleteAliasResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_key_material.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_key_material.go new file mode 100644 index 00000000..522e0136 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/delete_key_material.go @@ -0,0 +1,103 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteKeyMaterial invokes the kms.DeleteKeyMaterial API synchronously +// api document: https://help.aliyun.com/api/kms/deletekeymaterial.html +func (client *Client) DeleteKeyMaterial(request *DeleteKeyMaterialRequest) (response *DeleteKeyMaterialResponse, err error) { + response = CreateDeleteKeyMaterialResponse() + err = client.DoAction(request, response) + return +} + +// DeleteKeyMaterialWithChan invokes the kms.DeleteKeyMaterial API asynchronously +// api document: https://help.aliyun.com/api/kms/deletekeymaterial.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteKeyMaterialWithChan(request *DeleteKeyMaterialRequest) (<-chan *DeleteKeyMaterialResponse, <-chan error) { + responseChan := make(chan *DeleteKeyMaterialResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteKeyMaterial(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteKeyMaterialWithCallback invokes the kms.DeleteKeyMaterial API asynchronously +// api document: https://help.aliyun.com/api/kms/deletekeymaterial.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteKeyMaterialWithCallback(request *DeleteKeyMaterialRequest, callback func(response *DeleteKeyMaterialResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteKeyMaterialResponse + var err error + defer close(result) + response, err = client.DeleteKeyMaterial(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteKeyMaterialRequest is the request struct for api DeleteKeyMaterial +type DeleteKeyMaterialRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` +} + +// DeleteKeyMaterialResponse is the response struct for api DeleteKeyMaterial +type DeleteKeyMaterialResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateDeleteKeyMaterialRequest creates a request to invoke DeleteKeyMaterial API +func CreateDeleteKeyMaterialRequest() (request *DeleteKeyMaterialRequest) { + request = &DeleteKeyMaterialRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "DeleteKeyMaterial", "kms", "openAPI") + return +} + +// CreateDeleteKeyMaterialResponse creates a response to parse from DeleteKeyMaterial response +func CreateDeleteKeyMaterialResponse() (response *DeleteKeyMaterialResponse) { + response = &DeleteKeyMaterialResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_key.go new file mode 100644 index 00000000..bf3cc412 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_key.go @@ -0,0 +1,104 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeKey invokes the kms.DescribeKey API synchronously +// api document: https://help.aliyun.com/api/kms/describekey.html +func (client *Client) DescribeKey(request *DescribeKeyRequest) (response *DescribeKeyResponse, err error) { + response = CreateDescribeKeyResponse() + err = client.DoAction(request, response) + return +} + +// DescribeKeyWithChan invokes the kms.DescribeKey API asynchronously +// api document: https://help.aliyun.com/api/kms/describekey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeKeyWithChan(request *DescribeKeyRequest) (<-chan *DescribeKeyResponse, <-chan error) { + responseChan := make(chan *DescribeKeyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeKey(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeKeyWithCallback invokes the kms.DescribeKey API asynchronously +// api document: https://help.aliyun.com/api/kms/describekey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeKeyWithCallback(request *DescribeKeyRequest, callback func(response *DescribeKeyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeKeyResponse + var err error + defer close(result) + response, err = client.DescribeKey(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeKeyRequest is the request struct for api DescribeKey +type DescribeKeyRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` +} + +// DescribeKeyResponse is the response struct for api DescribeKey +type DescribeKeyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + KeyMetadata KeyMetadata `json:"KeyMetadata" xml:"KeyMetadata"` +} + +// CreateDescribeKeyRequest creates a request to invoke DescribeKey API +func CreateDescribeKeyRequest() (request *DescribeKeyRequest) { + request = &DescribeKeyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "DescribeKey", "kms", "openAPI") + return +} + +// CreateDescribeKeyResponse creates a response to parse from DescribeKey response +func CreateDescribeKeyResponse() (response *DescribeKeyResponse) { + response = &DescribeKeyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_regions.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_regions.go new file mode 100644 index 00000000..9f56726e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/describe_regions.go @@ -0,0 +1,103 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeRegions invokes the kms.DescribeRegions API synchronously +// api document: https://help.aliyun.com/api/kms/describeregions.html +func (client *Client) DescribeRegions(request *DescribeRegionsRequest) (response *DescribeRegionsResponse, err error) { + response = CreateDescribeRegionsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeRegionsWithChan invokes the kms.DescribeRegions API asynchronously +// api document: https://help.aliyun.com/api/kms/describeregions.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRegionsWithChan(request *DescribeRegionsRequest) (<-chan *DescribeRegionsResponse, <-chan error) { + responseChan := make(chan *DescribeRegionsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeRegions(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeRegionsWithCallback invokes the kms.DescribeRegions API asynchronously +// api document: https://help.aliyun.com/api/kms/describeregions.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRegionsWithCallback(request *DescribeRegionsRequest, callback func(response *DescribeRegionsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeRegionsResponse + var err error + defer close(result) + response, err = client.DescribeRegions(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeRegionsRequest is the request struct for api DescribeRegions +type DescribeRegionsRequest struct { + *requests.RpcRequest +} + +// DescribeRegionsResponse is the response struct for api DescribeRegions +type DescribeRegionsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Regions Regions `json:"Regions" xml:"Regions"` +} + +// CreateDescribeRegionsRequest creates a request to invoke DescribeRegions API +func CreateDescribeRegionsRequest() (request *DescribeRegionsRequest) { + request = &DescribeRegionsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "DescribeRegions", "kms", "openAPI") + return +} + +// CreateDescribeRegionsResponse creates a response to parse from DescribeRegions response +func CreateDescribeRegionsResponse() (response *DescribeRegionsResponse) { + response = &DescribeRegionsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/disable_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/disable_key.go new file mode 100644 index 00000000..5734e9e7 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/disable_key.go @@ -0,0 +1,103 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DisableKey invokes the kms.DisableKey API synchronously +// api document: https://help.aliyun.com/api/kms/disablekey.html +func (client *Client) DisableKey(request *DisableKeyRequest) (response *DisableKeyResponse, err error) { + response = CreateDisableKeyResponse() + err = client.DoAction(request, response) + return +} + +// DisableKeyWithChan invokes the kms.DisableKey API asynchronously +// api document: https://help.aliyun.com/api/kms/disablekey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DisableKeyWithChan(request *DisableKeyRequest) (<-chan *DisableKeyResponse, <-chan error) { + responseChan := make(chan *DisableKeyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DisableKey(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DisableKeyWithCallback invokes the kms.DisableKey API asynchronously +// api document: https://help.aliyun.com/api/kms/disablekey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DisableKeyWithCallback(request *DisableKeyRequest, callback func(response *DisableKeyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DisableKeyResponse + var err error + defer close(result) + response, err = client.DisableKey(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DisableKeyRequest is the request struct for api DisableKey +type DisableKeyRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` +} + +// DisableKeyResponse is the response struct for api DisableKey +type DisableKeyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateDisableKeyRequest creates a request to invoke DisableKey API +func CreateDisableKeyRequest() (request *DisableKeyRequest) { + request = &DisableKeyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "DisableKey", "kms", "openAPI") + return +} + +// CreateDisableKeyResponse creates a response to parse from DisableKey response +func CreateDisableKeyResponse() (response *DisableKeyResponse) { + response = &DisableKeyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/enable_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/enable_key.go new file mode 100644 index 00000000..94c2c139 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/enable_key.go @@ -0,0 +1,103 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// EnableKey invokes the kms.EnableKey API synchronously +// api document: https://help.aliyun.com/api/kms/enablekey.html +func (client *Client) EnableKey(request *EnableKeyRequest) (response *EnableKeyResponse, err error) { + response = CreateEnableKeyResponse() + err = client.DoAction(request, response) + return +} + +// EnableKeyWithChan invokes the kms.EnableKey API asynchronously +// api document: https://help.aliyun.com/api/kms/enablekey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) EnableKeyWithChan(request *EnableKeyRequest) (<-chan *EnableKeyResponse, <-chan error) { + responseChan := make(chan *EnableKeyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.EnableKey(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// EnableKeyWithCallback invokes the kms.EnableKey API asynchronously +// api document: https://help.aliyun.com/api/kms/enablekey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) EnableKeyWithCallback(request *EnableKeyRequest, callback func(response *EnableKeyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *EnableKeyResponse + var err error + defer close(result) + response, err = client.EnableKey(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// EnableKeyRequest is the request struct for api EnableKey +type EnableKeyRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` +} + +// EnableKeyResponse is the response struct for api EnableKey +type EnableKeyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateEnableKeyRequest creates a request to invoke EnableKey API +func CreateEnableKeyRequest() (request *EnableKeyRequest) { + request = &EnableKeyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "EnableKey", "kms", "openAPI") + return +} + +// CreateEnableKeyResponse creates a response to parse from EnableKey response +func CreateEnableKeyResponse() (response *EnableKeyResponse) { + response = &EnableKeyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/encrypt.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/encrypt.go new file mode 100644 index 00000000..3ca5e0f5 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/encrypt.go @@ -0,0 +1,107 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// Encrypt invokes the kms.Encrypt API synchronously +// api document: https://help.aliyun.com/api/kms/encrypt.html +func (client *Client) Encrypt(request *EncryptRequest) (response *EncryptResponse, err error) { + response = CreateEncryptResponse() + err = client.DoAction(request, response) + return +} + +// EncryptWithChan invokes the kms.Encrypt API asynchronously +// api document: https://help.aliyun.com/api/kms/encrypt.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) EncryptWithChan(request *EncryptRequest) (<-chan *EncryptResponse, <-chan error) { + responseChan := make(chan *EncryptResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.Encrypt(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// EncryptWithCallback invokes the kms.Encrypt API asynchronously +// api document: https://help.aliyun.com/api/kms/encrypt.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) EncryptWithCallback(request *EncryptRequest, callback func(response *EncryptResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *EncryptResponse + var err error + defer close(result) + response, err = client.Encrypt(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// EncryptRequest is the request struct for api Encrypt +type EncryptRequest struct { + *requests.RpcRequest + EncryptionContext string `position:"Query" name:"EncryptionContext"` + KeyId string `position:"Query" name:"KeyId"` + Plaintext string `position:"Query" name:"Plaintext"` +} + +// EncryptResponse is the response struct for api Encrypt +type EncryptResponse struct { + *responses.BaseResponse + CiphertextBlob string `json:"CiphertextBlob" xml:"CiphertextBlob"` + KeyId string `json:"KeyId" xml:"KeyId"` + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateEncryptRequest creates a request to invoke Encrypt API +func CreateEncryptRequest() (request *EncryptRequest) { + request = &EncryptRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "Encrypt", "kms", "openAPI") + return +} + +// CreateEncryptResponse creates a response to parse from Encrypt response +func CreateEncryptResponse() (response *EncryptResponse) { + response = &EncryptResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/generate_data_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/generate_data_key.go new file mode 100644 index 00000000..9c62b6d7 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/generate_data_key.go @@ -0,0 +1,109 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// GenerateDataKey invokes the kms.GenerateDataKey API synchronously +// api document: https://help.aliyun.com/api/kms/generatedatakey.html +func (client *Client) GenerateDataKey(request *GenerateDataKeyRequest) (response *GenerateDataKeyResponse, err error) { + response = CreateGenerateDataKeyResponse() + err = client.DoAction(request, response) + return +} + +// GenerateDataKeyWithChan invokes the kms.GenerateDataKey API asynchronously +// api document: https://help.aliyun.com/api/kms/generatedatakey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) GenerateDataKeyWithChan(request *GenerateDataKeyRequest) (<-chan *GenerateDataKeyResponse, <-chan error) { + responseChan := make(chan *GenerateDataKeyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.GenerateDataKey(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// GenerateDataKeyWithCallback invokes the kms.GenerateDataKey API asynchronously +// api document: https://help.aliyun.com/api/kms/generatedatakey.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) GenerateDataKeyWithCallback(request *GenerateDataKeyRequest, callback func(response *GenerateDataKeyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *GenerateDataKeyResponse + var err error + defer close(result) + response, err = client.GenerateDataKey(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// GenerateDataKeyRequest is the request struct for api GenerateDataKey +type GenerateDataKeyRequest struct { + *requests.RpcRequest + EncryptionContext string `position:"Query" name:"EncryptionContext"` + KeyId string `position:"Query" name:"KeyId"` + KeySpec string `position:"Query" name:"KeySpec"` + NumberOfBytes requests.Integer `position:"Query" name:"NumberOfBytes"` +} + +// GenerateDataKeyResponse is the response struct for api GenerateDataKey +type GenerateDataKeyResponse struct { + *responses.BaseResponse + CiphertextBlob string `json:"CiphertextBlob" xml:"CiphertextBlob"` + KeyId string `json:"KeyId" xml:"KeyId"` + Plaintext string `json:"Plaintext" xml:"Plaintext"` + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateGenerateDataKeyRequest creates a request to invoke GenerateDataKey API +func CreateGenerateDataKeyRequest() (request *GenerateDataKeyRequest) { + request = &GenerateDataKeyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "GenerateDataKey", "kms", "openAPI") + return +} + +// CreateGenerateDataKeyResponse creates a response to parse from GenerateDataKey response +func CreateGenerateDataKeyResponse() (response *GenerateDataKeyResponse) { + response = &GenerateDataKeyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/get_parameters_for_import.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/get_parameters_for_import.go new file mode 100644 index 00000000..ef748a5e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/get_parameters_for_import.go @@ -0,0 +1,109 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// GetParametersForImport invokes the kms.GetParametersForImport API synchronously +// api document: https://help.aliyun.com/api/kms/getparametersforimport.html +func (client *Client) GetParametersForImport(request *GetParametersForImportRequest) (response *GetParametersForImportResponse, err error) { + response = CreateGetParametersForImportResponse() + err = client.DoAction(request, response) + return +} + +// GetParametersForImportWithChan invokes the kms.GetParametersForImport API asynchronously +// api document: https://help.aliyun.com/api/kms/getparametersforimport.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) GetParametersForImportWithChan(request *GetParametersForImportRequest) (<-chan *GetParametersForImportResponse, <-chan error) { + responseChan := make(chan *GetParametersForImportResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.GetParametersForImport(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// GetParametersForImportWithCallback invokes the kms.GetParametersForImport API asynchronously +// api document: https://help.aliyun.com/api/kms/getparametersforimport.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) GetParametersForImportWithCallback(request *GetParametersForImportRequest, callback func(response *GetParametersForImportResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *GetParametersForImportResponse + var err error + defer close(result) + response, err = client.GetParametersForImport(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// GetParametersForImportRequest is the request struct for api GetParametersForImport +type GetParametersForImportRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` + WrappingAlgorithm string `position:"Query" name:"WrappingAlgorithm"` + WrappingKeySpec string `position:"Query" name:"WrappingKeySpec"` +} + +// GetParametersForImportResponse is the response struct for api GetParametersForImport +type GetParametersForImportResponse struct { + *responses.BaseResponse + KeyId string `json:"KeyId" xml:"KeyId"` + RequestId string `json:"RequestId" xml:"RequestId"` + ImportToken string `json:"ImportToken" xml:"ImportToken"` + PublicKey string `json:"PublicKey" xml:"PublicKey"` + TokenExpireTime string `json:"TokenExpireTime" xml:"TokenExpireTime"` +} + +// CreateGetParametersForImportRequest creates a request to invoke GetParametersForImport API +func CreateGetParametersForImportRequest() (request *GetParametersForImportRequest) { + request = &GetParametersForImportRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "GetParametersForImport", "kms", "openAPI") + return +} + +// CreateGetParametersForImportResponse creates a response to parse from GetParametersForImport response +func CreateGetParametersForImportResponse() (response *GetParametersForImportResponse) { + response = &GetParametersForImportResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/import_key_material.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/import_key_material.go new file mode 100644 index 00000000..e594eb93 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/import_key_material.go @@ -0,0 +1,106 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ImportKeyMaterial invokes the kms.ImportKeyMaterial API synchronously +// api document: https://help.aliyun.com/api/kms/importkeymaterial.html +func (client *Client) ImportKeyMaterial(request *ImportKeyMaterialRequest) (response *ImportKeyMaterialResponse, err error) { + response = CreateImportKeyMaterialResponse() + err = client.DoAction(request, response) + return +} + +// ImportKeyMaterialWithChan invokes the kms.ImportKeyMaterial API asynchronously +// api document: https://help.aliyun.com/api/kms/importkeymaterial.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ImportKeyMaterialWithChan(request *ImportKeyMaterialRequest) (<-chan *ImportKeyMaterialResponse, <-chan error) { + responseChan := make(chan *ImportKeyMaterialResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ImportKeyMaterial(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ImportKeyMaterialWithCallback invokes the kms.ImportKeyMaterial API asynchronously +// api document: https://help.aliyun.com/api/kms/importkeymaterial.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ImportKeyMaterialWithCallback(request *ImportKeyMaterialRequest, callback func(response *ImportKeyMaterialResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ImportKeyMaterialResponse + var err error + defer close(result) + response, err = client.ImportKeyMaterial(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ImportKeyMaterialRequest is the request struct for api ImportKeyMaterial +type ImportKeyMaterialRequest struct { + *requests.RpcRequest + ImportToken string `position:"Query" name:"ImportToken"` + EncryptedKeyMaterial string `position:"Query" name:"EncryptedKeyMaterial"` + KeyMaterialExpireUnix requests.Integer `position:"Query" name:"KeyMaterialExpireUnix"` + KeyId string `position:"Query" name:"KeyId"` +} + +// ImportKeyMaterialResponse is the response struct for api ImportKeyMaterial +type ImportKeyMaterialResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateImportKeyMaterialRequest creates a request to invoke ImportKeyMaterial API +func CreateImportKeyMaterialRequest() (request *ImportKeyMaterialRequest) { + request = &ImportKeyMaterialRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "ImportKeyMaterial", "kms", "openAPI") + return +} + +// CreateImportKeyMaterialResponse creates a response to parse from ImportKeyMaterial response +func CreateImportKeyMaterialResponse() (response *ImportKeyMaterialResponse) { + response = &ImportKeyMaterialResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases.go new file mode 100644 index 00000000..fa961a8e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases.go @@ -0,0 +1,108 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ListAliases invokes the kms.ListAliases API synchronously +// api document: https://help.aliyun.com/api/kms/listaliases.html +func (client *Client) ListAliases(request *ListAliasesRequest) (response *ListAliasesResponse, err error) { + response = CreateListAliasesResponse() + err = client.DoAction(request, response) + return +} + +// ListAliasesWithChan invokes the kms.ListAliases API asynchronously +// api document: https://help.aliyun.com/api/kms/listaliases.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListAliasesWithChan(request *ListAliasesRequest) (<-chan *ListAliasesResponse, <-chan error) { + responseChan := make(chan *ListAliasesResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ListAliases(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ListAliasesWithCallback invokes the kms.ListAliases API asynchronously +// api document: https://help.aliyun.com/api/kms/listaliases.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListAliasesWithCallback(request *ListAliasesRequest, callback func(response *ListAliasesResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ListAliasesResponse + var err error + defer close(result) + response, err = client.ListAliases(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ListAliasesRequest is the request struct for api ListAliases +type ListAliasesRequest struct { + *requests.RpcRequest + PageSize requests.Integer `position:"Query" name:"PageSize"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// ListAliasesResponse is the response struct for api ListAliases +type ListAliasesResponse struct { + *responses.BaseResponse + TotalCount int `json:"TotalCount" xml:"TotalCount"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + PageSize int `json:"PageSize" xml:"PageSize"` + RequestId string `json:"RequestId" xml:"RequestId"` + Aliases AliasesInListAliases `json:"Aliases" xml:"Aliases"` +} + +// CreateListAliasesRequest creates a request to invoke ListAliases API +func CreateListAliasesRequest() (request *ListAliasesRequest) { + request = &ListAliasesRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "ListAliases", "kms", "openAPI") + return +} + +// CreateListAliasesResponse creates a response to parse from ListAliases response +func CreateListAliasesResponse() (response *ListAliasesResponse) { + response = &ListAliasesResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases_by_key_id.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases_by_key_id.go new file mode 100644 index 00000000..227d2794 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_aliases_by_key_id.go @@ -0,0 +1,109 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ListAliasesByKeyId invokes the kms.ListAliasesByKeyId API synchronously +// api document: https://help.aliyun.com/api/kms/listaliasesbykeyid.html +func (client *Client) ListAliasesByKeyId(request *ListAliasesByKeyIdRequest) (response *ListAliasesByKeyIdResponse, err error) { + response = CreateListAliasesByKeyIdResponse() + err = client.DoAction(request, response) + return +} + +// ListAliasesByKeyIdWithChan invokes the kms.ListAliasesByKeyId API asynchronously +// api document: https://help.aliyun.com/api/kms/listaliasesbykeyid.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListAliasesByKeyIdWithChan(request *ListAliasesByKeyIdRequest) (<-chan *ListAliasesByKeyIdResponse, <-chan error) { + responseChan := make(chan *ListAliasesByKeyIdResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ListAliasesByKeyId(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ListAliasesByKeyIdWithCallback invokes the kms.ListAliasesByKeyId API asynchronously +// api document: https://help.aliyun.com/api/kms/listaliasesbykeyid.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListAliasesByKeyIdWithCallback(request *ListAliasesByKeyIdRequest, callback func(response *ListAliasesByKeyIdResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ListAliasesByKeyIdResponse + var err error + defer close(result) + response, err = client.ListAliasesByKeyId(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ListAliasesByKeyIdRequest is the request struct for api ListAliasesByKeyId +type ListAliasesByKeyIdRequest struct { + *requests.RpcRequest + PageSize requests.Integer `position:"Query" name:"PageSize"` + KeyId string `position:"Query" name:"KeyId"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// ListAliasesByKeyIdResponse is the response struct for api ListAliasesByKeyId +type ListAliasesByKeyIdResponse struct { + *responses.BaseResponse + TotalCount int `json:"TotalCount" xml:"TotalCount"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + PageSize int `json:"PageSize" xml:"PageSize"` + RequestId string `json:"RequestId" xml:"RequestId"` + Aliases AliasesInListAliasesByKeyId `json:"Aliases" xml:"Aliases"` +} + +// CreateListAliasesByKeyIdRequest creates a request to invoke ListAliasesByKeyId API +func CreateListAliasesByKeyIdRequest() (request *ListAliasesByKeyIdRequest) { + request = &ListAliasesByKeyIdRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "ListAliasesByKeyId", "kms", "openAPI") + return +} + +// CreateListAliasesByKeyIdResponse creates a response to parse from ListAliasesByKeyId response +func CreateListAliasesByKeyIdResponse() (response *ListAliasesByKeyIdResponse) { + response = &ListAliasesByKeyIdResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_keys.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_keys.go new file mode 100644 index 00000000..3384d709 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_keys.go @@ -0,0 +1,108 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ListKeys invokes the kms.ListKeys API synchronously +// api document: https://help.aliyun.com/api/kms/listkeys.html +func (client *Client) ListKeys(request *ListKeysRequest) (response *ListKeysResponse, err error) { + response = CreateListKeysResponse() + err = client.DoAction(request, response) + return +} + +// ListKeysWithChan invokes the kms.ListKeys API asynchronously +// api document: https://help.aliyun.com/api/kms/listkeys.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListKeysWithChan(request *ListKeysRequest) (<-chan *ListKeysResponse, <-chan error) { + responseChan := make(chan *ListKeysResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ListKeys(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ListKeysWithCallback invokes the kms.ListKeys API asynchronously +// api document: https://help.aliyun.com/api/kms/listkeys.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListKeysWithCallback(request *ListKeysRequest, callback func(response *ListKeysResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ListKeysResponse + var err error + defer close(result) + response, err = client.ListKeys(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ListKeysRequest is the request struct for api ListKeys +type ListKeysRequest struct { + *requests.RpcRequest + PageSize requests.Integer `position:"Query" name:"PageSize"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// ListKeysResponse is the response struct for api ListKeys +type ListKeysResponse struct { + *responses.BaseResponse + TotalCount int `json:"TotalCount" xml:"TotalCount"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + PageSize int `json:"PageSize" xml:"PageSize"` + RequestId string `json:"RequestId" xml:"RequestId"` + Keys Keys `json:"Keys" xml:"Keys"` +} + +// CreateListKeysRequest creates a request to invoke ListKeys API +func CreateListKeysRequest() (request *ListKeysRequest) { + request = &ListKeysRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "ListKeys", "kms", "openAPI") + return +} + +// CreateListKeysResponse creates a response to parse from ListKeys response +func CreateListKeysResponse() (response *ListKeysResponse) { + response = &ListKeysResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_resource_tags.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_resource_tags.go new file mode 100644 index 00000000..4f642754 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/list_resource_tags.go @@ -0,0 +1,104 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ListResourceTags invokes the kms.ListResourceTags API synchronously +// api document: https://help.aliyun.com/api/kms/listresourcetags.html +func (client *Client) ListResourceTags(request *ListResourceTagsRequest) (response *ListResourceTagsResponse, err error) { + response = CreateListResourceTagsResponse() + err = client.DoAction(request, response) + return +} + +// ListResourceTagsWithChan invokes the kms.ListResourceTags API asynchronously +// api document: https://help.aliyun.com/api/kms/listresourcetags.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListResourceTagsWithChan(request *ListResourceTagsRequest) (<-chan *ListResourceTagsResponse, <-chan error) { + responseChan := make(chan *ListResourceTagsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ListResourceTags(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ListResourceTagsWithCallback invokes the kms.ListResourceTags API asynchronously +// api document: https://help.aliyun.com/api/kms/listresourcetags.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ListResourceTagsWithCallback(request *ListResourceTagsRequest, callback func(response *ListResourceTagsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ListResourceTagsResponse + var err error + defer close(result) + response, err = client.ListResourceTags(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ListResourceTagsRequest is the request struct for api ListResourceTags +type ListResourceTagsRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` +} + +// ListResourceTagsResponse is the response struct for api ListResourceTags +type ListResourceTagsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Tags Tags `json:"Tags" xml:"Tags"` +} + +// CreateListResourceTagsRequest creates a request to invoke ListResourceTags API +func CreateListResourceTagsRequest() (request *ListResourceTagsRequest) { + request = &ListResourceTagsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "ListResourceTags", "kms", "openAPI") + return +} + +// CreateListResourceTagsResponse creates a response to parse from ListResourceTags response +func CreateListResourceTagsResponse() (response *ListResourceTagsResponse) { + response = &ListResourceTagsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/schedule_key_deletion.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/schedule_key_deletion.go new file mode 100644 index 00000000..23ce5eb4 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/schedule_key_deletion.go @@ -0,0 +1,104 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ScheduleKeyDeletion invokes the kms.ScheduleKeyDeletion API synchronously +// api document: https://help.aliyun.com/api/kms/schedulekeydeletion.html +func (client *Client) ScheduleKeyDeletion(request *ScheduleKeyDeletionRequest) (response *ScheduleKeyDeletionResponse, err error) { + response = CreateScheduleKeyDeletionResponse() + err = client.DoAction(request, response) + return +} + +// ScheduleKeyDeletionWithChan invokes the kms.ScheduleKeyDeletion API asynchronously +// api document: https://help.aliyun.com/api/kms/schedulekeydeletion.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ScheduleKeyDeletionWithChan(request *ScheduleKeyDeletionRequest) (<-chan *ScheduleKeyDeletionResponse, <-chan error) { + responseChan := make(chan *ScheduleKeyDeletionResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ScheduleKeyDeletion(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ScheduleKeyDeletionWithCallback invokes the kms.ScheduleKeyDeletion API asynchronously +// api document: https://help.aliyun.com/api/kms/schedulekeydeletion.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ScheduleKeyDeletionWithCallback(request *ScheduleKeyDeletionRequest, callback func(response *ScheduleKeyDeletionResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ScheduleKeyDeletionResponse + var err error + defer close(result) + response, err = client.ScheduleKeyDeletion(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ScheduleKeyDeletionRequest is the request struct for api ScheduleKeyDeletion +type ScheduleKeyDeletionRequest struct { + *requests.RpcRequest + PendingWindowInDays requests.Integer `position:"Query" name:"PendingWindowInDays"` + KeyId string `position:"Query" name:"KeyId"` +} + +// ScheduleKeyDeletionResponse is the response struct for api ScheduleKeyDeletion +type ScheduleKeyDeletionResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateScheduleKeyDeletionRequest creates a request to invoke ScheduleKeyDeletion API +func CreateScheduleKeyDeletionRequest() (request *ScheduleKeyDeletionRequest) { + request = &ScheduleKeyDeletionRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "ScheduleKeyDeletion", "kms", "openAPI") + return +} + +// CreateScheduleKeyDeletionResponse creates a response to parse from ScheduleKeyDeletion response +func CreateScheduleKeyDeletionResponse() (response *ScheduleKeyDeletionResponse) { + response = &ScheduleKeyDeletionResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_alias.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_alias.go new file mode 100644 index 00000000..56b5984e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_alias.go @@ -0,0 +1,23 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Alias is a nested struct in kms response +type Alias struct { + AliasArn string `json:"AliasArn" xml:"AliasArn"` + AliasName string `json:"AliasName" xml:"AliasName"` + KeyId string `json:"KeyId" xml:"KeyId"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases.go new file mode 100644 index 00000000..a08047f1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases.go @@ -0,0 +1,21 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// AliasesInListAliases is a nested struct in kms response +type AliasesInListAliases struct { + Alias []Alias `json:"Alias" xml:"Alias"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases_by_key_id.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases_by_key_id.go new file mode 100644 index 00000000..8f52f423 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_aliases_in_list_aliases_by_key_id.go @@ -0,0 +1,21 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// AliasesInListAliasesByKeyId is a nested struct in kms response +type AliasesInListAliasesByKeyId struct { + Alias []Alias `json:"Alias" xml:"Alias"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key.go new file mode 100644 index 00000000..8e6f508e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key.go @@ -0,0 +1,22 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Key is a nested struct in kms response +type Key struct { + KeyId string `json:"KeyId" xml:"KeyId"` + KeyArn string `json:"KeyArn" xml:"KeyArn"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key_metadata.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key_metadata.go new file mode 100644 index 00000000..5432b8c1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_key_metadata.go @@ -0,0 +1,30 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// KeyMetadata is a nested struct in kms response +type KeyMetadata struct { + Arn string `json:"Arn" xml:"Arn"` + KeyState string `json:"KeyState" xml:"KeyState"` + CreationDate string `json:"CreationDate" xml:"CreationDate"` + KeyUsage string `json:"KeyUsage" xml:"KeyUsage"` + DeleteDate string `json:"DeleteDate" xml:"DeleteDate"` + Creator string `json:"Creator" xml:"Creator"` + Origin string `json:"Origin" xml:"Origin"` + Description string `json:"Description" xml:"Description"` + KeyId string `json:"KeyId" xml:"KeyId"` + MaterialExpireTime string `json:"MaterialExpireTime" xml:"MaterialExpireTime"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_keys.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_keys.go new file mode 100644 index 00000000..5e36d49f --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_keys.go @@ -0,0 +1,21 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Keys is a nested struct in kms response +type Keys struct { + Key []Key `json:"Key" xml:"Key"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_region.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_region.go new file mode 100644 index 00000000..d54b0e59 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_region.go @@ -0,0 +1,21 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Region is a nested struct in kms response +type Region struct { + RegionId string `json:"RegionId" xml:"RegionId"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_regions.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_regions.go new file mode 100644 index 00000000..4c87936e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_regions.go @@ -0,0 +1,21 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Regions is a nested struct in kms response +type Regions struct { + Region []Region `json:"Region" xml:"Region"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tag.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tag.go new file mode 100644 index 00000000..b2806f8c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tag.go @@ -0,0 +1,23 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Tag is a nested struct in kms response +type Tag struct { + KeyId string `json:"KeyId" xml:"KeyId"` + TagKey string `json:"TagKey" xml:"TagKey"` + TagValue string `json:"TagValue" xml:"TagValue"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tags.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tags.go new file mode 100644 index 00000000..c3c2234b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/struct_tags.go @@ -0,0 +1,21 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Tags is a nested struct in kms response +type Tags struct { + Tag []Tag `json:"Tag" xml:"Tag"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/tag_resource.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/tag_resource.go new file mode 100644 index 00000000..b5c29953 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/tag_resource.go @@ -0,0 +1,104 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// TagResource invokes the kms.TagResource API synchronously +// api document: https://help.aliyun.com/api/kms/tagresource.html +func (client *Client) TagResource(request *TagResourceRequest) (response *TagResourceResponse, err error) { + response = CreateTagResourceResponse() + err = client.DoAction(request, response) + return +} + +// TagResourceWithChan invokes the kms.TagResource API asynchronously +// api document: https://help.aliyun.com/api/kms/tagresource.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) TagResourceWithChan(request *TagResourceRequest) (<-chan *TagResourceResponse, <-chan error) { + responseChan := make(chan *TagResourceResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.TagResource(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// TagResourceWithCallback invokes the kms.TagResource API asynchronously +// api document: https://help.aliyun.com/api/kms/tagresource.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) TagResourceWithCallback(request *TagResourceRequest, callback func(response *TagResourceResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *TagResourceResponse + var err error + defer close(result) + response, err = client.TagResource(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// TagResourceRequest is the request struct for api TagResource +type TagResourceRequest struct { + *requests.RpcRequest + KeyId string `position:"Query" name:"KeyId"` + Tags string `position:"Query" name:"Tags"` +} + +// TagResourceResponse is the response struct for api TagResource +type TagResourceResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateTagResourceRequest creates a request to invoke TagResource API +func CreateTagResourceRequest() (request *TagResourceRequest) { + request = &TagResourceRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "TagResource", "kms", "openAPI") + return +} + +// CreateTagResourceResponse creates a response to parse from TagResource response +func CreateTagResourceResponse() (response *TagResourceResponse) { + response = &TagResourceResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/untag_resource.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/untag_resource.go new file mode 100644 index 00000000..8135ac80 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/untag_resource.go @@ -0,0 +1,104 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UntagResource invokes the kms.UntagResource API synchronously +// api document: https://help.aliyun.com/api/kms/untagresource.html +func (client *Client) UntagResource(request *UntagResourceRequest) (response *UntagResourceResponse, err error) { + response = CreateUntagResourceResponse() + err = client.DoAction(request, response) + return +} + +// UntagResourceWithChan invokes the kms.UntagResource API asynchronously +// api document: https://help.aliyun.com/api/kms/untagresource.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UntagResourceWithChan(request *UntagResourceRequest) (<-chan *UntagResourceResponse, <-chan error) { + responseChan := make(chan *UntagResourceResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UntagResource(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UntagResourceWithCallback invokes the kms.UntagResource API asynchronously +// api document: https://help.aliyun.com/api/kms/untagresource.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UntagResourceWithCallback(request *UntagResourceRequest, callback func(response *UntagResourceResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UntagResourceResponse + var err error + defer close(result) + response, err = client.UntagResource(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UntagResourceRequest is the request struct for api UntagResource +type UntagResourceRequest struct { + *requests.RpcRequest + TagKeys string `position:"Query" name:"TagKeys"` + KeyId string `position:"Query" name:"KeyId"` +} + +// UntagResourceResponse is the response struct for api UntagResource +type UntagResourceResponse struct { + *responses.BaseResponse + KeyId string `json:"KeyId" xml:"KeyId"` +} + +// CreateUntagResourceRequest creates a request to invoke UntagResource API +func CreateUntagResourceRequest() (request *UntagResourceRequest) { + request = &UntagResourceRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "UntagResource", "kms", "openAPI") + return +} + +// CreateUntagResourceResponse creates a response to parse from UntagResource response +func CreateUntagResourceResponse() (response *UntagResourceResponse) { + response = &UntagResourceResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/update_alias.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/update_alias.go new file mode 100644 index 00000000..16b52402 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/kms/update_alias.go @@ -0,0 +1,104 @@ +package kms + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateAlias invokes the kms.UpdateAlias API synchronously +// api document: https://help.aliyun.com/api/kms/updatealias.html +func (client *Client) UpdateAlias(request *UpdateAliasRequest) (response *UpdateAliasResponse, err error) { + response = CreateUpdateAliasResponse() + err = client.DoAction(request, response) + return +} + +// UpdateAliasWithChan invokes the kms.UpdateAlias API asynchronously +// api document: https://help.aliyun.com/api/kms/updatealias.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateAliasWithChan(request *UpdateAliasRequest) (<-chan *UpdateAliasResponse, <-chan error) { + responseChan := make(chan *UpdateAliasResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateAlias(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateAliasWithCallback invokes the kms.UpdateAlias API asynchronously +// api document: https://help.aliyun.com/api/kms/updatealias.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateAliasWithCallback(request *UpdateAliasRequest, callback func(response *UpdateAliasResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateAliasResponse + var err error + defer close(result) + response, err = client.UpdateAlias(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateAliasRequest is the request struct for api UpdateAlias +type UpdateAliasRequest struct { + *requests.RpcRequest + AliasName string `position:"Query" name:"AliasName"` + KeyId string `position:"Query" name:"KeyId"` +} + +// UpdateAliasResponse is the response struct for api UpdateAlias +type UpdateAliasResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateUpdateAliasRequest creates a request to invoke UpdateAlias API +func CreateUpdateAliasRequest() (request *UpdateAliasRequest) { + request = &UpdateAliasRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Kms", "2016-01-20", "UpdateAlias", "kms", "openAPI") + return +} + +// CreateUpdateAliasResponse creates a response to parse from UpdateAlias response +func CreateUpdateAliasResponse() (response *UpdateAliasResponse) { + response = &UpdateAliasResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/jmespath/go-jmespath/.gitignore b/vendor/github.com/jmespath/go-jmespath/.gitignore new file mode 100644 index 00000000..5091fb07 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/.gitignore @@ -0,0 +1,4 @@ +/jpgo +jmespath-fuzz.zip +cpu.out +go-jmespath.test diff --git a/vendor/github.com/jmespath/go-jmespath/.travis.yml b/vendor/github.com/jmespath/go-jmespath/.travis.yml new file mode 100644 index 00000000..1f980775 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/.travis.yml @@ -0,0 +1,9 @@ +language: go + +sudo: false + +go: + - 1.4 + +install: go get -v -t ./... +script: make test diff --git a/vendor/github.com/jmespath/go-jmespath/LICENSE b/vendor/github.com/jmespath/go-jmespath/LICENSE new file mode 100644 index 00000000..b03310a9 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/LICENSE @@ -0,0 +1,13 @@ +Copyright 2015 James Saryerwinnie + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/github.com/jmespath/go-jmespath/Makefile b/vendor/github.com/jmespath/go-jmespath/Makefile new file mode 100644 index 00000000..a828d284 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/Makefile @@ -0,0 +1,44 @@ + +CMD = jpgo + +help: + @echo "Please use \`make ' where is one of" + @echo " test to run all the tests" + @echo " build to build the library and jp executable" + @echo " generate to run codegen" + + +generate: + go generate ./... + +build: + rm -f $(CMD) + go build ./... + rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./... + mv cmd/$(CMD)/$(CMD) . + +test: + go test -v ./... + +check: + go vet ./... + @echo "golint ./..." + @lint=`golint ./...`; \ + lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \ + echo "$$lint"; \ + if [ "$$lint" != "" ]; then exit 1; fi + +htmlc: + go test -coverprofile="/tmp/jpcov" && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov + +buildfuzz: + go-fuzz-build github.com/jmespath/go-jmespath/fuzz + +fuzz: buildfuzz + go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/testdata + +bench: + go test -bench . -cpuprofile cpu.out + +pprof-cpu: + go tool pprof ./go-jmespath.test ./cpu.out diff --git a/vendor/github.com/jmespath/go-jmespath/README.md b/vendor/github.com/jmespath/go-jmespath/README.md new file mode 100644 index 00000000..187ef676 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/README.md @@ -0,0 +1,7 @@ +# go-jmespath - A JMESPath implementation in Go + +[![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath) + + + +See http://jmespath.org for more info. diff --git a/vendor/github.com/jmespath/go-jmespath/api.go b/vendor/github.com/jmespath/go-jmespath/api.go new file mode 100644 index 00000000..8e26ffee --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/api.go @@ -0,0 +1,49 @@ +package jmespath + +import "strconv" + +// JMESPath is the epresentation of a compiled JMES path query. A JMESPath is +// safe for concurrent use by multiple goroutines. +type JMESPath struct { + ast ASTNode + intr *treeInterpreter +} + +// Compile parses a JMESPath expression and returns, if successful, a JMESPath +// object that can be used to match against data. +func Compile(expression string) (*JMESPath, error) { + parser := NewParser() + ast, err := parser.Parse(expression) + if err != nil { + return nil, err + } + jmespath := &JMESPath{ast: ast, intr: newInterpreter()} + return jmespath, nil +} + +// MustCompile is like Compile but panics if the expression cannot be parsed. +// It simplifies safe initialization of global variables holding compiled +// JMESPaths. +func MustCompile(expression string) *JMESPath { + jmespath, err := Compile(expression) + if err != nil { + panic(`jmespath: Compile(` + strconv.Quote(expression) + `): ` + err.Error()) + } + return jmespath +} + +// Search evaluates a JMESPath expression against input data and returns the result. +func (jp *JMESPath) Search(data interface{}) (interface{}, error) { + return jp.intr.Execute(jp.ast, data) +} + +// Search evaluates a JMESPath expression against input data and returns the result. +func Search(expression string, data interface{}) (interface{}, error) { + intr := newInterpreter() + parser := NewParser() + ast, err := parser.Parse(expression) + if err != nil { + return nil, err + } + return intr.Execute(ast, data) +} diff --git a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go new file mode 100644 index 00000000..1cd2d239 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go @@ -0,0 +1,16 @@ +// generated by stringer -type astNodeType; DO NOT EDIT + +package jmespath + +import "fmt" + +const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection" + +var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307} + +func (i astNodeType) String() string { + if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) { + return fmt.Sprintf("astNodeType(%d)", i) + } + return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]] +} diff --git a/vendor/github.com/jmespath/go-jmespath/functions.go b/vendor/github.com/jmespath/go-jmespath/functions.go new file mode 100644 index 00000000..9b7cd89b --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/functions.go @@ -0,0 +1,842 @@ +package jmespath + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "strings" + "unicode/utf8" +) + +type jpFunction func(arguments []interface{}) (interface{}, error) + +type jpType string + +const ( + jpUnknown jpType = "unknown" + jpNumber jpType = "number" + jpString jpType = "string" + jpArray jpType = "array" + jpObject jpType = "object" + jpArrayNumber jpType = "array[number]" + jpArrayString jpType = "array[string]" + jpExpref jpType = "expref" + jpAny jpType = "any" +) + +type functionEntry struct { + name string + arguments []argSpec + handler jpFunction + hasExpRef bool +} + +type argSpec struct { + types []jpType + variadic bool +} + +type byExprString struct { + intr *treeInterpreter + node ASTNode + items []interface{} + hasError bool +} + +func (a *byExprString) Len() int { + return len(a.items) +} +func (a *byExprString) Swap(i, j int) { + a.items[i], a.items[j] = a.items[j], a.items[i] +} +func (a *byExprString) Less(i, j int) bool { + first, err := a.intr.Execute(a.node, a.items[i]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + ith, ok := first.(string) + if !ok { + a.hasError = true + return true + } + second, err := a.intr.Execute(a.node, a.items[j]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + jth, ok := second.(string) + if !ok { + a.hasError = true + return true + } + return ith < jth +} + +type byExprFloat struct { + intr *treeInterpreter + node ASTNode + items []interface{} + hasError bool +} + +func (a *byExprFloat) Len() int { + return len(a.items) +} +func (a *byExprFloat) Swap(i, j int) { + a.items[i], a.items[j] = a.items[j], a.items[i] +} +func (a *byExprFloat) Less(i, j int) bool { + first, err := a.intr.Execute(a.node, a.items[i]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + ith, ok := first.(float64) + if !ok { + a.hasError = true + return true + } + second, err := a.intr.Execute(a.node, a.items[j]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + jth, ok := second.(float64) + if !ok { + a.hasError = true + return true + } + return ith < jth +} + +type functionCaller struct { + functionTable map[string]functionEntry +} + +func newFunctionCaller() *functionCaller { + caller := &functionCaller{} + caller.functionTable = map[string]functionEntry{ + "length": { + name: "length", + arguments: []argSpec{ + {types: []jpType{jpString, jpArray, jpObject}}, + }, + handler: jpfLength, + }, + "starts_with": { + name: "starts_with", + arguments: []argSpec{ + {types: []jpType{jpString}}, + {types: []jpType{jpString}}, + }, + handler: jpfStartsWith, + }, + "abs": { + name: "abs", + arguments: []argSpec{ + {types: []jpType{jpNumber}}, + }, + handler: jpfAbs, + }, + "avg": { + name: "avg", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber}}, + }, + handler: jpfAvg, + }, + "ceil": { + name: "ceil", + arguments: []argSpec{ + {types: []jpType{jpNumber}}, + }, + handler: jpfCeil, + }, + "contains": { + name: "contains", + arguments: []argSpec{ + {types: []jpType{jpArray, jpString}}, + {types: []jpType{jpAny}}, + }, + handler: jpfContains, + }, + "ends_with": { + name: "ends_with", + arguments: []argSpec{ + {types: []jpType{jpString}}, + {types: []jpType{jpString}}, + }, + handler: jpfEndsWith, + }, + "floor": { + name: "floor", + arguments: []argSpec{ + {types: []jpType{jpNumber}}, + }, + handler: jpfFloor, + }, + "map": { + name: "amp", + arguments: []argSpec{ + {types: []jpType{jpExpref}}, + {types: []jpType{jpArray}}, + }, + handler: jpfMap, + hasExpRef: true, + }, + "max": { + name: "max", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber, jpArrayString}}, + }, + handler: jpfMax, + }, + "merge": { + name: "merge", + arguments: []argSpec{ + {types: []jpType{jpObject}, variadic: true}, + }, + handler: jpfMerge, + }, + "max_by": { + name: "max_by", + arguments: []argSpec{ + {types: []jpType{jpArray}}, + {types: []jpType{jpExpref}}, + }, + handler: jpfMaxBy, + hasExpRef: true, + }, + "sum": { + name: "sum", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber}}, + }, + handler: jpfSum, + }, + "min": { + name: "min", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber, jpArrayString}}, + }, + handler: jpfMin, + }, + "min_by": { + name: "min_by", + arguments: []argSpec{ + {types: []jpType{jpArray}}, + {types: []jpType{jpExpref}}, + }, + handler: jpfMinBy, + hasExpRef: true, + }, + "type": { + name: "type", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfType, + }, + "keys": { + name: "keys", + arguments: []argSpec{ + {types: []jpType{jpObject}}, + }, + handler: jpfKeys, + }, + "values": { + name: "values", + arguments: []argSpec{ + {types: []jpType{jpObject}}, + }, + handler: jpfValues, + }, + "sort": { + name: "sort", + arguments: []argSpec{ + {types: []jpType{jpArrayString, jpArrayNumber}}, + }, + handler: jpfSort, + }, + "sort_by": { + name: "sort_by", + arguments: []argSpec{ + {types: []jpType{jpArray}}, + {types: []jpType{jpExpref}}, + }, + handler: jpfSortBy, + hasExpRef: true, + }, + "join": { + name: "join", + arguments: []argSpec{ + {types: []jpType{jpString}}, + {types: []jpType{jpArrayString}}, + }, + handler: jpfJoin, + }, + "reverse": { + name: "reverse", + arguments: []argSpec{ + {types: []jpType{jpArray, jpString}}, + }, + handler: jpfReverse, + }, + "to_array": { + name: "to_array", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfToArray, + }, + "to_string": { + name: "to_string", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfToString, + }, + "to_number": { + name: "to_number", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfToNumber, + }, + "not_null": { + name: "not_null", + arguments: []argSpec{ + {types: []jpType{jpAny}, variadic: true}, + }, + handler: jpfNotNull, + }, + } + return caller +} + +func (e *functionEntry) resolveArgs(arguments []interface{}) ([]interface{}, error) { + if len(e.arguments) == 0 { + return arguments, nil + } + if !e.arguments[len(e.arguments)-1].variadic { + if len(e.arguments) != len(arguments) { + return nil, errors.New("incorrect number of args") + } + for i, spec := range e.arguments { + userArg := arguments[i] + err := spec.typeCheck(userArg) + if err != nil { + return nil, err + } + } + return arguments, nil + } + if len(arguments) < len(e.arguments) { + return nil, errors.New("Invalid arity.") + } + return arguments, nil +} + +func (a *argSpec) typeCheck(arg interface{}) error { + for _, t := range a.types { + switch t { + case jpNumber: + if _, ok := arg.(float64); ok { + return nil + } + case jpString: + if _, ok := arg.(string); ok { + return nil + } + case jpArray: + if isSliceType(arg) { + return nil + } + case jpObject: + if _, ok := arg.(map[string]interface{}); ok { + return nil + } + case jpArrayNumber: + if _, ok := toArrayNum(arg); ok { + return nil + } + case jpArrayString: + if _, ok := toArrayStr(arg); ok { + return nil + } + case jpAny: + return nil + case jpExpref: + if _, ok := arg.(expRef); ok { + return nil + } + } + } + return fmt.Errorf("Invalid type for: %v, expected: %#v", arg, a.types) +} + +func (f *functionCaller) CallFunction(name string, arguments []interface{}, intr *treeInterpreter) (interface{}, error) { + entry, ok := f.functionTable[name] + if !ok { + return nil, errors.New("unknown function: " + name) + } + resolvedArgs, err := entry.resolveArgs(arguments) + if err != nil { + return nil, err + } + if entry.hasExpRef { + var extra []interface{} + extra = append(extra, intr) + resolvedArgs = append(extra, resolvedArgs...) + } + return entry.handler(resolvedArgs) +} + +func jpfAbs(arguments []interface{}) (interface{}, error) { + num := arguments[0].(float64) + return math.Abs(num), nil +} + +func jpfLength(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if c, ok := arg.(string); ok { + return float64(utf8.RuneCountInString(c)), nil + } else if isSliceType(arg) { + v := reflect.ValueOf(arg) + return float64(v.Len()), nil + } else if c, ok := arg.(map[string]interface{}); ok { + return float64(len(c)), nil + } + return nil, errors.New("could not compute length()") +} + +func jpfStartsWith(arguments []interface{}) (interface{}, error) { + search := arguments[0].(string) + prefix := arguments[1].(string) + return strings.HasPrefix(search, prefix), nil +} + +func jpfAvg(arguments []interface{}) (interface{}, error) { + // We've already type checked the value so we can safely use + // type assertions. + args := arguments[0].([]interface{}) + length := float64(len(args)) + numerator := 0.0 + for _, n := range args { + numerator += n.(float64) + } + return numerator / length, nil +} +func jpfCeil(arguments []interface{}) (interface{}, error) { + val := arguments[0].(float64) + return math.Ceil(val), nil +} +func jpfContains(arguments []interface{}) (interface{}, error) { + search := arguments[0] + el := arguments[1] + if searchStr, ok := search.(string); ok { + if elStr, ok := el.(string); ok { + return strings.Index(searchStr, elStr) != -1, nil + } + return false, nil + } + // Otherwise this is a generic contains for []interface{} + general := search.([]interface{}) + for _, item := range general { + if item == el { + return true, nil + } + } + return false, nil +} +func jpfEndsWith(arguments []interface{}) (interface{}, error) { + search := arguments[0].(string) + suffix := arguments[1].(string) + return strings.HasSuffix(search, suffix), nil +} +func jpfFloor(arguments []interface{}) (interface{}, error) { + val := arguments[0].(float64) + return math.Floor(val), nil +} +func jpfMap(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + exp := arguments[1].(expRef) + node := exp.ref + arr := arguments[2].([]interface{}) + mapped := make([]interface{}, 0, len(arr)) + for _, value := range arr { + current, err := intr.Execute(node, value) + if err != nil { + return nil, err + } + mapped = append(mapped, current) + } + return mapped, nil +} +func jpfMax(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item > best { + best = item + } + } + return best, nil + } + // Otherwise we're dealing with a max() of strings. + items, _ := toArrayStr(arguments[0]) + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item > best { + best = item + } + } + return best, nil +} +func jpfMerge(arguments []interface{}) (interface{}, error) { + final := make(map[string]interface{}) + for _, m := range arguments { + mapped := m.(map[string]interface{}) + for key, value := range mapped { + final[key] = value + } + } + return final, nil +} +func jpfMaxBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return nil, nil + } else if len(arr) == 1 { + return arr[0], nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + switch t := start.(type) { + case float64: + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(float64) + if !ok { + return nil, errors.New("invalid type, must be number") + } + if current > bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + case string: + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(string) + if !ok { + return nil, errors.New("invalid type, must be string") + } + if current > bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + default: + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfSum(arguments []interface{}) (interface{}, error) { + items, _ := toArrayNum(arguments[0]) + sum := 0.0 + for _, item := range items { + sum += item + } + return sum, nil +} + +func jpfMin(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item < best { + best = item + } + } + return best, nil + } + items, _ := toArrayStr(arguments[0]) + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item < best { + best = item + } + } + return best, nil +} + +func jpfMinBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return nil, nil + } else if len(arr) == 1 { + return arr[0], nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + if t, ok := start.(float64); ok { + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(float64) + if !ok { + return nil, errors.New("invalid type, must be number") + } + if current < bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + } else if t, ok := start.(string); ok { + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(string) + if !ok { + return nil, errors.New("invalid type, must be string") + } + if current < bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + } else { + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfType(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if _, ok := arg.(float64); ok { + return "number", nil + } + if _, ok := arg.(string); ok { + return "string", nil + } + if _, ok := arg.([]interface{}); ok { + return "array", nil + } + if _, ok := arg.(map[string]interface{}); ok { + return "object", nil + } + if arg == nil { + return "null", nil + } + if arg == true || arg == false { + return "boolean", nil + } + return nil, errors.New("unknown type") +} +func jpfKeys(arguments []interface{}) (interface{}, error) { + arg := arguments[0].(map[string]interface{}) + collected := make([]interface{}, 0, len(arg)) + for key := range arg { + collected = append(collected, key) + } + return collected, nil +} +func jpfValues(arguments []interface{}) (interface{}, error) { + arg := arguments[0].(map[string]interface{}) + collected := make([]interface{}, 0, len(arg)) + for _, value := range arg { + collected = append(collected, value) + } + return collected, nil +} +func jpfSort(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + d := sort.Float64Slice(items) + sort.Stable(d) + final := make([]interface{}, len(d)) + for i, val := range d { + final[i] = val + } + return final, nil + } + // Otherwise we're dealing with sort()'ing strings. + items, _ := toArrayStr(arguments[0]) + d := sort.StringSlice(items) + sort.Stable(d) + final := make([]interface{}, len(d)) + for i, val := range d { + final[i] = val + } + return final, nil +} +func jpfSortBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return arr, nil + } else if len(arr) == 1 { + return arr, nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + if _, ok := start.(float64); ok { + sortable := &byExprFloat{intr, node, arr, false} + sort.Stable(sortable) + if sortable.hasError { + return nil, errors.New("error in sort_by comparison") + } + return arr, nil + } else if _, ok := start.(string); ok { + sortable := &byExprString{intr, node, arr, false} + sort.Stable(sortable) + if sortable.hasError { + return nil, errors.New("error in sort_by comparison") + } + return arr, nil + } else { + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfJoin(arguments []interface{}) (interface{}, error) { + sep := arguments[0].(string) + // We can't just do arguments[1].([]string), we have to + // manually convert each item to a string. + arrayStr := []string{} + for _, item := range arguments[1].([]interface{}) { + arrayStr = append(arrayStr, item.(string)) + } + return strings.Join(arrayStr, sep), nil +} +func jpfReverse(arguments []interface{}) (interface{}, error) { + if s, ok := arguments[0].(string); ok { + r := []rune(s) + for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { + r[i], r[j] = r[j], r[i] + } + return string(r), nil + } + items := arguments[0].([]interface{}) + length := len(items) + reversed := make([]interface{}, length) + for i, item := range items { + reversed[length-(i+1)] = item + } + return reversed, nil +} +func jpfToArray(arguments []interface{}) (interface{}, error) { + if _, ok := arguments[0].([]interface{}); ok { + return arguments[0], nil + } + return arguments[:1:1], nil +} +func jpfToString(arguments []interface{}) (interface{}, error) { + if v, ok := arguments[0].(string); ok { + return v, nil + } + result, err := json.Marshal(arguments[0]) + if err != nil { + return nil, err + } + return string(result), nil +} +func jpfToNumber(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if v, ok := arg.(float64); ok { + return v, nil + } + if v, ok := arg.(string); ok { + conv, err := strconv.ParseFloat(v, 64) + if err != nil { + return nil, nil + } + return conv, nil + } + if _, ok := arg.([]interface{}); ok { + return nil, nil + } + if _, ok := arg.(map[string]interface{}); ok { + return nil, nil + } + if arg == nil { + return nil, nil + } + if arg == true || arg == false { + return nil, nil + } + return nil, errors.New("unknown type") +} +func jpfNotNull(arguments []interface{}) (interface{}, error) { + for _, arg := range arguments { + if arg != nil { + return arg, nil + } + } + return nil, nil +} diff --git a/vendor/github.com/jmespath/go-jmespath/interpreter.go b/vendor/github.com/jmespath/go-jmespath/interpreter.go new file mode 100644 index 00000000..13c74604 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/interpreter.go @@ -0,0 +1,418 @@ +package jmespath + +import ( + "errors" + "reflect" + "unicode" + "unicode/utf8" +) + +/* This is a tree based interpreter. It walks the AST and directly + interprets the AST to search through a JSON document. +*/ + +type treeInterpreter struct { + fCall *functionCaller +} + +func newInterpreter() *treeInterpreter { + interpreter := treeInterpreter{} + interpreter.fCall = newFunctionCaller() + return &interpreter +} + +type expRef struct { + ref ASTNode +} + +// Execute takes an ASTNode and input data and interprets the AST directly. +// It will produce the result of applying the JMESPath expression associated +// with the ASTNode to the input data "value". +func (intr *treeInterpreter) Execute(node ASTNode, value interface{}) (interface{}, error) { + switch node.nodeType { + case ASTComparator: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + right, err := intr.Execute(node.children[1], value) + if err != nil { + return nil, err + } + switch node.value { + case tEQ: + return objsEqual(left, right), nil + case tNE: + return !objsEqual(left, right), nil + } + leftNum, ok := left.(float64) + if !ok { + return nil, nil + } + rightNum, ok := right.(float64) + if !ok { + return nil, nil + } + switch node.value { + case tGT: + return leftNum > rightNum, nil + case tGTE: + return leftNum >= rightNum, nil + case tLT: + return leftNum < rightNum, nil + case tLTE: + return leftNum <= rightNum, nil + } + case ASTExpRef: + return expRef{ref: node.children[0]}, nil + case ASTFunctionExpression: + resolvedArgs := []interface{}{} + for _, arg := range node.children { + current, err := intr.Execute(arg, value) + if err != nil { + return nil, err + } + resolvedArgs = append(resolvedArgs, current) + } + return intr.fCall.CallFunction(node.value.(string), resolvedArgs, intr) + case ASTField: + if m, ok := value.(map[string]interface{}); ok { + key := node.value.(string) + return m[key], nil + } + return intr.fieldFromStruct(node.value.(string), value) + case ASTFilterProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + sliceType, ok := left.([]interface{}) + if !ok { + if isSliceType(left) { + return intr.filterProjectionWithReflection(node, left) + } + return nil, nil + } + compareNode := node.children[2] + collected := []interface{}{} + for _, element := range sliceType { + result, err := intr.Execute(compareNode, element) + if err != nil { + return nil, err + } + if !isFalse(result) { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + } + return collected, nil + case ASTFlatten: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + sliceType, ok := left.([]interface{}) + if !ok { + // If we can't type convert to []interface{}, there's + // a chance this could still work via reflection if we're + // dealing with user provided types. + if isSliceType(left) { + return intr.flattenWithReflection(left) + } + return nil, nil + } + flattened := []interface{}{} + for _, element := range sliceType { + if elementSlice, ok := element.([]interface{}); ok { + flattened = append(flattened, elementSlice...) + } else if isSliceType(element) { + reflectFlat := []interface{}{} + v := reflect.ValueOf(element) + for i := 0; i < v.Len(); i++ { + reflectFlat = append(reflectFlat, v.Index(i).Interface()) + } + flattened = append(flattened, reflectFlat...) + } else { + flattened = append(flattened, element) + } + } + return flattened, nil + case ASTIdentity, ASTCurrentNode: + return value, nil + case ASTIndex: + if sliceType, ok := value.([]interface{}); ok { + index := node.value.(int) + if index < 0 { + index += len(sliceType) + } + if index < len(sliceType) && index >= 0 { + return sliceType[index], nil + } + return nil, nil + } + // Otherwise try via reflection. + rv := reflect.ValueOf(value) + if rv.Kind() == reflect.Slice { + index := node.value.(int) + if index < 0 { + index += rv.Len() + } + if index < rv.Len() && index >= 0 { + v := rv.Index(index) + return v.Interface(), nil + } + } + return nil, nil + case ASTKeyValPair: + return intr.Execute(node.children[0], value) + case ASTLiteral: + return node.value, nil + case ASTMultiSelectHash: + if value == nil { + return nil, nil + } + collected := make(map[string]interface{}) + for _, child := range node.children { + current, err := intr.Execute(child, value) + if err != nil { + return nil, err + } + key := child.value.(string) + collected[key] = current + } + return collected, nil + case ASTMultiSelectList: + if value == nil { + return nil, nil + } + collected := []interface{}{} + for _, child := range node.children { + current, err := intr.Execute(child, value) + if err != nil { + return nil, err + } + collected = append(collected, current) + } + return collected, nil + case ASTOrExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + matched, err = intr.Execute(node.children[1], value) + if err != nil { + return nil, err + } + } + return matched, nil + case ASTAndExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + return matched, nil + } + return intr.Execute(node.children[1], value) + case ASTNotExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + return true, nil + } + return false, nil + case ASTPipe: + result := value + var err error + for _, child := range node.children { + result, err = intr.Execute(child, result) + if err != nil { + return nil, err + } + } + return result, nil + case ASTProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + sliceType, ok := left.([]interface{}) + if !ok { + if isSliceType(left) { + return intr.projectWithReflection(node, left) + } + return nil, nil + } + collected := []interface{}{} + var current interface{} + for _, element := range sliceType { + current, err = intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + return collected, nil + case ASTSubexpression, ASTIndexExpression: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + return intr.Execute(node.children[1], left) + case ASTSlice: + sliceType, ok := value.([]interface{}) + if !ok { + if isSliceType(value) { + return intr.sliceWithReflection(node, value) + } + return nil, nil + } + parts := node.value.([]*int) + sliceParams := make([]sliceParam, 3) + for i, part := range parts { + if part != nil { + sliceParams[i].Specified = true + sliceParams[i].N = *part + } + } + return slice(sliceType, sliceParams) + case ASTValueProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + mapType, ok := left.(map[string]interface{}) + if !ok { + return nil, nil + } + values := make([]interface{}, len(mapType)) + for _, value := range mapType { + values = append(values, value) + } + collected := []interface{}{} + for _, element := range values { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + return collected, nil + } + return nil, errors.New("Unknown AST node: " + node.nodeType.String()) +} + +func (intr *treeInterpreter) fieldFromStruct(key string, value interface{}) (interface{}, error) { + rv := reflect.ValueOf(value) + first, n := utf8.DecodeRuneInString(key) + fieldName := string(unicode.ToUpper(first)) + key[n:] + if rv.Kind() == reflect.Struct { + v := rv.FieldByName(fieldName) + if !v.IsValid() { + return nil, nil + } + return v.Interface(), nil + } else if rv.Kind() == reflect.Ptr { + // Handle multiple levels of indirection? + if rv.IsNil() { + return nil, nil + } + rv = rv.Elem() + v := rv.FieldByName(fieldName) + if !v.IsValid() { + return nil, nil + } + return v.Interface(), nil + } + return nil, nil +} + +func (intr *treeInterpreter) flattenWithReflection(value interface{}) (interface{}, error) { + v := reflect.ValueOf(value) + flattened := []interface{}{} + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + if reflect.TypeOf(element).Kind() == reflect.Slice { + // Then insert the contents of the element + // slice into the flattened slice, + // i.e flattened = append(flattened, mySlice...) + elementV := reflect.ValueOf(element) + for j := 0; j < elementV.Len(); j++ { + flattened = append( + flattened, elementV.Index(j).Interface()) + } + } else { + flattened = append(flattened, element) + } + } + return flattened, nil +} + +func (intr *treeInterpreter) sliceWithReflection(node ASTNode, value interface{}) (interface{}, error) { + v := reflect.ValueOf(value) + parts := node.value.([]*int) + sliceParams := make([]sliceParam, 3) + for i, part := range parts { + if part != nil { + sliceParams[i].Specified = true + sliceParams[i].N = *part + } + } + final := []interface{}{} + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + final = append(final, element) + } + return slice(final, sliceParams) +} + +func (intr *treeInterpreter) filterProjectionWithReflection(node ASTNode, value interface{}) (interface{}, error) { + compareNode := node.children[2] + collected := []interface{}{} + v := reflect.ValueOf(value) + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + result, err := intr.Execute(compareNode, element) + if err != nil { + return nil, err + } + if !isFalse(result) { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + } + return collected, nil +} + +func (intr *treeInterpreter) projectWithReflection(node ASTNode, value interface{}) (interface{}, error) { + collected := []interface{}{} + v := reflect.ValueOf(value) + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + result, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if result != nil { + collected = append(collected, result) + } + } + return collected, nil +} diff --git a/vendor/github.com/jmespath/go-jmespath/lexer.go b/vendor/github.com/jmespath/go-jmespath/lexer.go new file mode 100644 index 00000000..817900c8 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/lexer.go @@ -0,0 +1,420 @@ +package jmespath + +import ( + "bytes" + "encoding/json" + "fmt" + "strconv" + "strings" + "unicode/utf8" +) + +type token struct { + tokenType tokType + value string + position int + length int +} + +type tokType int + +const eof = -1 + +// Lexer contains information about the expression being tokenized. +type Lexer struct { + expression string // The expression provided by the user. + currentPos int // The current position in the string. + lastWidth int // The width of the current rune. This + buf bytes.Buffer // Internal buffer used for building up values. +} + +// SyntaxError is the main error used whenever a lexing or parsing error occurs. +type SyntaxError struct { + msg string // Error message displayed to user + Expression string // Expression that generated a SyntaxError + Offset int // The location in the string where the error occurred +} + +func (e SyntaxError) Error() string { + // In the future, it would be good to underline the specific + // location where the error occurred. + return "SyntaxError: " + e.msg +} + +// HighlightLocation will show where the syntax error occurred. +// It will place a "^" character on a line below the expression +// at the point where the syntax error occurred. +func (e SyntaxError) HighlightLocation() string { + return e.Expression + "\n" + strings.Repeat(" ", e.Offset) + "^" +} + +//go:generate stringer -type=tokType +const ( + tUnknown tokType = iota + tStar + tDot + tFilter + tFlatten + tLparen + tRparen + tLbracket + tRbracket + tLbrace + tRbrace + tOr + tPipe + tNumber + tUnquotedIdentifier + tQuotedIdentifier + tComma + tColon + tLT + tLTE + tGT + tGTE + tEQ + tNE + tJSONLiteral + tStringLiteral + tCurrent + tExpref + tAnd + tNot + tEOF +) + +var basicTokens = map[rune]tokType{ + '.': tDot, + '*': tStar, + ',': tComma, + ':': tColon, + '{': tLbrace, + '}': tRbrace, + ']': tRbracket, // tLbracket not included because it could be "[]" + '(': tLparen, + ')': tRparen, + '@': tCurrent, +} + +// Bit mask for [a-zA-Z_] shifted down 64 bits to fit in a single uint64. +// When using this bitmask just be sure to shift the rune down 64 bits +// before checking against identifierStartBits. +const identifierStartBits uint64 = 576460745995190270 + +// Bit mask for [a-zA-Z0-9], 128 bits -> 2 uint64s. +var identifierTrailingBits = [2]uint64{287948901175001088, 576460745995190270} + +var whiteSpace = map[rune]bool{ + ' ': true, '\t': true, '\n': true, '\r': true, +} + +func (t token) String() string { + return fmt.Sprintf("Token{%+v, %s, %d, %d}", + t.tokenType, t.value, t.position, t.length) +} + +// NewLexer creates a new JMESPath lexer. +func NewLexer() *Lexer { + lexer := Lexer{} + return &lexer +} + +func (lexer *Lexer) next() rune { + if lexer.currentPos >= len(lexer.expression) { + lexer.lastWidth = 0 + return eof + } + r, w := utf8.DecodeRuneInString(lexer.expression[lexer.currentPos:]) + lexer.lastWidth = w + lexer.currentPos += w + return r +} + +func (lexer *Lexer) back() { + lexer.currentPos -= lexer.lastWidth +} + +func (lexer *Lexer) peek() rune { + t := lexer.next() + lexer.back() + return t +} + +// tokenize takes an expression and returns corresponding tokens. +func (lexer *Lexer) tokenize(expression string) ([]token, error) { + var tokens []token + lexer.expression = expression + lexer.currentPos = 0 + lexer.lastWidth = 0 +loop: + for { + r := lexer.next() + if identifierStartBits&(1<<(uint64(r)-64)) > 0 { + t := lexer.consumeUnquotedIdentifier() + tokens = append(tokens, t) + } else if val, ok := basicTokens[r]; ok { + // Basic single char token. + t := token{ + tokenType: val, + value: string(r), + position: lexer.currentPos - lexer.lastWidth, + length: 1, + } + tokens = append(tokens, t) + } else if r == '-' || (r >= '0' && r <= '9') { + t := lexer.consumeNumber() + tokens = append(tokens, t) + } else if r == '[' { + t := lexer.consumeLBracket() + tokens = append(tokens, t) + } else if r == '"' { + t, err := lexer.consumeQuotedIdentifier() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '\'' { + t, err := lexer.consumeRawStringLiteral() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '`' { + t, err := lexer.consumeLiteral() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '|' { + t := lexer.matchOrElse(r, '|', tOr, tPipe) + tokens = append(tokens, t) + } else if r == '<' { + t := lexer.matchOrElse(r, '=', tLTE, tLT) + tokens = append(tokens, t) + } else if r == '>' { + t := lexer.matchOrElse(r, '=', tGTE, tGT) + tokens = append(tokens, t) + } else if r == '!' { + t := lexer.matchOrElse(r, '=', tNE, tNot) + tokens = append(tokens, t) + } else if r == '=' { + t := lexer.matchOrElse(r, '=', tEQ, tUnknown) + tokens = append(tokens, t) + } else if r == '&' { + t := lexer.matchOrElse(r, '&', tAnd, tExpref) + tokens = append(tokens, t) + } else if r == eof { + break loop + } else if _, ok := whiteSpace[r]; ok { + // Ignore whitespace + } else { + return tokens, lexer.syntaxError(fmt.Sprintf("Unknown char: %s", strconv.QuoteRuneToASCII(r))) + } + } + tokens = append(tokens, token{tEOF, "", len(lexer.expression), 0}) + return tokens, nil +} + +// Consume characters until the ending rune "r" is reached. +// If the end of the expression is reached before seeing the +// terminating rune "r", then an error is returned. +// If no error occurs then the matching substring is returned. +// The returned string will not include the ending rune. +func (lexer *Lexer) consumeUntil(end rune) (string, error) { + start := lexer.currentPos + current := lexer.next() + for current != end && current != eof { + if current == '\\' && lexer.peek() != eof { + lexer.next() + } + current = lexer.next() + } + if lexer.lastWidth == 0 { + // Then we hit an EOF so we never reached the closing + // delimiter. + return "", SyntaxError{ + msg: "Unclosed delimiter: " + string(end), + Expression: lexer.expression, + Offset: len(lexer.expression), + } + } + return lexer.expression[start : lexer.currentPos-lexer.lastWidth], nil +} + +func (lexer *Lexer) consumeLiteral() (token, error) { + start := lexer.currentPos + value, err := lexer.consumeUntil('`') + if err != nil { + return token{}, err + } + value = strings.Replace(value, "\\`", "`", -1) + return token{ + tokenType: tJSONLiteral, + value: value, + position: start, + length: len(value), + }, nil +} + +func (lexer *Lexer) consumeRawStringLiteral() (token, error) { + start := lexer.currentPos + currentIndex := start + current := lexer.next() + for current != '\'' && lexer.peek() != eof { + if current == '\\' && lexer.peek() == '\'' { + chunk := lexer.expression[currentIndex : lexer.currentPos-1] + lexer.buf.WriteString(chunk) + lexer.buf.WriteString("'") + lexer.next() + currentIndex = lexer.currentPos + } + current = lexer.next() + } + if lexer.lastWidth == 0 { + // Then we hit an EOF so we never reached the closing + // delimiter. + return token{}, SyntaxError{ + msg: "Unclosed delimiter: '", + Expression: lexer.expression, + Offset: len(lexer.expression), + } + } + if currentIndex < lexer.currentPos { + lexer.buf.WriteString(lexer.expression[currentIndex : lexer.currentPos-1]) + } + value := lexer.buf.String() + // Reset the buffer so it can reused again. + lexer.buf.Reset() + return token{ + tokenType: tStringLiteral, + value: value, + position: start, + length: len(value), + }, nil +} + +func (lexer *Lexer) syntaxError(msg string) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: lexer.expression, + Offset: lexer.currentPos - 1, + } +} + +// Checks for a two char token, otherwise matches a single character +// token. This is used whenever a two char token overlaps a single +// char token, e.g. "||" -> tPipe, "|" -> tOr. +func (lexer *Lexer) matchOrElse(first rune, second rune, matchedType tokType, singleCharType tokType) token { + start := lexer.currentPos - lexer.lastWidth + nextRune := lexer.next() + var t token + if nextRune == second { + t = token{ + tokenType: matchedType, + value: string(first) + string(second), + position: start, + length: 2, + } + } else { + lexer.back() + t = token{ + tokenType: singleCharType, + value: string(first), + position: start, + length: 1, + } + } + return t +} + +func (lexer *Lexer) consumeLBracket() token { + // There's three options here: + // 1. A filter expression "[?" + // 2. A flatten operator "[]" + // 3. A bare rbracket "[" + start := lexer.currentPos - lexer.lastWidth + nextRune := lexer.next() + var t token + if nextRune == '?' { + t = token{ + tokenType: tFilter, + value: "[?", + position: start, + length: 2, + } + } else if nextRune == ']' { + t = token{ + tokenType: tFlatten, + value: "[]", + position: start, + length: 2, + } + } else { + t = token{ + tokenType: tLbracket, + value: "[", + position: start, + length: 1, + } + lexer.back() + } + return t +} + +func (lexer *Lexer) consumeQuotedIdentifier() (token, error) { + start := lexer.currentPos + value, err := lexer.consumeUntil('"') + if err != nil { + return token{}, err + } + var decoded string + asJSON := []byte("\"" + value + "\"") + if err := json.Unmarshal([]byte(asJSON), &decoded); err != nil { + return token{}, err + } + return token{ + tokenType: tQuotedIdentifier, + value: decoded, + position: start - 1, + length: len(decoded), + }, nil +} + +func (lexer *Lexer) consumeUnquotedIdentifier() token { + // Consume runes until we reach the end of an unquoted + // identifier. + start := lexer.currentPos - lexer.lastWidth + for { + r := lexer.next() + if r < 0 || r > 128 || identifierTrailingBits[uint64(r)/64]&(1<<(uint64(r)%64)) == 0 { + lexer.back() + break + } + } + value := lexer.expression[start:lexer.currentPos] + return token{ + tokenType: tUnquotedIdentifier, + value: value, + position: start, + length: lexer.currentPos - start, + } +} + +func (lexer *Lexer) consumeNumber() token { + // Consume runes until we reach something that's not a number. + start := lexer.currentPos - lexer.lastWidth + for { + r := lexer.next() + if r < '0' || r > '9' { + lexer.back() + break + } + } + value := lexer.expression[start:lexer.currentPos] + return token{ + tokenType: tNumber, + value: value, + position: start, + length: lexer.currentPos - start, + } +} diff --git a/vendor/github.com/jmespath/go-jmespath/parser.go b/vendor/github.com/jmespath/go-jmespath/parser.go new file mode 100644 index 00000000..1240a175 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/parser.go @@ -0,0 +1,603 @@ +package jmespath + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" +) + +type astNodeType int + +//go:generate stringer -type astNodeType +const ( + ASTEmpty astNodeType = iota + ASTComparator + ASTCurrentNode + ASTExpRef + ASTFunctionExpression + ASTField + ASTFilterProjection + ASTFlatten + ASTIdentity + ASTIndex + ASTIndexExpression + ASTKeyValPair + ASTLiteral + ASTMultiSelectHash + ASTMultiSelectList + ASTOrExpression + ASTAndExpression + ASTNotExpression + ASTPipe + ASTProjection + ASTSubexpression + ASTSlice + ASTValueProjection +) + +// ASTNode represents the abstract syntax tree of a JMESPath expression. +type ASTNode struct { + nodeType astNodeType + value interface{} + children []ASTNode +} + +func (node ASTNode) String() string { + return node.PrettyPrint(0) +} + +// PrettyPrint will pretty print the parsed AST. +// The AST is an implementation detail and this pretty print +// function is provided as a convenience method to help with +// debugging. You should not rely on its output as the internal +// structure of the AST may change at any time. +func (node ASTNode) PrettyPrint(indent int) string { + spaces := strings.Repeat(" ", indent) + output := fmt.Sprintf("%s%s {\n", spaces, node.nodeType) + nextIndent := indent + 2 + if node.value != nil { + if converted, ok := node.value.(fmt.Stringer); ok { + // Account for things like comparator nodes + // that are enums with a String() method. + output += fmt.Sprintf("%svalue: %s\n", strings.Repeat(" ", nextIndent), converted.String()) + } else { + output += fmt.Sprintf("%svalue: %#v\n", strings.Repeat(" ", nextIndent), node.value) + } + } + lastIndex := len(node.children) + if lastIndex > 0 { + output += fmt.Sprintf("%schildren: {\n", strings.Repeat(" ", nextIndent)) + childIndent := nextIndent + 2 + for _, elem := range node.children { + output += elem.PrettyPrint(childIndent) + } + } + output += fmt.Sprintf("%s}\n", spaces) + return output +} + +var bindingPowers = map[tokType]int{ + tEOF: 0, + tUnquotedIdentifier: 0, + tQuotedIdentifier: 0, + tRbracket: 0, + tRparen: 0, + tComma: 0, + tRbrace: 0, + tNumber: 0, + tCurrent: 0, + tExpref: 0, + tColon: 0, + tPipe: 1, + tOr: 2, + tAnd: 3, + tEQ: 5, + tLT: 5, + tLTE: 5, + tGT: 5, + tGTE: 5, + tNE: 5, + tFlatten: 9, + tStar: 20, + tFilter: 21, + tDot: 40, + tNot: 45, + tLbrace: 50, + tLbracket: 55, + tLparen: 60, +} + +// Parser holds state about the current expression being parsed. +type Parser struct { + expression string + tokens []token + index int +} + +// NewParser creates a new JMESPath parser. +func NewParser() *Parser { + p := Parser{} + return &p +} + +// Parse will compile a JMESPath expression. +func (p *Parser) Parse(expression string) (ASTNode, error) { + lexer := NewLexer() + p.expression = expression + p.index = 0 + tokens, err := lexer.tokenize(expression) + if err != nil { + return ASTNode{}, err + } + p.tokens = tokens + parsed, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if p.current() != tEOF { + return ASTNode{}, p.syntaxError(fmt.Sprintf( + "Unexpected token at the end of the expresssion: %s", p.current())) + } + return parsed, nil +} + +func (p *Parser) parseExpression(bindingPower int) (ASTNode, error) { + var err error + leftToken := p.lookaheadToken(0) + p.advance() + leftNode, err := p.nud(leftToken) + if err != nil { + return ASTNode{}, err + } + currentToken := p.current() + for bindingPower < bindingPowers[currentToken] { + p.advance() + leftNode, err = p.led(currentToken, leftNode) + if err != nil { + return ASTNode{}, err + } + currentToken = p.current() + } + return leftNode, nil +} + +func (p *Parser) parseIndexExpression() (ASTNode, error) { + if p.lookahead(0) == tColon || p.lookahead(1) == tColon { + return p.parseSliceExpression() + } + indexStr := p.lookaheadToken(0).value + parsedInt, err := strconv.Atoi(indexStr) + if err != nil { + return ASTNode{}, err + } + indexNode := ASTNode{nodeType: ASTIndex, value: parsedInt} + p.advance() + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + return indexNode, nil +} + +func (p *Parser) parseSliceExpression() (ASTNode, error) { + parts := []*int{nil, nil, nil} + index := 0 + current := p.current() + for current != tRbracket && index < 3 { + if current == tColon { + index++ + p.advance() + } else if current == tNumber { + parsedInt, err := strconv.Atoi(p.lookaheadToken(0).value) + if err != nil { + return ASTNode{}, err + } + parts[index] = &parsedInt + p.advance() + } else { + return ASTNode{}, p.syntaxError( + "Expected tColon or tNumber" + ", received: " + p.current().String()) + } + current = p.current() + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTSlice, + value: parts, + }, nil +} + +func (p *Parser) match(tokenType tokType) error { + if p.current() == tokenType { + p.advance() + return nil + } + return p.syntaxError("Expected " + tokenType.String() + ", received: " + p.current().String()) +} + +func (p *Parser) led(tokenType tokType, node ASTNode) (ASTNode, error) { + switch tokenType { + case tDot: + if p.current() != tStar { + right, err := p.parseDotRHS(bindingPowers[tDot]) + return ASTNode{ + nodeType: ASTSubexpression, + children: []ASTNode{node, right}, + }, err + } + p.advance() + right, err := p.parseProjectionRHS(bindingPowers[tDot]) + return ASTNode{ + nodeType: ASTValueProjection, + children: []ASTNode{node, right}, + }, err + case tPipe: + right, err := p.parseExpression(bindingPowers[tPipe]) + return ASTNode{nodeType: ASTPipe, children: []ASTNode{node, right}}, err + case tOr: + right, err := p.parseExpression(bindingPowers[tOr]) + return ASTNode{nodeType: ASTOrExpression, children: []ASTNode{node, right}}, err + case tAnd: + right, err := p.parseExpression(bindingPowers[tAnd]) + return ASTNode{nodeType: ASTAndExpression, children: []ASTNode{node, right}}, err + case tLparen: + name := node.value + var args []ASTNode + for p.current() != tRparen { + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if p.current() == tComma { + if err := p.match(tComma); err != nil { + return ASTNode{}, err + } + } + args = append(args, expression) + } + if err := p.match(tRparen); err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTFunctionExpression, + value: name, + children: args, + }, nil + case tFilter: + return p.parseFilter(node) + case tFlatten: + left := ASTNode{nodeType: ASTFlatten, children: []ASTNode{node}} + right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{left, right}, + }, err + case tEQ, tNE, tGT, tGTE, tLT, tLTE: + right, err := p.parseExpression(bindingPowers[tokenType]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTComparator, + value: tokenType, + children: []ASTNode{node, right}, + }, nil + case tLbracket: + tokenType := p.current() + var right ASTNode + var err error + if tokenType == tNumber || tokenType == tColon { + right, err = p.parseIndexExpression() + if err != nil { + return ASTNode{}, err + } + return p.projectIfSlice(node, right) + } + // Otherwise this is a projection. + if err := p.match(tStar); err != nil { + return ASTNode{}, err + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + right, err = p.parseProjectionRHS(bindingPowers[tStar]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{node, right}, + }, nil + } + return ASTNode{}, p.syntaxError("Unexpected token: " + tokenType.String()) +} + +func (p *Parser) nud(token token) (ASTNode, error) { + switch token.tokenType { + case tJSONLiteral: + var parsed interface{} + err := json.Unmarshal([]byte(token.value), &parsed) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTLiteral, value: parsed}, nil + case tStringLiteral: + return ASTNode{nodeType: ASTLiteral, value: token.value}, nil + case tUnquotedIdentifier: + return ASTNode{ + nodeType: ASTField, + value: token.value, + }, nil + case tQuotedIdentifier: + node := ASTNode{nodeType: ASTField, value: token.value} + if p.current() == tLparen { + return ASTNode{}, p.syntaxErrorToken("Can't have quoted identifier as function name.", token) + } + return node, nil + case tStar: + left := ASTNode{nodeType: ASTIdentity} + var right ASTNode + var err error + if p.current() == tRbracket { + right = ASTNode{nodeType: ASTIdentity} + } else { + right, err = p.parseProjectionRHS(bindingPowers[tStar]) + } + return ASTNode{nodeType: ASTValueProjection, children: []ASTNode{left, right}}, err + case tFilter: + return p.parseFilter(ASTNode{nodeType: ASTIdentity}) + case tLbrace: + return p.parseMultiSelectHash() + case tFlatten: + left := ASTNode{ + nodeType: ASTFlatten, + children: []ASTNode{{nodeType: ASTIdentity}}, + } + right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTProjection, children: []ASTNode{left, right}}, nil + case tLbracket: + tokenType := p.current() + //var right ASTNode + if tokenType == tNumber || tokenType == tColon { + right, err := p.parseIndexExpression() + if err != nil { + return ASTNode{}, nil + } + return p.projectIfSlice(ASTNode{nodeType: ASTIdentity}, right) + } else if tokenType == tStar && p.lookahead(1) == tRbracket { + p.advance() + p.advance() + right, err := p.parseProjectionRHS(bindingPowers[tStar]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{{nodeType: ASTIdentity}, right}, + }, nil + } else { + return p.parseMultiSelectList() + } + case tCurrent: + return ASTNode{nodeType: ASTCurrentNode}, nil + case tExpref: + expression, err := p.parseExpression(bindingPowers[tExpref]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTExpRef, children: []ASTNode{expression}}, nil + case tNot: + expression, err := p.parseExpression(bindingPowers[tNot]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTNotExpression, children: []ASTNode{expression}}, nil + case tLparen: + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if err := p.match(tRparen); err != nil { + return ASTNode{}, err + } + return expression, nil + case tEOF: + return ASTNode{}, p.syntaxErrorToken("Incomplete expression", token) + } + + return ASTNode{}, p.syntaxErrorToken("Invalid token: "+token.tokenType.String(), token) +} + +func (p *Parser) parseMultiSelectList() (ASTNode, error) { + var expressions []ASTNode + for { + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + expressions = append(expressions, expression) + if p.current() == tRbracket { + break + } + err = p.match(tComma) + if err != nil { + return ASTNode{}, err + } + } + err := p.match(tRbracket) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTMultiSelectList, + children: expressions, + }, nil +} + +func (p *Parser) parseMultiSelectHash() (ASTNode, error) { + var children []ASTNode + for { + keyToken := p.lookaheadToken(0) + if err := p.match(tUnquotedIdentifier); err != nil { + if err := p.match(tQuotedIdentifier); err != nil { + return ASTNode{}, p.syntaxError("Expected tQuotedIdentifier or tUnquotedIdentifier") + } + } + keyName := keyToken.value + err := p.match(tColon) + if err != nil { + return ASTNode{}, err + } + value, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + node := ASTNode{ + nodeType: ASTKeyValPair, + value: keyName, + children: []ASTNode{value}, + } + children = append(children, node) + if p.current() == tComma { + err := p.match(tComma) + if err != nil { + return ASTNode{}, nil + } + } else if p.current() == tRbrace { + err := p.match(tRbrace) + if err != nil { + return ASTNode{}, nil + } + break + } + } + return ASTNode{ + nodeType: ASTMultiSelectHash, + children: children, + }, nil +} + +func (p *Parser) projectIfSlice(left ASTNode, right ASTNode) (ASTNode, error) { + indexExpr := ASTNode{ + nodeType: ASTIndexExpression, + children: []ASTNode{left, right}, + } + if right.nodeType == ASTSlice { + right, err := p.parseProjectionRHS(bindingPowers[tStar]) + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{indexExpr, right}, + }, err + } + return indexExpr, nil +} +func (p *Parser) parseFilter(node ASTNode) (ASTNode, error) { + var right, condition ASTNode + var err error + condition, err = p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + if p.current() == tFlatten { + right = ASTNode{nodeType: ASTIdentity} + } else { + right, err = p.parseProjectionRHS(bindingPowers[tFilter]) + if err != nil { + return ASTNode{}, err + } + } + + return ASTNode{ + nodeType: ASTFilterProjection, + children: []ASTNode{node, right, condition}, + }, nil +} + +func (p *Parser) parseDotRHS(bindingPower int) (ASTNode, error) { + lookahead := p.current() + if tokensOneOf([]tokType{tQuotedIdentifier, tUnquotedIdentifier, tStar}, lookahead) { + return p.parseExpression(bindingPower) + } else if lookahead == tLbracket { + if err := p.match(tLbracket); err != nil { + return ASTNode{}, err + } + return p.parseMultiSelectList() + } else if lookahead == tLbrace { + if err := p.match(tLbrace); err != nil { + return ASTNode{}, err + } + return p.parseMultiSelectHash() + } + return ASTNode{}, p.syntaxError("Expected identifier, lbracket, or lbrace") +} + +func (p *Parser) parseProjectionRHS(bindingPower int) (ASTNode, error) { + current := p.current() + if bindingPowers[current] < 10 { + return ASTNode{nodeType: ASTIdentity}, nil + } else if current == tLbracket { + return p.parseExpression(bindingPower) + } else if current == tFilter { + return p.parseExpression(bindingPower) + } else if current == tDot { + err := p.match(tDot) + if err != nil { + return ASTNode{}, err + } + return p.parseDotRHS(bindingPower) + } else { + return ASTNode{}, p.syntaxError("Error") + } +} + +func (p *Parser) lookahead(number int) tokType { + return p.lookaheadToken(number).tokenType +} + +func (p *Parser) current() tokType { + return p.lookahead(0) +} + +func (p *Parser) lookaheadToken(number int) token { + return p.tokens[p.index+number] +} + +func (p *Parser) advance() { + p.index++ +} + +func tokensOneOf(elements []tokType, token tokType) bool { + for _, elem := range elements { + if elem == token { + return true + } + } + return false +} + +func (p *Parser) syntaxError(msg string) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: p.expression, + Offset: p.lookaheadToken(0).position, + } +} + +// Create a SyntaxError based on the provided token. +// This differs from syntaxError() which creates a SyntaxError +// based on the current lookahead token. +func (p *Parser) syntaxErrorToken(msg string, t token) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: p.expression, + Offset: t.position, + } +} diff --git a/vendor/github.com/jmespath/go-jmespath/toktype_string.go b/vendor/github.com/jmespath/go-jmespath/toktype_string.go new file mode 100644 index 00000000..dae79cbd --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/toktype_string.go @@ -0,0 +1,16 @@ +// generated by stringer -type=tokType; DO NOT EDIT + +package jmespath + +import "fmt" + +const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF" + +var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214} + +func (i tokType) String() string { + if i < 0 || i >= tokType(len(_tokType_index)-1) { + return fmt.Sprintf("tokType(%d)", i) + } + return _tokType_name[_tokType_index[i]:_tokType_index[i+1]] +} diff --git a/vendor/github.com/jmespath/go-jmespath/util.go b/vendor/github.com/jmespath/go-jmespath/util.go new file mode 100644 index 00000000..ddc1b7d7 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/util.go @@ -0,0 +1,185 @@ +package jmespath + +import ( + "errors" + "reflect" +) + +// IsFalse determines if an object is false based on the JMESPath spec. +// JMESPath defines false values to be any of: +// - An empty string array, or hash. +// - The boolean value false. +// - nil +func isFalse(value interface{}) bool { + switch v := value.(type) { + case bool: + return !v + case []interface{}: + return len(v) == 0 + case map[string]interface{}: + return len(v) == 0 + case string: + return len(v) == 0 + case nil: + return true + } + // Try the reflection cases before returning false. + rv := reflect.ValueOf(value) + switch rv.Kind() { + case reflect.Struct: + // A struct type will never be false, even if + // all of its values are the zero type. + return false + case reflect.Slice, reflect.Map: + return rv.Len() == 0 + case reflect.Ptr: + if rv.IsNil() { + return true + } + // If it's a pointer type, we'll try to deref the pointer + // and evaluate the pointer value for isFalse. + element := rv.Elem() + return isFalse(element.Interface()) + } + return false +} + +// ObjsEqual is a generic object equality check. +// It will take two arbitrary objects and recursively determine +// if they are equal. +func objsEqual(left interface{}, right interface{}) bool { + return reflect.DeepEqual(left, right) +} + +// SliceParam refers to a single part of a slice. +// A slice consists of a start, a stop, and a step, similar to +// python slices. +type sliceParam struct { + N int + Specified bool +} + +// Slice supports [start:stop:step] style slicing that's supported in JMESPath. +func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) { + computed, err := computeSliceParams(len(slice), parts) + if err != nil { + return nil, err + } + start, stop, step := computed[0], computed[1], computed[2] + result := []interface{}{} + if step > 0 { + for i := start; i < stop; i += step { + result = append(result, slice[i]) + } + } else { + for i := start; i > stop; i += step { + result = append(result, slice[i]) + } + } + return result, nil +} + +func computeSliceParams(length int, parts []sliceParam) ([]int, error) { + var start, stop, step int + if !parts[2].Specified { + step = 1 + } else if parts[2].N == 0 { + return nil, errors.New("Invalid slice, step cannot be 0") + } else { + step = parts[2].N + } + var stepValueNegative bool + if step < 0 { + stepValueNegative = true + } else { + stepValueNegative = false + } + + if !parts[0].Specified { + if stepValueNegative { + start = length - 1 + } else { + start = 0 + } + } else { + start = capSlice(length, parts[0].N, step) + } + + if !parts[1].Specified { + if stepValueNegative { + stop = -1 + } else { + stop = length + } + } else { + stop = capSlice(length, parts[1].N, step) + } + return []int{start, stop, step}, nil +} + +func capSlice(length int, actual int, step int) int { + if actual < 0 { + actual += length + if actual < 0 { + if step < 0 { + actual = -1 + } else { + actual = 0 + } + } + } else if actual >= length { + if step < 0 { + actual = length - 1 + } else { + actual = length + } + } + return actual +} + +// ToArrayNum converts an empty interface type to a slice of float64. +// If any element in the array cannot be converted, then nil is returned +// along with a second value of false. +func toArrayNum(data interface{}) ([]float64, bool) { + // Is there a better way to do this with reflect? + if d, ok := data.([]interface{}); ok { + result := make([]float64, len(d)) + for i, el := range d { + item, ok := el.(float64) + if !ok { + return nil, false + } + result[i] = item + } + return result, true + } + return nil, false +} + +// ToArrayStr converts an empty interface type to a slice of strings. +// If any element in the array cannot be converted, then nil is returned +// along with a second value of false. If the input data could be entirely +// converted, then the converted data, along with a second value of true, +// will be returned. +func toArrayStr(data interface{}) ([]string, bool) { + // Is there a better way to do this with reflect? + if d, ok := data.([]interface{}); ok { + result := make([]string, len(d)) + for i, el := range d { + item, ok := el.(string) + if !ok { + return nil, false + } + result[i] = item + } + return result, true + } + return nil, false +} + +func isSliceType(v interface{}) bool { + if v == nil { + return false + } + return reflect.TypeOf(v).Kind() == reflect.Slice +} diff --git a/vendor/github.com/json-iterator/go/.codecov.yml b/vendor/github.com/json-iterator/go/.codecov.yml new file mode 100644 index 00000000..955dc0be --- /dev/null +++ b/vendor/github.com/json-iterator/go/.codecov.yml @@ -0,0 +1,3 @@ +ignore: + - "output_tests/.*" + diff --git a/vendor/github.com/json-iterator/go/.gitignore b/vendor/github.com/json-iterator/go/.gitignore new file mode 100644 index 00000000..15556530 --- /dev/null +++ b/vendor/github.com/json-iterator/go/.gitignore @@ -0,0 +1,4 @@ +/vendor +/bug_test.go +/coverage.txt +/.idea diff --git a/vendor/github.com/json-iterator/go/.travis.yml b/vendor/github.com/json-iterator/go/.travis.yml new file mode 100644 index 00000000..449e67cd --- /dev/null +++ b/vendor/github.com/json-iterator/go/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.8.x + - 1.x + +before_install: + - go get -t -v ./... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/json-iterator/go/Gopkg.lock b/vendor/github.com/json-iterator/go/Gopkg.lock new file mode 100644 index 00000000..c8a9fbb3 --- /dev/null +++ b/vendor/github.com/json-iterator/go/Gopkg.lock @@ -0,0 +1,21 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/modern-go/concurrent" + packages = ["."] + revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a" + version = "1.0.0" + +[[projects]] + name = "github.com/modern-go/reflect2" + packages = ["."] + revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" + version = "1.0.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "ea54a775e5a354cb015502d2e7aa4b74230fc77e894f34a838b268c25ec8eeb8" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/json-iterator/go/Gopkg.toml b/vendor/github.com/json-iterator/go/Gopkg.toml new file mode 100644 index 00000000..313a0f88 --- /dev/null +++ b/vendor/github.com/json-iterator/go/Gopkg.toml @@ -0,0 +1,26 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + +ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"] + +[[constraint]] + name = "github.com/modern-go/reflect2" + version = "1.0.1" diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/json-iterator/go/LICENSE new file mode 100644 index 00000000..2cf4f5ab --- /dev/null +++ b/vendor/github.com/json-iterator/go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md new file mode 100644 index 00000000..50d56ffb --- /dev/null +++ b/vendor/github.com/json-iterator/go/README.md @@ -0,0 +1,87 @@ +[![Sourcegraph](https://sourcegraph.com/github.com/json-iterator/go/-/badge.svg)](https://sourcegraph.com/github.com/json-iterator/go?badge) +[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/json-iterator/go) +[![Build Status](https://travis-ci.org/json-iterator/go.svg?branch=master)](https://travis-ci.org/json-iterator/go) +[![codecov](https://codecov.io/gh/json-iterator/go/branch/master/graph/badge.svg)](https://codecov.io/gh/json-iterator/go) +[![rcard](https://goreportcard.com/badge/github.com/json-iterator/go)](https://goreportcard.com/report/github.com/json-iterator/go) +[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE) +[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) + +A high-performance 100% compatible drop-in replacement of "encoding/json" + +You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go) + +# Benchmark + +![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png) + +Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go + +Raw Result (easyjson requires static code generation) + +| | ns/op | allocation bytes | allocation times | +| --- | --- | --- | --- | +| std decode | 35510 ns/op | 1960 B/op | 99 allocs/op | +| easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op | +| jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op | +| std encode | 2213 ns/op | 712 B/op | 5 allocs/op | +| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op | +| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op | + +Always benchmark with your own workload. +The result depends heavily on the data input. + +# Usage + +100% compatibility with standard lib + +Replace + +```go +import "encoding/json" +json.Marshal(&data) +``` + +with + +```go +import "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Marshal(&data) +``` + +Replace + +```go +import "encoding/json" +json.Unmarshal(input, &data) +``` + +with + +```go +import "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Unmarshal(input, &data) +``` + +[More documentation](http://jsoniter.com/migrate-from-go-std.html) + +# How to get + +``` +go get github.com/json-iterator/go +``` + +# Contribution Welcomed ! + +Contributors + +* [thockin](https://github.com/thockin) +* [mattn](https://github.com/mattn) +* [cch123](https://github.com/cch123) +* [Oleg Shaldybin](https://github.com/olegshaldybin) +* [Jason Toffaletti](https://github.com/toffaletti) + +Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) diff --git a/vendor/github.com/json-iterator/go/adapter.go b/vendor/github.com/json-iterator/go/adapter.go new file mode 100644 index 00000000..e674d0f3 --- /dev/null +++ b/vendor/github.com/json-iterator/go/adapter.go @@ -0,0 +1,150 @@ +package jsoniter + +import ( + "bytes" + "io" +) + +// RawMessage to make replace json with jsoniter +type RawMessage []byte + +// Unmarshal adapts to json/encoding Unmarshal API +// +// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. +// Refer to https://godoc.org/encoding/json#Unmarshal for more information +func Unmarshal(data []byte, v interface{}) error { + return ConfigDefault.Unmarshal(data, v) +} + +// UnmarshalFromString convenient method to read from string instead of []byte +func UnmarshalFromString(str string, v interface{}) error { + return ConfigDefault.UnmarshalFromString(str, v) +} + +// Get quick method to get value from deeply nested JSON structure +func Get(data []byte, path ...interface{}) Any { + return ConfigDefault.Get(data, path...) +} + +// Marshal adapts to json/encoding Marshal API +// +// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API +// Refer to https://godoc.org/encoding/json#Marshal for more information +func Marshal(v interface{}) ([]byte, error) { + return ConfigDefault.Marshal(v) +} + +// MarshalIndent same as json.MarshalIndent. Prefix is not supported. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + return ConfigDefault.MarshalIndent(v, prefix, indent) +} + +// MarshalToString convenient method to write as string instead of []byte +func MarshalToString(v interface{}) (string, error) { + return ConfigDefault.MarshalToString(v) +} + +// NewDecoder adapts to json/stream NewDecoder API. +// +// NewDecoder returns a new decoder that reads from r. +// +// Instead of a json/encoding Decoder, an Decoder is returned +// Refer to https://godoc.org/encoding/json#NewDecoder for more information +func NewDecoder(reader io.Reader) *Decoder { + return ConfigDefault.NewDecoder(reader) +} + +// Decoder reads and decodes JSON values from an input stream. +// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) +type Decoder struct { + iter *Iterator +} + +// Decode decode JSON into interface{} +func (adapter *Decoder) Decode(obj interface{}) error { + if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil { + if !adapter.iter.loadMore() { + return io.EOF + } + } + adapter.iter.ReadVal(obj) + err := adapter.iter.Error + if err == io.EOF { + return nil + } + return adapter.iter.Error +} + +// More is there more? +func (adapter *Decoder) More() bool { + iter := adapter.iter + if iter.Error != nil { + return false + } + c := iter.nextToken() + if c == 0 { + return false + } + iter.unreadByte() + return c != ']' && c != '}' +} + +// Buffered remaining buffer +func (adapter *Decoder) Buffered() io.Reader { + remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] + return bytes.NewReader(remaining) +} + +// UseNumber causes the Decoder to unmarshal a number into an interface{} as a +// Number instead of as a float64. +func (adapter *Decoder) UseNumber() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.UseNumber = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// DisallowUnknownFields causes the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (adapter *Decoder) DisallowUnknownFields() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.DisallowUnknownFields = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// NewEncoder same as json.NewEncoder +func NewEncoder(writer io.Writer) *Encoder { + return ConfigDefault.NewEncoder(writer) +} + +// Encoder same as json.Encoder +type Encoder struct { + stream *Stream +} + +// Encode encode interface{} as JSON to io.Writer +func (adapter *Encoder) Encode(val interface{}) error { + adapter.stream.WriteVal(val) + adapter.stream.WriteRaw("\n") + adapter.stream.Flush() + return adapter.stream.Error +} + +// SetIndent set the indention. Prefix is not supported +func (adapter *Encoder) SetIndent(prefix, indent string) { + config := adapter.stream.cfg.configBeforeFrozen + config.IndentionStep = len(indent) + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// SetEscapeHTML escape html by default, set to false to disable +func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { + config := adapter.stream.cfg.configBeforeFrozen + config.EscapeHTML = escapeHTML + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// Valid reports whether data is a valid JSON encoding. +func Valid(data []byte) bool { + return ConfigDefault.Valid(data) +} diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/any.go new file mode 100644 index 00000000..f6b8aeab --- /dev/null +++ b/vendor/github.com/json-iterator/go/any.go @@ -0,0 +1,325 @@ +package jsoniter + +import ( + "errors" + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "strconv" + "unsafe" +) + +// Any generic object representation. +// The lazy json implementation holds []byte and parse lazily. +type Any interface { + LastError() error + ValueType() ValueType + MustBeValid() Any + ToBool() bool + ToInt() int + ToInt32() int32 + ToInt64() int64 + ToUint() uint + ToUint32() uint32 + ToUint64() uint64 + ToFloat32() float32 + ToFloat64() float64 + ToString() string + ToVal(val interface{}) + Get(path ...interface{}) Any + Size() int + Keys() []string + GetInterface() interface{} + WriteTo(stream *Stream) +} + +type baseAny struct{} + +func (any *baseAny) Get(path ...interface{}) Any { + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *baseAny) Size() int { + return 0 +} + +func (any *baseAny) Keys() []string { + return []string{} +} + +func (any *baseAny) ToVal(obj interface{}) { + panic("not implemented") +} + +// WrapInt32 turn int32 into Any interface +func WrapInt32(val int32) Any { + return &int32Any{baseAny{}, val} +} + +// WrapInt64 turn int64 into Any interface +func WrapInt64(val int64) Any { + return &int64Any{baseAny{}, val} +} + +// WrapUint32 turn uint32 into Any interface +func WrapUint32(val uint32) Any { + return &uint32Any{baseAny{}, val} +} + +// WrapUint64 turn uint64 into Any interface +func WrapUint64(val uint64) Any { + return &uint64Any{baseAny{}, val} +} + +// WrapFloat64 turn float64 into Any interface +func WrapFloat64(val float64) Any { + return &floatAny{baseAny{}, val} +} + +// WrapString turn string into Any interface +func WrapString(val string) Any { + return &stringAny{baseAny{}, val} +} + +// Wrap turn a go object into Any interface +func Wrap(val interface{}) Any { + if val == nil { + return &nilAny{} + } + asAny, isAny := val.(Any) + if isAny { + return asAny + } + typ := reflect2.TypeOf(val) + switch typ.Kind() { + case reflect.Slice: + return wrapArray(val) + case reflect.Struct: + return wrapStruct(val) + case reflect.Map: + return wrapMap(val) + case reflect.String: + return WrapString(val.(string)) + case reflect.Int: + if strconv.IntSize == 32 { + return WrapInt32(int32(val.(int))) + } + return WrapInt64(int64(val.(int))) + case reflect.Int8: + return WrapInt32(int32(val.(int8))) + case reflect.Int16: + return WrapInt32(int32(val.(int16))) + case reflect.Int32: + return WrapInt32(val.(int32)) + case reflect.Int64: + return WrapInt64(val.(int64)) + case reflect.Uint: + if strconv.IntSize == 32 { + return WrapUint32(uint32(val.(uint))) + } + return WrapUint64(uint64(val.(uint))) + case reflect.Uintptr: + if ptrSize == 32 { + return WrapUint32(uint32(val.(uintptr))) + } + return WrapUint64(uint64(val.(uintptr))) + case reflect.Uint8: + return WrapUint32(uint32(val.(uint8))) + case reflect.Uint16: + return WrapUint32(uint32(val.(uint16))) + case reflect.Uint32: + return WrapUint32(uint32(val.(uint32))) + case reflect.Uint64: + return WrapUint64(val.(uint64)) + case reflect.Float32: + return WrapFloat64(float64(val.(float32))) + case reflect.Float64: + return WrapFloat64(val.(float64)) + case reflect.Bool: + if val.(bool) == true { + return &trueAny{} + } + return &falseAny{} + } + return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} +} + +// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. +func (iter *Iterator) ReadAny() Any { + return iter.readAny() +} + +func (iter *Iterator) readAny() Any { + c := iter.nextToken() + switch c { + case '"': + iter.unreadByte() + return &stringAny{baseAny{}, iter.ReadString()} + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + return &nilAny{} + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + return &trueAny{} + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + return &falseAny{} + case '{': + return iter.readObjectAny() + case '[': + return iter.readArrayAny() + case '-': + return iter.readNumberAny(false) + case 0: + return &invalidAny{baseAny{}, errors.New("input is empty")} + default: + return iter.readNumberAny(true) + } +} + +func (iter *Iterator) readNumberAny(positive bool) Any { + iter.startCapture(iter.head - 1) + iter.skipNumber() + lazyBuf := iter.stopCapture() + return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readObjectAny() Any { + iter.startCapture(iter.head - 1) + iter.skipObject() + lazyBuf := iter.stopCapture() + return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readArrayAny() Any { + iter.startCapture(iter.head - 1) + iter.skipArray() + lazyBuf := iter.stopCapture() + return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func locateObjectField(iter *Iterator, target string) []byte { + var found []byte + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + if field == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + return true + }) + return found +} + +func locateArrayElement(iter *Iterator, target int) []byte { + var found []byte + n := 0 + iter.ReadArrayCB(func(iter *Iterator) bool { + if n == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + n++ + return true + }) + return found +} + +func locatePath(iter *Iterator, path []interface{}) Any { + for i, pathKeyObj := range path { + switch pathKey := pathKeyObj.(type) { + case string: + valueBytes := locateObjectField(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int: + valueBytes := locateArrayElement(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int32: + if '*' == pathKey { + return iter.readAny().Get(path[i:]...) + } + return newInvalidAny(path[i:]) + default: + return newInvalidAny(path[i:]) + } + } + if iter.Error != nil && iter.Error != io.EOF { + return &invalidAny{baseAny{}, iter.Error} + } + return iter.readAny() +} + +var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem() + +func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +type anyCodec struct { + valType reflect2.Type +} + +func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + panic("not implemented") +} + +func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + any.WriteTo(stream) +} + +func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + return any.Size() == 0 +} + +type directAnyCodec struct { +} + +func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *(*Any)(ptr) = iter.readAny() +} + +func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + any := *(*Any)(ptr) + if any == nil { + stream.WriteNil() + return + } + any.WriteTo(stream) +} + +func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { + any := *(*Any)(ptr) + return any.Size() == 0 +} diff --git a/vendor/github.com/json-iterator/go/any_array.go b/vendor/github.com/json-iterator/go/any_array.go new file mode 100644 index 00000000..0449e9aa --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_array.go @@ -0,0 +1,278 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type arrayLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *arrayLazyAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayLazyAny) MustBeValid() Any { + return any +} + +func (any *arrayLazyAny) LastError() error { + return any.err +} + +func (any *arrayLazyAny) ToBool() bool { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.ReadArray() +} + +func (any *arrayLazyAny) ToInt() int { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt32() int32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt64() int64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint() uint { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint32() uint32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint64() uint64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat32() float32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat64() float64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *arrayLazyAny) ToVal(val interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(val) +} + +func (any *arrayLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateArrayElement(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + arr := make([]Any, 0) + iter.ReadArrayCB(func(iter *Iterator) bool { + found := iter.readAny().Get(path[1:]...) + if found.ValueType() != InvalidValue { + arr = append(arr, found) + } + return true + }) + return wrapArray(arr) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadArrayCB(func(iter *Iterator) bool { + size++ + iter.Skip() + return true + }) + return size +} + +func (any *arrayLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *arrayLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type arrayAny struct { + baseAny + val reflect.Value +} + +func wrapArray(val interface{}) *arrayAny { + return &arrayAny{baseAny{}, reflect.ValueOf(val)} +} + +func (any *arrayAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayAny) MustBeValid() Any { + return any +} + +func (any *arrayAny) LastError() error { + return nil +} + +func (any *arrayAny) ToBool() bool { + return any.val.Len() != 0 +} + +func (any *arrayAny) ToInt() int { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt32() int32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt64() int64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint() uint { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint32() uint32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint64() uint64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat32() float32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat64() float64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToString() string { + str, _ := MarshalToString(any.val.Interface()) + return str +} + +func (any *arrayAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + if firstPath < 0 || firstPath >= any.val.Len() { + return newInvalidAny(path) + } + return Wrap(any.val.Index(firstPath).Interface()) + case int32: + if '*' == firstPath { + mappedAll := make([]Any, 0) + for i := 0; i < any.val.Len(); i++ { + mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll = append(mappedAll, mapped) + } + } + return wrapArray(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayAny) Size() int { + return any.val.Len() +} + +func (any *arrayAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *arrayAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go new file mode 100644 index 00000000..9452324a --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_bool.go @@ -0,0 +1,137 @@ +package jsoniter + +type trueAny struct { + baseAny +} + +func (any *trueAny) LastError() error { + return nil +} + +func (any *trueAny) ToBool() bool { + return true +} + +func (any *trueAny) ToInt() int { + return 1 +} + +func (any *trueAny) ToInt32() int32 { + return 1 +} + +func (any *trueAny) ToInt64() int64 { + return 1 +} + +func (any *trueAny) ToUint() uint { + return 1 +} + +func (any *trueAny) ToUint32() uint32 { + return 1 +} + +func (any *trueAny) ToUint64() uint64 { + return 1 +} + +func (any *trueAny) ToFloat32() float32 { + return 1 +} + +func (any *trueAny) ToFloat64() float64 { + return 1 +} + +func (any *trueAny) ToString() string { + return "true" +} + +func (any *trueAny) WriteTo(stream *Stream) { + stream.WriteTrue() +} + +func (any *trueAny) Parse() *Iterator { + return nil +} + +func (any *trueAny) GetInterface() interface{} { + return true +} + +func (any *trueAny) ValueType() ValueType { + return BoolValue +} + +func (any *trueAny) MustBeValid() Any { + return any +} + +type falseAny struct { + baseAny +} + +func (any *falseAny) LastError() error { + return nil +} + +func (any *falseAny) ToBool() bool { + return false +} + +func (any *falseAny) ToInt() int { + return 0 +} + +func (any *falseAny) ToInt32() int32 { + return 0 +} + +func (any *falseAny) ToInt64() int64 { + return 0 +} + +func (any *falseAny) ToUint() uint { + return 0 +} + +func (any *falseAny) ToUint32() uint32 { + return 0 +} + +func (any *falseAny) ToUint64() uint64 { + return 0 +} + +func (any *falseAny) ToFloat32() float32 { + return 0 +} + +func (any *falseAny) ToFloat64() float64 { + return 0 +} + +func (any *falseAny) ToString() string { + return "false" +} + +func (any *falseAny) WriteTo(stream *Stream) { + stream.WriteFalse() +} + +func (any *falseAny) Parse() *Iterator { + return nil +} + +func (any *falseAny) GetInterface() interface{} { + return false +} + +func (any *falseAny) ValueType() ValueType { + return BoolValue +} + +func (any *falseAny) MustBeValid() Any { + return any +} diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/any_float.go new file mode 100644 index 00000000..35fdb094 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_float.go @@ -0,0 +1,83 @@ +package jsoniter + +import ( + "strconv" +) + +type floatAny struct { + baseAny + val float64 +} + +func (any *floatAny) Parse() *Iterator { + return nil +} + +func (any *floatAny) ValueType() ValueType { + return NumberValue +} + +func (any *floatAny) MustBeValid() Any { + return any +} + +func (any *floatAny) LastError() error { + return nil +} + +func (any *floatAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *floatAny) ToInt() int { + return int(any.val) +} + +func (any *floatAny) ToInt32() int32 { + return int32(any.val) +} + +func (any *floatAny) ToInt64() int64 { + return int64(any.val) +} + +func (any *floatAny) ToUint() uint { + if any.val > 0 { + return uint(any.val) + } + return 0 +} + +func (any *floatAny) ToUint32() uint32 { + if any.val > 0 { + return uint32(any.val) + } + return 0 +} + +func (any *floatAny) ToUint64() uint64 { + if any.val > 0 { + return uint64(any.val) + } + return 0 +} + +func (any *floatAny) ToFloat32() float32 { + return float32(any.val) +} + +func (any *floatAny) ToFloat64() float64 { + return any.val +} + +func (any *floatAny) ToString() string { + return strconv.FormatFloat(any.val, 'E', -1, 64) +} + +func (any *floatAny) WriteTo(stream *Stream) { + stream.WriteFloat64(any.val) +} + +func (any *floatAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go new file mode 100644 index 00000000..1b56f399 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int32Any struct { + baseAny + val int32 +} + +func (any *int32Any) LastError() error { + return nil +} + +func (any *int32Any) ValueType() ValueType { + return NumberValue +} + +func (any *int32Any) MustBeValid() Any { + return any +} + +func (any *int32Any) ToBool() bool { + return any.val != 0 +} + +func (any *int32Any) ToInt() int { + return int(any.val) +} + +func (any *int32Any) ToInt32() int32 { + return any.val +} + +func (any *int32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *int32Any) ToUint() uint { + return uint(any.val) +} + +func (any *int32Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *int32Any) WriteTo(stream *Stream) { + stream.WriteInt32(any.val) +} + +func (any *int32Any) Parse() *Iterator { + return nil +} + +func (any *int32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go new file mode 100644 index 00000000..c440d72b --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int64Any struct { + baseAny + val int64 +} + +func (any *int64Any) LastError() error { + return nil +} + +func (any *int64Any) ValueType() ValueType { + return NumberValue +} + +func (any *int64Any) MustBeValid() Any { + return any +} + +func (any *int64Any) ToBool() bool { + return any.val != 0 +} + +func (any *int64Any) ToInt() int { + return int(any.val) +} + +func (any *int64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *int64Any) ToInt64() int64 { + return any.val +} + +func (any *int64Any) ToUint() uint { + return uint(any.val) +} + +func (any *int64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int64Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int64Any) ToString() string { + return strconv.FormatInt(any.val, 10) +} + +func (any *int64Any) WriteTo(stream *Stream) { + stream.WriteInt64(any.val) +} + +func (any *int64Any) Parse() *Iterator { + return nil +} + +func (any *int64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go new file mode 100644 index 00000000..1d859eac --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_invalid.go @@ -0,0 +1,82 @@ +package jsoniter + +import "fmt" + +type invalidAny struct { + baseAny + err error +} + +func newInvalidAny(path []interface{}) *invalidAny { + return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} +} + +func (any *invalidAny) LastError() error { + return any.err +} + +func (any *invalidAny) ValueType() ValueType { + return InvalidValue +} + +func (any *invalidAny) MustBeValid() Any { + panic(any.err) +} + +func (any *invalidAny) ToBool() bool { + return false +} + +func (any *invalidAny) ToInt() int { + return 0 +} + +func (any *invalidAny) ToInt32() int32 { + return 0 +} + +func (any *invalidAny) ToInt64() int64 { + return 0 +} + +func (any *invalidAny) ToUint() uint { + return 0 +} + +func (any *invalidAny) ToUint32() uint32 { + return 0 +} + +func (any *invalidAny) ToUint64() uint64 { + return 0 +} + +func (any *invalidAny) ToFloat32() float32 { + return 0 +} + +func (any *invalidAny) ToFloat64() float64 { + return 0 +} + +func (any *invalidAny) ToString() string { + return "" +} + +func (any *invalidAny) WriteTo(stream *Stream) { +} + +func (any *invalidAny) Get(path ...interface{}) Any { + if any.err == nil { + return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} + } + return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} +} + +func (any *invalidAny) Parse() *Iterator { + return nil +} + +func (any *invalidAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go new file mode 100644 index 00000000..d04cb54c --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_nil.go @@ -0,0 +1,69 @@ +package jsoniter + +type nilAny struct { + baseAny +} + +func (any *nilAny) LastError() error { + return nil +} + +func (any *nilAny) ValueType() ValueType { + return NilValue +} + +func (any *nilAny) MustBeValid() Any { + return any +} + +func (any *nilAny) ToBool() bool { + return false +} + +func (any *nilAny) ToInt() int { + return 0 +} + +func (any *nilAny) ToInt32() int32 { + return 0 +} + +func (any *nilAny) ToInt64() int64 { + return 0 +} + +func (any *nilAny) ToUint() uint { + return 0 +} + +func (any *nilAny) ToUint32() uint32 { + return 0 +} + +func (any *nilAny) ToUint64() uint64 { + return 0 +} + +func (any *nilAny) ToFloat32() float32 { + return 0 +} + +func (any *nilAny) ToFloat64() float64 { + return 0 +} + +func (any *nilAny) ToString() string { + return "" +} + +func (any *nilAny) WriteTo(stream *Stream) { + stream.WriteNil() +} + +func (any *nilAny) Parse() *Iterator { + return nil +} + +func (any *nilAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/any_number.go new file mode 100644 index 00000000..9d1e901a --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_number.go @@ -0,0 +1,123 @@ +package jsoniter + +import ( + "io" + "unsafe" +) + +type numberLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *numberLazyAny) ValueType() ValueType { + return NumberValue +} + +func (any *numberLazyAny) MustBeValid() Any { + return any +} + +func (any *numberLazyAny) LastError() error { + return any.err +} + +func (any *numberLazyAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *numberLazyAny) ToInt() int { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt32() int32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt64() int64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint() uint { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint32() uint32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint64() uint64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat32() float32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat64() float64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *numberLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *numberLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/any_object.go new file mode 100644 index 00000000..c44ef5c9 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_object.go @@ -0,0 +1,374 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type objectLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *objectLazyAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectLazyAny) MustBeValid() Any { + return any +} + +func (any *objectLazyAny) LastError() error { + return any.err +} + +func (any *objectLazyAny) ToBool() bool { + return true +} + +func (any *objectLazyAny) ToInt() int { + return 0 +} + +func (any *objectLazyAny) ToInt32() int32 { + return 0 +} + +func (any *objectLazyAny) ToInt64() int64 { + return 0 +} + +func (any *objectLazyAny) ToUint() uint { + return 0 +} + +func (any *objectLazyAny) ToUint32() uint32 { + return 0 +} + +func (any *objectLazyAny) ToUint64() uint64 { + return 0 +} + +func (any *objectLazyAny) ToFloat32() float32 { + return 0 +} + +func (any *objectLazyAny) ToFloat64() float64 { + return 0 +} + +func (any *objectLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *objectLazyAny) ToVal(obj interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(obj) +} + +func (any *objectLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateObjectField(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + mapped := locatePath(iter, path[1:]) + if mapped.ValueType() != InvalidValue { + mappedAll[field] = mapped + } + return true + }) + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectLazyAny) Keys() []string { + keys := []string{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + iter.Skip() + keys = append(keys, field) + return true + }) + return keys +} + +func (any *objectLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + size++ + return true + }) + return size +} + +func (any *objectLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *objectLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type objectAny struct { + baseAny + err error + val reflect.Value +} + +func wrapStruct(val interface{}) *objectAny { + return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *objectAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectAny) MustBeValid() Any { + return any +} + +func (any *objectAny) Parse() *Iterator { + return nil +} + +func (any *objectAny) LastError() error { + return any.err +} + +func (any *objectAny) ToBool() bool { + return any.val.NumField() != 0 +} + +func (any *objectAny) ToInt() int { + return 0 +} + +func (any *objectAny) ToInt32() int32 { + return 0 +} + +func (any *objectAny) ToInt64() int64 { + return 0 +} + +func (any *objectAny) ToUint() uint { + return 0 +} + +func (any *objectAny) ToUint32() uint32 { + return 0 +} + +func (any *objectAny) ToUint64() uint64 { + return 0 +} + +func (any *objectAny) ToFloat32() float32 { + return 0 +} + +func (any *objectAny) ToFloat64() float64 { + return 0 +} + +func (any *objectAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *objectAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + field := any.val.FieldByName(firstPath) + if !field.IsValid() { + return newInvalidAny(path) + } + return Wrap(field.Interface()) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for i := 0; i < any.val.NumField(); i++ { + field := any.val.Field(i) + if field.CanInterface() { + mapped := Wrap(field.Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[any.val.Type().Field(i).Name] = mapped + } + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectAny) Keys() []string { + keys := make([]string, 0, any.val.NumField()) + for i := 0; i < any.val.NumField(); i++ { + keys = append(keys, any.val.Type().Field(i).Name) + } + return keys +} + +func (any *objectAny) Size() int { + return any.val.NumField() +} + +func (any *objectAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *objectAny) GetInterface() interface{} { + return any.val.Interface() +} + +type mapAny struct { + baseAny + err error + val reflect.Value +} + +func wrapMap(val interface{}) *mapAny { + return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *mapAny) ValueType() ValueType { + return ObjectValue +} + +func (any *mapAny) MustBeValid() Any { + return any +} + +func (any *mapAny) Parse() *Iterator { + return nil +} + +func (any *mapAny) LastError() error { + return any.err +} + +func (any *mapAny) ToBool() bool { + return true +} + +func (any *mapAny) ToInt() int { + return 0 +} + +func (any *mapAny) ToInt32() int32 { + return 0 +} + +func (any *mapAny) ToInt64() int64 { + return 0 +} + +func (any *mapAny) ToUint() uint { + return 0 +} + +func (any *mapAny) ToUint32() uint32 { + return 0 +} + +func (any *mapAny) ToUint64() uint64 { + return 0 +} + +func (any *mapAny) ToFloat32() float32 { + return 0 +} + +func (any *mapAny) ToFloat64() float64 { + return 0 +} + +func (any *mapAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *mapAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for _, key := range any.val.MapKeys() { + keyAsStr := key.String() + element := Wrap(any.val.MapIndex(key).Interface()) + mapped := element.Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[keyAsStr] = mapped + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + value := any.val.MapIndex(reflect.ValueOf(firstPath)) + if !value.IsValid() { + return newInvalidAny(path) + } + return Wrap(value.Interface()) + } +} + +func (any *mapAny) Keys() []string { + keys := make([]string, 0, any.val.Len()) + for _, key := range any.val.MapKeys() { + keys = append(keys, key.String()) + } + return keys +} + +func (any *mapAny) Size() int { + return any.val.Len() +} + +func (any *mapAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *mapAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/any_str.go new file mode 100644 index 00000000..a4b93c78 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_str.go @@ -0,0 +1,166 @@ +package jsoniter + +import ( + "fmt" + "strconv" +) + +type stringAny struct { + baseAny + val string +} + +func (any *stringAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *stringAny) Parse() *Iterator { + return nil +} + +func (any *stringAny) ValueType() ValueType { + return StringValue +} + +func (any *stringAny) MustBeValid() Any { + return any +} + +func (any *stringAny) LastError() error { + return nil +} + +func (any *stringAny) ToBool() bool { + str := any.ToString() + if str == "0" { + return false + } + for _, c := range str { + switch c { + case ' ', '\n', '\r', '\t': + default: + return true + } + } + return false +} + +func (any *stringAny) ToInt() int { + return int(any.ToInt64()) + +} + +func (any *stringAny) ToInt32() int32 { + return int32(any.ToInt64()) +} + +func (any *stringAny) ToInt64() int64 { + if any.val == "" { + return 0 + } + + flag := 1 + startPos := 0 + endPos := 0 + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + if any.val[0] == '-' { + flag = -1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) + return int64(flag) * parsed +} + +func (any *stringAny) ToUint() uint { + return uint(any.ToUint64()) +} + +func (any *stringAny) ToUint32() uint32 { + return uint32(any.ToUint64()) +} + +func (any *stringAny) ToUint64() uint64 { + if any.val == "" { + return 0 + } + + startPos := 0 + endPos := 0 + + if any.val[0] == '-' { + return 0 + } + if any.val[0] == '+' { + startPos = 1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) + return parsed +} + +func (any *stringAny) ToFloat32() float32 { + return float32(any.ToFloat64()) +} + +func (any *stringAny) ToFloat64() float64 { + if len(any.val) == 0 { + return 0 + } + + // first char invalid + if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { + return 0 + } + + // extract valid num expression from string + // eg 123true => 123, -12.12xxa => -12.12 + endPos := 1 + for i := 1; i < len(any.val); i++ { + if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { + endPos = i + 1 + continue + } + + // end position is the first char which is not digit + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + endPos = i + break + } + } + parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) + return parsed +} + +func (any *stringAny) ToString() string { + return any.val +} + +func (any *stringAny) WriteTo(stream *Stream) { + stream.WriteString(any.val) +} + +func (any *stringAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go new file mode 100644 index 00000000..656bbd33 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint32Any struct { + baseAny + val uint32 +} + +func (any *uint32Any) LastError() error { + return nil +} + +func (any *uint32Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint32Any) MustBeValid() Any { + return any +} + +func (any *uint32Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint32Any) ToInt() int { + return int(any.val) +} + +func (any *uint32Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint32Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint32Any) ToUint32() uint32 { + return any.val +} + +func (any *uint32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *uint32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *uint32Any) WriteTo(stream *Stream) { + stream.WriteUint32(any.val) +} + +func (any *uint32Any) Parse() *Iterator { + return nil +} + +func (any *uint32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go new file mode 100644 index 00000000..7df2fce3 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint64Any struct { + baseAny + val uint64 +} + +func (any *uint64Any) LastError() error { + return nil +} + +func (any *uint64Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint64Any) MustBeValid() Any { + return any +} + +func (any *uint64Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint64Any) ToInt() int { + return int(any.val) +} + +func (any *uint64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint64Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint64Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *uint64Any) ToUint64() uint64 { + return any.val +} + +func (any *uint64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint64Any) ToString() string { + return strconv.FormatUint(any.val, 10) +} + +func (any *uint64Any) WriteTo(stream *Stream) { + stream.WriteUint64(any.val) +} + +func (any *uint64Any) Parse() *Iterator { + return nil +} + +func (any *uint64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/build.sh b/vendor/github.com/json-iterator/go/build.sh new file mode 100755 index 00000000..b45ef688 --- /dev/null +++ b/vendor/github.com/json-iterator/go/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +set -x + +if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then + mkdir -p /tmp/build-golang/src/github.com/json-iterator + ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go +fi +export GOPATH=/tmp/build-golang +go get -u github.com/golang/dep/cmd/dep +cd /tmp/build-golang/src/github.com/json-iterator/go +exec $GOPATH/bin/dep ensure -update diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go new file mode 100644 index 00000000..8c58fcba --- /dev/null +++ b/vendor/github.com/json-iterator/go/config.go @@ -0,0 +1,375 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "reflect" + "sync" + "unsafe" + + "github.com/modern-go/concurrent" + "github.com/modern-go/reflect2" +) + +// Config customize how the API should behave. +// The API is created from Config by Froze. +type Config struct { + IndentionStep int + MarshalFloatWith6Digits bool + EscapeHTML bool + SortMapKeys bool + UseNumber bool + DisallowUnknownFields bool + TagKey string + OnlyTaggedField bool + ValidateJsonRawMessage bool + ObjectFieldMustBeSimpleString bool + CaseSensitive bool +} + +// API the public interface of this package. +// Primary Marshal and Unmarshal. +type API interface { + IteratorPool + StreamPool + MarshalToString(v interface{}) (string, error) + Marshal(v interface{}) ([]byte, error) + MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) + UnmarshalFromString(str string, v interface{}) error + Unmarshal(data []byte, v interface{}) error + Get(data []byte, path ...interface{}) Any + NewEncoder(writer io.Writer) *Encoder + NewDecoder(reader io.Reader) *Decoder + Valid(data []byte) bool + RegisterExtension(extension Extension) + DecoderOf(typ reflect2.Type) ValDecoder + EncoderOf(typ reflect2.Type) ValEncoder +} + +// ConfigDefault the default API +var ConfigDefault = Config{ + EscapeHTML: true, +}.Froze() + +// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior +var ConfigCompatibleWithStandardLibrary = Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, +}.Froze() + +// ConfigFastest marshals float with only 6 digits precision +var ConfigFastest = Config{ + EscapeHTML: false, + MarshalFloatWith6Digits: true, // will lose precession + ObjectFieldMustBeSimpleString: true, // do not unescape object field +}.Froze() + +type frozenConfig struct { + configBeforeFrozen Config + sortMapKeys bool + indentionStep int + objectFieldMustBeSimpleString bool + onlyTaggedField bool + disallowUnknownFields bool + decoderCache *concurrent.Map + encoderCache *concurrent.Map + encoderExtension Extension + decoderExtension Extension + extraExtensions []Extension + streamPool *sync.Pool + iteratorPool *sync.Pool + caseSensitive bool +} + +func (cfg *frozenConfig) initCache() { + cfg.decoderCache = concurrent.NewMap() + cfg.encoderCache = concurrent.NewMap() +} + +func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { + cfg.decoderCache.Store(cacheKey, decoder) +} + +func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { + cfg.encoderCache.Store(cacheKey, encoder) +} + +func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { + decoder, found := cfg.decoderCache.Load(cacheKey) + if found { + return decoder.(ValDecoder) + } + return nil +} + +func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { + encoder, found := cfg.encoderCache.Load(cacheKey) + if found { + return encoder.(ValEncoder) + } + return nil +} + +var cfgCache = concurrent.NewMap() + +func getFrozenConfigFromCache(cfg Config) *frozenConfig { + obj, found := cfgCache.Load(cfg) + if found { + return obj.(*frozenConfig) + } + return nil +} + +func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { + cfgCache.Store(cfg, frozenConfig) +} + +// Froze forge API from config +func (cfg Config) Froze() API { + api := &frozenConfig{ + sortMapKeys: cfg.SortMapKeys, + indentionStep: cfg.IndentionStep, + objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, + onlyTaggedField: cfg.OnlyTaggedField, + disallowUnknownFields: cfg.DisallowUnknownFields, + caseSensitive: cfg.CaseSensitive, + } + api.streamPool = &sync.Pool{ + New: func() interface{} { + return NewStream(api, nil, 512) + }, + } + api.iteratorPool = &sync.Pool{ + New: func() interface{} { + return NewIterator(api) + }, + } + api.initCache() + encoderExtension := EncoderExtension{} + decoderExtension := DecoderExtension{} + if cfg.MarshalFloatWith6Digits { + api.marshalFloatWith6Digits(encoderExtension) + } + if cfg.EscapeHTML { + api.escapeHTML(encoderExtension) + } + if cfg.UseNumber { + api.useNumber(decoderExtension) + } + if cfg.ValidateJsonRawMessage { + api.validateJsonRawMessage(encoderExtension) + } + api.encoderExtension = encoderExtension + api.decoderExtension = decoderExtension + api.configBeforeFrozen = cfg + return api +} + +func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig { + api := getFrozenConfigFromCache(cfg) + if api != nil { + return api + } + api = cfg.Froze().(*frozenConfig) + for _, extension := range extraExtensions { + api.RegisterExtension(extension) + } + addFrozenConfigToCache(cfg, api) + return api +} + +func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) { + encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { + rawMessage := *(*json.RawMessage)(ptr) + iter := cfg.BorrowIterator([]byte(rawMessage)) + iter.Read() + if iter.Error != nil { + stream.WriteRaw("null") + } else { + cfg.ReturnIterator(iter) + stream.WriteRaw(string(rawMessage)) + } + }, func(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 + }} + extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder + extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder +} + +func (cfg *frozenConfig) useNumber(extension DecoderExtension) { + extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { + exitingValue := *((*interface{})(ptr)) + if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr { + iter.ReadVal(exitingValue) + return + } + if iter.WhatIsNext() == NumberValue { + *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) + } else { + *((*interface{})(ptr)) = iter.Read() + } + }} +} +func (cfg *frozenConfig) getTagKey() string { + tagKey := cfg.configBeforeFrozen.TagKey + if tagKey == "" { + return "json" + } + return tagKey +} + +func (cfg *frozenConfig) RegisterExtension(extension Extension) { + cfg.extraExtensions = append(cfg.extraExtensions, extension) + copied := cfg.configBeforeFrozen + cfg.configBeforeFrozen = copied +} + +type lossyFloat32Encoder struct { +} + +func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32Lossy(*((*float32)(ptr))) +} + +func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type lossyFloat64Encoder struct { +} + +func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64Lossy(*((*float64)(ptr))) +} + +func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +// EnableLossyFloatMarshalling keeps 10**(-6) precision +// for float variables for better performance. +func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) { + // for better performance + extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{} + extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{} +} + +type htmlEscapedStringEncoder struct { +} + +func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteStringWithHTMLEscaped(str) +} + +func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) { + encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{} +} + +func (cfg *frozenConfig) cleanDecoders() { + typeDecoders = map[string]ValDecoder{} + fieldDecoders = map[string]ValDecoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) cleanEncoders() { + typeEncoders = map[string]ValEncoder{} + fieldEncoders = map[string]ValEncoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return "", stream.Error + } + return string(stream.Buffer()), nil +} + +func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return nil, stream.Error + } + result := stream.Buffer() + copied := make([]byte, len(result)) + copy(copied, result) + return copied, nil +} + +func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + if prefix != "" { + panic("prefix is not supported") + } + for _, r := range indent { + if r != ' ' { + panic("indent can only be space") + } + } + newCfg := cfg.configBeforeFrozen + newCfg.IndentionStep = len(indent) + return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v) +} + +func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { + data := []byte(str) + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + return locatePath(iter, path) +} + +func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder { + stream := NewStream(cfg, writer, 512) + return &Encoder{stream} +} + +func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { + iter := Parse(cfg, reader, 512) + return &Decoder{iter} +} + +func (cfg *frozenConfig) Valid(data []byte) bool { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.Skip() + return iter.Error == nil +} diff --git a/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md new file mode 100644 index 00000000..3095662b --- /dev/null +++ b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md @@ -0,0 +1,7 @@ +| json type \ dest type | bool | int | uint | float |string| +| --- | --- | --- | --- |--|--| +| number | positive => true
negative => true
zero => false| 23.2 => 23
-32.1 => -32| 12.1 => 12
-12.1 => 0|as normal|same as origin| +| string | empty string => false
string "0" => false
other strings => true | "123.32" => 123
"-123.4" => -123
"123.23xxxw" => 123
"abcde12" => 0
"-32.1" => -32| 13.2 => 13
-1.1 => 0 |12.1 => 12.1
-12.3 => -12.3
12.4xxa => 12.4
+1.1e2 =>110 |same as origin| +| bool | true => true
false => false| true => 1
false => 0 | true => 1
false => 0 |true => 1
false => 0|true => "true"
false => "false"| +| object | true | 0 | 0 |0|originnal json| +| array | empty array => false
nonempty array => true| [] => 0
[1,2] => 1 | [] => 0
[1,2] => 1 |[] => 0
[1,2] => 1|original json| \ No newline at end of file diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/iter.go new file mode 100644 index 00000000..95ae54fb --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter.go @@ -0,0 +1,322 @@ +package jsoniter + +import ( + "encoding/json" + "fmt" + "io" +) + +// ValueType the type for JSON element +type ValueType int + +const ( + // InvalidValue invalid JSON element + InvalidValue ValueType = iota + // StringValue JSON element "string" + StringValue + // NumberValue JSON element 100 or 0.10 + NumberValue + // NilValue JSON element null + NilValue + // BoolValue JSON element true or false + BoolValue + // ArrayValue JSON element [] + ArrayValue + // ObjectValue JSON element {} + ObjectValue +) + +var hexDigits []byte +var valueTypes []ValueType + +func init() { + hexDigits = make([]byte, 256) + for i := 0; i < len(hexDigits); i++ { + hexDigits[i] = 255 + } + for i := '0'; i <= '9'; i++ { + hexDigits[i] = byte(i - '0') + } + for i := 'a'; i <= 'f'; i++ { + hexDigits[i] = byte((i - 'a') + 10) + } + for i := 'A'; i <= 'F'; i++ { + hexDigits[i] = byte((i - 'A') + 10) + } + valueTypes = make([]ValueType, 256) + for i := 0; i < len(valueTypes); i++ { + valueTypes[i] = InvalidValue + } + valueTypes['"'] = StringValue + valueTypes['-'] = NumberValue + valueTypes['0'] = NumberValue + valueTypes['1'] = NumberValue + valueTypes['2'] = NumberValue + valueTypes['3'] = NumberValue + valueTypes['4'] = NumberValue + valueTypes['5'] = NumberValue + valueTypes['6'] = NumberValue + valueTypes['7'] = NumberValue + valueTypes['8'] = NumberValue + valueTypes['9'] = NumberValue + valueTypes['t'] = BoolValue + valueTypes['f'] = BoolValue + valueTypes['n'] = NilValue + valueTypes['['] = ArrayValue + valueTypes['{'] = ObjectValue +} + +// Iterator is a io.Reader like object, with JSON specific read functions. +// Error is not returned as return value, but stored as Error member on this iterator instance. +type Iterator struct { + cfg *frozenConfig + reader io.Reader + buf []byte + head int + tail int + captureStartedAt int + captured []byte + Error error + Attachment interface{} // open for customized decoder +} + +// NewIterator creates an empty Iterator instance +func NewIterator(cfg API) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: nil, + head: 0, + tail: 0, + } +} + +// Parse creates an Iterator instance from io.Reader +func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: reader, + buf: make([]byte, bufSize), + head: 0, + tail: 0, + } +} + +// ParseBytes creates an Iterator instance from byte array +func ParseBytes(cfg API, input []byte) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: input, + head: 0, + tail: len(input), + } +} + +// ParseString creates an Iterator instance from string +func ParseString(cfg API, input string) *Iterator { + return ParseBytes(cfg, []byte(input)) +} + +// Pool returns a pool can provide more iterator with same configuration +func (iter *Iterator) Pool() IteratorPool { + return iter.cfg +} + +// Reset reuse iterator instance by specifying another reader +func (iter *Iterator) Reset(reader io.Reader) *Iterator { + iter.reader = reader + iter.head = 0 + iter.tail = 0 + return iter +} + +// ResetBytes reuse iterator instance by specifying another byte array as input +func (iter *Iterator) ResetBytes(input []byte) *Iterator { + iter.reader = nil + iter.buf = input + iter.head = 0 + iter.tail = len(input) + return iter +} + +// WhatIsNext gets ValueType of relatively next json element +func (iter *Iterator) WhatIsNext() ValueType { + valueType := valueTypes[iter.nextToken()] + iter.unreadByte() + return valueType +} + +func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + return false + } + return true +} + +func (iter *Iterator) isObjectEnd() bool { + c := iter.nextToken() + if c == ',' { + return false + } + if c == '}' { + return true + } + iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) + return true +} + +func (iter *Iterator) nextToken() byte { + // a variation of skip whitespaces, returning the next non-whitespace token + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + 1 + return c + } + if !iter.loadMore() { + return 0 + } + } +} + +// ReportError record a error in iterator instance with current position. +func (iter *Iterator) ReportError(operation string, msg string) { + if iter.Error != nil { + if iter.Error != io.EOF { + return + } + } + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + peekEnd := iter.head + 10 + if peekEnd > iter.tail { + peekEnd = iter.tail + } + parsing := string(iter.buf[peekStart:peekEnd]) + contextStart := iter.head - 50 + if contextStart < 0 { + contextStart = 0 + } + contextEnd := iter.head + 50 + if contextEnd > iter.tail { + contextEnd = iter.tail + } + context := string(iter.buf[contextStart:contextEnd]) + iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", + operation, msg, iter.head-peekStart, parsing, context) +} + +// CurrentBuffer gets current buffer as string for debugging purpose +func (iter *Iterator) CurrentBuffer() string { + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, + string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) +} + +func (iter *Iterator) readByte() (ret byte) { + if iter.head == iter.tail { + if iter.loadMore() { + ret = iter.buf[iter.head] + iter.head++ + return ret + } + return 0 + } + ret = iter.buf[iter.head] + iter.head++ + return ret +} + +func (iter *Iterator) loadMore() bool { + if iter.reader == nil { + if iter.Error == nil { + iter.head = iter.tail + iter.Error = io.EOF + } + return false + } + if iter.captured != nil { + iter.captured = append(iter.captured, + iter.buf[iter.captureStartedAt:iter.tail]...) + iter.captureStartedAt = 0 + } + for { + n, err := iter.reader.Read(iter.buf) + if n == 0 { + if err != nil { + if iter.Error == nil { + iter.Error = err + } + return false + } + } else { + iter.head = 0 + iter.tail = n + return true + } + } +} + +func (iter *Iterator) unreadByte() { + if iter.Error != nil { + return + } + iter.head-- + return +} + +// Read read the next JSON element as generic interface{}. +func (iter *Iterator) Read() interface{} { + valueType := iter.WhatIsNext() + switch valueType { + case StringValue: + return iter.ReadString() + case NumberValue: + if iter.cfg.configBeforeFrozen.UseNumber { + return json.Number(iter.readNumberAsString()) + } + return iter.ReadFloat64() + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + return nil + case BoolValue: + return iter.ReadBool() + case ArrayValue: + arr := []interface{}{} + iter.ReadArrayCB(func(iter *Iterator) bool { + var elem interface{} + iter.ReadVal(&elem) + arr = append(arr, elem) + return true + }) + return arr + case ObjectValue: + obj := map[string]interface{}{} + iter.ReadMapCB(func(Iter *Iterator, field string) bool { + var elem interface{} + iter.ReadVal(&elem) + obj[field] = elem + return true + }) + return obj + default: + iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) + return nil + } +} diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go new file mode 100644 index 00000000..6188cb45 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_array.go @@ -0,0 +1,58 @@ +package jsoniter + +// ReadArray read array element, tells if the array has more element to read. +func (iter *Iterator) ReadArray() (ret bool) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return false // null + case '[': + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + return true + } + return false + case ']': + return false + case ',': + return true + default: + iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) + return + } +} + +// ReadArrayCB read array with callback +func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { + c := iter.nextToken() + if c == '[' { + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + if !callback(iter) { + return false + } + c = iter.nextToken() + for c == ',' { + if !callback(iter) { + return false + } + c = iter.nextToken() + } + if c != ']' { + iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) + return false + } + return true + } + return true + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) + return false +} diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go new file mode 100644 index 00000000..b9754638 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_float.go @@ -0,0 +1,339 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "math/big" + "strconv" + "strings" + "unsafe" +) + +var floatDigits []int8 + +const invalidCharForNumber = int8(-1) +const endOfNumber = int8(-2) +const dotInNumber = int8(-3) + +func init() { + floatDigits = make([]int8, 256) + for i := 0; i < len(floatDigits); i++ { + floatDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + floatDigits[i] = i - int8('0') + } + floatDigits[','] = endOfNumber + floatDigits[']'] = endOfNumber + floatDigits['}'] = endOfNumber + floatDigits[' '] = endOfNumber + floatDigits['\t'] = endOfNumber + floatDigits['\n'] = endOfNumber + floatDigits['.'] = dotInNumber +} + +// ReadBigFloat read big.Float +func (iter *Iterator) ReadBigFloat() (ret *big.Float) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + prec := 64 + if len(str) > prec { + prec = len(str) + } + val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) + if err != nil { + iter.Error = err + return nil + } + return val +} + +// ReadBigInt read big.Int +func (iter *Iterator) ReadBigInt() (ret *big.Int) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + ret = big.NewInt(0) + var success bool + ret, success = ret.SetString(str, 10) + if !success { + iter.ReportError("ReadBigInt", "invalid big int") + return nil + } + return ret +} + +//ReadFloat32 read float32 +func (iter *Iterator) ReadFloat32() (ret float32) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat32() + } + iter.unreadByte() + return iter.readPositiveFloat32() +} + +func (iter *Iterator) readPositiveFloat32() (ret float32) { + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c := iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.ReportError("readFloat32", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat32", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat32", "leading zero is invalid") + return + } + } + value := uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.head = i + return float32(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat32SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float32(float64(value) / float64(pow10[decimalPlaces])) + } + // too many decimal places + return iter.readFloat32SlowPath() + case invalidCharForNumber, dotInNumber: + return iter.readFloat32SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat32SlowPath() +} + +func (iter *Iterator) readNumberAsString() (ret string) { + strBuf := [16]byte{} + str := strBuf[0:0] +load_loop: + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + str = append(str, c) + continue + default: + iter.head = i + break load_loop + } + } + if !iter.loadMore() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + return + } + if len(str) == 0 { + iter.ReportError("readNumberAsString", "invalid number") + } + return *(*string)(unsafe.Pointer(&str)) +} + +func (iter *Iterator) readFloat32SlowPath() (ret float32) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat32SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 32) + if err != nil { + iter.Error = err + return + } + return float32(val) +} + +// ReadFloat64 read float64 +func (iter *Iterator) ReadFloat64() (ret float64) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat64() + } + iter.unreadByte() + return iter.readPositiveFloat64() +} + +func (iter *Iterator) readPositiveFloat64() (ret float64) { + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c := iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.ReportError("readFloat64", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat64", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat64", "leading zero is invalid") + return + } + } + value := uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.head = i + return float64(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat64SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float64(value) / float64(pow10[decimalPlaces]) + } + // too many decimal places + return iter.readFloat64SlowPath() + case invalidCharForNumber, dotInNumber: + return iter.readFloat64SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat64SlowPath() +} + +func (iter *Iterator) readFloat64SlowPath() (ret float64) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat64SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 64) + if err != nil { + iter.Error = err + return + } + return val +} + +func validateFloat(str string) string { + // strconv.ParseFloat is not validating `1.` or `1.e1` + if len(str) == 0 { + return "empty number" + } + if str[0] == '-' { + return "-- is not valid" + } + dotPos := strings.IndexByte(str, '.') + if dotPos != -1 { + if dotPos == len(str)-1 { + return "dot can not be last character" + } + switch str[dotPos+1] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + return "missing digit after dot" + } + } + return "" +} + +// ReadNumber read json.Number +func (iter *Iterator) ReadNumber() (ret json.Number) { + return json.Number(iter.readNumberAsString()) +} diff --git a/vendor/github.com/json-iterator/go/iter_int.go b/vendor/github.com/json-iterator/go/iter_int.go new file mode 100644 index 00000000..21423203 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_int.go @@ -0,0 +1,345 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var intDigits []int8 + +const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 +const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 + +func init() { + intDigits = make([]int8, 256) + for i := 0; i < len(intDigits); i++ { + intDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + intDigits[i] = i - int8('0') + } +} + +// ReadUint read uint +func (iter *Iterator) ReadUint() uint { + if strconv.IntSize == 32 { + return uint(iter.ReadUint32()) + } + return uint(iter.ReadUint64()) +} + +// ReadInt read int +func (iter *Iterator) ReadInt() int { + if strconv.IntSize == 32 { + return int(iter.ReadInt32()) + } + return int(iter.ReadInt64()) +} + +// ReadInt8 read int8 +func (iter *Iterator) ReadInt8() (ret int8) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt8+1 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int8(val) + } + val := iter.readUint32(c) + if val > math.MaxInt8 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int8(val) +} + +// ReadUint8 read uint8 +func (iter *Iterator) ReadUint8() (ret uint8) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint8 { + iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint8(val) +} + +// ReadInt16 read int16 +func (iter *Iterator) ReadInt16() (ret int16) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt16+1 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int16(val) + } + val := iter.readUint32(c) + if val > math.MaxInt16 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int16(val) +} + +// ReadUint16 read uint16 +func (iter *Iterator) ReadUint16() (ret uint16) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint16 { + iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint16(val) +} + +// ReadInt32 read int32 +func (iter *Iterator) ReadInt32() (ret int32) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt32+1 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int32(val) + } + val := iter.readUint32(c) + if val > math.MaxInt32 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int32(val) +} + +// ReadUint32 read uint32 +func (iter *Iterator) ReadUint32() (ret uint32) { + return iter.readUint32(iter.nextToken()) +} + +func (iter *Iterator) readUint32(c byte) (ret uint32) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint32(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint32(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint32(ind2)*10 + uint32(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint32SafeToMultiply10 { + value2 := (value << 3) + (value << 1) + uint32(ind) + if value2 < value { + iter.ReportError("readUint32", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint32(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +// ReadInt64 read int64 +func (iter *Iterator) ReadInt64() (ret int64) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint64(iter.readByte()) + if val > math.MaxInt64+1 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return -int64(val) + } + val := iter.readUint64(c) + if val > math.MaxInt64 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return int64(val) +} + +// ReadUint64 read uint64 +func (iter *Iterator) ReadUint64() uint64 { + return iter.readUint64(iter.nextToken()) +} + +func (iter *Iterator) readUint64(c byte) (ret uint64) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint64(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint64(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint64(ind2)*10 + uint64(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint64SafeToMultiple10 { + value2 := (value << 3) + (value << 1) + uint64(ind) + if value2 < value { + iter.ReportError("readUint64", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint64(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +func (iter *Iterator) assertInteger() { + if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { + iter.ReportError("assertInteger", "can not decode float as int") + } +} diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go new file mode 100644 index 00000000..1c575767 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_object.go @@ -0,0 +1,251 @@ +package jsoniter + +import ( + "fmt" + "strings" +) + +// ReadObject read one field from object. +// If object ended, returns empty string. +// Otherwise, returns the field name. +func (iter *Iterator) ReadObject() (ret string) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return "" // null + case '{': + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } + if c == '}' { + return "" // end of object + } + iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) + return + case ',': + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + case '}': + return "" // end of object + default: + iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) + return + } +} + +// CaseInsensitive +func (iter *Iterator) readFieldHash() int64 { + hash := int64(0x811c9dc5) + c := iter.nextToken() + if c != '"' { + iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) + return 0 + } + for { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + b := iter.buf[i] + if b == '\\' { + iter.head = i + for _, b := range iter.readStringSlowPath() { + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if b == '"' { + iter.head = i + 1 + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + if !iter.loadMore() { + iter.ReportError("readFieldHash", `incomplete field name`) + return 0 + } + } +} + +func calcHash(str string, caseSensitive bool) int64 { + if !caseSensitive { + str = strings.ToLower(str) + } + hash := int64(0x811c9dc5) + for _, b := range []byte(str) { + hash ^= int64(b) + hash *= 0x1000193 + } + return int64(hash) +} + +// ReadObjectCB read object with callback, the key is ascii only and field name not copied +func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + var field string + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadObjectCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +// ReadMapCB read map with callback, the key can be any string +func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadMapCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectStart() bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '}' { + return false + } + iter.unreadByte() + return true + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return false + } + iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { + str := iter.ReadStringAsSlice() + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if iter.buf[iter.head] != ':' { + iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) + return + } + iter.head++ + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if ret == nil { + return str + } + return ret +} diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go new file mode 100644 index 00000000..f58beb91 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip.go @@ -0,0 +1,129 @@ +package jsoniter + +import "fmt" + +// ReadNil reads a json object as nil and +// returns whether it's a nil or not +func (iter *Iterator) ReadNil() (ret bool) { + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') // null + return true + } + iter.unreadByte() + return false +} + +// ReadBool reads a json object as BoolValue +func (iter *Iterator) ReadBool() (ret bool) { + c := iter.nextToken() + if c == 't' { + iter.skipThreeBytes('r', 'u', 'e') + return true + } + if c == 'f' { + iter.skipFourBytes('a', 'l', 's', 'e') + return false + } + iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) + return +} + +// SkipAndReturnBytes skip next JSON element, and return its content as []byte. +// The []byte can be kept, it is a copy of data. +func (iter *Iterator) SkipAndReturnBytes() []byte { + iter.startCapture(iter.head) + iter.Skip() + return iter.stopCapture() +} + +type captureBuffer struct { + startedAt int + captured []byte +} + +func (iter *Iterator) startCapture(captureStartedAt int) { + if iter.captured != nil { + panic("already in capture mode") + } + iter.captureStartedAt = captureStartedAt + iter.captured = make([]byte, 0, 32) +} + +func (iter *Iterator) stopCapture() []byte { + if iter.captured == nil { + panic("not in capture mode") + } + captured := iter.captured + remaining := iter.buf[iter.captureStartedAt:iter.head] + iter.captureStartedAt = -1 + iter.captured = nil + if len(captured) == 0 { + copied := make([]byte, len(remaining)) + copy(copied, remaining) + return copied + } + captured = append(captured, remaining...) + return captured +} + +// Skip skips a json object and positions to relatively the next json object +func (iter *Iterator) Skip() { + c := iter.nextToken() + switch c { + case '"': + iter.skipString() + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + case '0': + iter.unreadByte() + iter.ReadFloat32() + case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.skipNumber() + case '[': + iter.skipArray() + case '{': + iter.skipObject() + default: + iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) + return + } +} + +func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b4 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } +} + +func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go new file mode 100644 index 00000000..8fcdc3b6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go @@ -0,0 +1,144 @@ +//+build jsoniter_sloppy + +package jsoniter + +// sloppy but faster implementation, do not validate the input json + +func (iter *Iterator) skipNumber() { + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\r', '\t', ',', '}', ']': + iter.head = i + return + } + } + if !iter.loadMore() { + return + } + } +} + +func (iter *Iterator) skipArray() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '[': // If open symbol, increase level + level++ + case ']': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete array") + return + } + } +} + +func (iter *Iterator) skipObject() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '{': // If open symbol, increase level + level++ + case '}': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete object") + return + } + } +} + +func (iter *Iterator) skipString() { + for { + end, escaped := iter.findStringEnd() + if end == -1 { + if !iter.loadMore() { + iter.ReportError("skipString", "incomplete string") + return + } + if escaped { + iter.head = 1 // skip the first char as last char read is \ + } + } else { + iter.head = end + return + } + } +} + +// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go +// Tries to find the end of string +// Support if string contains escaped quote symbols. +func (iter *Iterator) findStringEnd() (int, bool) { + escaped := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + if !escaped { + return i + 1, false + } + j := i - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return i + 1, true + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + } + } else if c == '\\' { + escaped = true + } + } + j := iter.tail - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return -1, false // do not end with \ + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + + } + return -1, true // end with \ +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go new file mode 100644 index 00000000..6cf66d04 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_strict.go @@ -0,0 +1,99 @@ +//+build !jsoniter_sloppy + +package jsoniter + +import ( + "fmt" + "io" +) + +func (iter *Iterator) skipNumber() { + if !iter.trySkipNumber() { + iter.unreadByte() + if iter.Error != nil && iter.Error != io.EOF { + return + } + iter.ReadFloat64() + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = nil + iter.ReadBigFloat() + } + } +} + +func (iter *Iterator) trySkipNumber() bool { + dotFound := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + case '.': + if dotFound { + iter.ReportError("validateNumber", `more than one dot found in number`) + return true // already failed + } + if i+1 == iter.tail { + return false + } + c = iter.buf[i+1] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + iter.ReportError("validateNumber", `missing digit after dot`) + return true // already failed + } + dotFound = true + default: + switch c { + case ',', ']', '}', ' ', '\t', '\n', '\r': + if iter.head == i { + return false // if - without following digits + } + iter.head = i + return true // must be valid + } + return false // may be invalid + } + } + return false +} + +func (iter *Iterator) skipString() { + if !iter.trySkipString() { + iter.unreadByte() + iter.ReadString() + } +} + +func (iter *Iterator) trySkipString() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + iter.head = i + 1 + return true // valid + } else if c == '\\' { + return false + } else if c < ' ' { + iter.ReportError("trySkipString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return true // already failed + } + } + return false +} + +func (iter *Iterator) skipObject() { + iter.unreadByte() + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + return true + }) +} + +func (iter *Iterator) skipArray() { + iter.unreadByte() + iter.ReadArrayCB(func(iter *Iterator) bool { + iter.Skip() + return true + }) +} diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/iter_str.go new file mode 100644 index 00000000..adc487ea --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_str.go @@ -0,0 +1,215 @@ +package jsoniter + +import ( + "fmt" + "unicode/utf16" +) + +// ReadString read string from iterator +func (iter *Iterator) ReadString() (ret string) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + ret = string(iter.buf[iter.head:i]) + iter.head = i + 1 + return ret + } else if c == '\\' { + break + } else if c < ' ' { + iter.ReportError("ReadString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return + } + } + return iter.readStringSlowPath() + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return "" + } + iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readStringSlowPath() (ret string) { + var str []byte + var c byte + for iter.Error == nil { + c = iter.readByte() + if c == '"' { + return string(str) + } + if c == '\\' { + c = iter.readByte() + str = iter.readEscapedChar(c, str) + } else { + str = append(str, c) + } + } + iter.ReportError("readStringSlowPath", "unexpected end of input") + return +} + +func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { + switch c { + case 'u': + r := iter.readU4() + if utf16.IsSurrogate(r) { + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != '\\' { + iter.unreadByte() + str = appendRune(str, r) + return str + } + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != 'u' { + str = appendRune(str, r) + return iter.readEscapedChar(c, str) + } + r2 := iter.readU4() + if iter.Error != nil { + return nil + } + combined := utf16.DecodeRune(r, r2) + if combined == '\uFFFD' { + str = appendRune(str, r) + str = appendRune(str, r2) + } else { + str = appendRune(str, combined) + } + } else { + str = appendRune(str, r) + } + case '"': + str = append(str, '"') + case '\\': + str = append(str, '\\') + case '/': + str = append(str, '/') + case 'b': + str = append(str, '\b') + case 'f': + str = append(str, '\f') + case 'n': + str = append(str, '\n') + case 'r': + str = append(str, '\r') + case 't': + str = append(str, '\t') + default: + iter.ReportError("readEscapedChar", + `invalid escape char after \`) + return nil + } + return str +} + +// ReadStringAsSlice read string from iterator without copying into string form. +// The []byte can not be kept, as it will change after next iterator call. +func (iter *Iterator) ReadStringAsSlice() (ret []byte) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + // for: field name, base64, number + if iter.buf[i] == '"' { + // fast path: reuse the underlying buffer + ret = iter.buf[iter.head:i] + iter.head = i + 1 + return ret + } + } + readLen := iter.tail - iter.head + copied := make([]byte, readLen, readLen*2) + copy(copied, iter.buf[iter.head:iter.tail]) + iter.head = iter.tail + for iter.Error == nil { + c := iter.readByte() + if c == '"' { + return copied + } + copied = append(copied, c) + } + return copied + } + iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readU4() (ret rune) { + for i := 0; i < 4; i++ { + c := iter.readByte() + if iter.Error != nil { + return + } + if c >= '0' && c <= '9' { + ret = ret*16 + rune(c-'0') + } else if c >= 'a' && c <= 'f' { + ret = ret*16 + rune(c-'a'+10) + } else if c >= 'A' && c <= 'F' { + ret = ret*16 + rune(c-'A'+10) + } else { + iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) + return + } + } + return ret +} + +const ( + t1 = 0x00 // 0000 0000 + tx = 0x80 // 1000 0000 + t2 = 0xC0 // 1100 0000 + t3 = 0xE0 // 1110 0000 + t4 = 0xF0 // 1111 0000 + t5 = 0xF8 // 1111 1000 + + maskx = 0x3F // 0011 1111 + mask2 = 0x1F // 0001 1111 + mask3 = 0x0F // 0000 1111 + mask4 = 0x07 // 0000 0111 + + rune1Max = 1<<7 - 1 + rune2Max = 1<<11 - 1 + rune3Max = 1<<16 - 1 + + surrogateMin = 0xD800 + surrogateMax = 0xDFFF + + maxRune = '\U0010FFFF' // Maximum valid Unicode code point. + runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" +) + +func appendRune(p []byte, r rune) []byte { + // Negative values are erroneous. Making it unsigned addresses the problem. + switch i := uint32(r); { + case i <= rune1Max: + p = append(p, byte(r)) + return p + case i <= rune2Max: + p = append(p, t2|byte(r>>6)) + p = append(p, tx|byte(r)&maskx) + return p + case i > maxRune, surrogateMin <= i && i <= surrogateMax: + r = runeError + fallthrough + case i <= rune3Max: + p = append(p, t3|byte(r>>12)) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + default: + p = append(p, t4|byte(r>>18)) + p = append(p, tx|byte(r>>12)&maskx) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + } +} diff --git a/vendor/github.com/json-iterator/go/jsoniter.go b/vendor/github.com/json-iterator/go/jsoniter.go new file mode 100644 index 00000000..c2934f91 --- /dev/null +++ b/vendor/github.com/json-iterator/go/jsoniter.go @@ -0,0 +1,18 @@ +// Package jsoniter implements encoding and decoding of JSON as defined in +// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. +// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter +// and variable type declarations (if any). +// jsoniter interfaces gives 100% compatibility with code using standard lib. +// +// "JSON and Go" +// (https://golang.org/doc/articles/json_and_go.html) +// gives a description of how Marshal/Unmarshal operate +// between arbitrary or predefined json objects and bytes, +// and it applies to jsoniter.Marshal/Unmarshal as well. +// +// Besides, jsoniter.Iterator provides a different set of interfaces +// iterating given bytes/string/reader +// and yielding parsed elements one by one. +// This set of interfaces reads input as required and gives +// better performance. +package jsoniter diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/pool.go new file mode 100644 index 00000000..e2389b56 --- /dev/null +++ b/vendor/github.com/json-iterator/go/pool.go @@ -0,0 +1,42 @@ +package jsoniter + +import ( + "io" +) + +// IteratorPool a thread safe pool of iterators with same configuration +type IteratorPool interface { + BorrowIterator(data []byte) *Iterator + ReturnIterator(iter *Iterator) +} + +// StreamPool a thread safe pool of streams with same configuration +type StreamPool interface { + BorrowStream(writer io.Writer) *Stream + ReturnStream(stream *Stream) +} + +func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { + stream := cfg.streamPool.Get().(*Stream) + stream.Reset(writer) + return stream +} + +func (cfg *frozenConfig) ReturnStream(stream *Stream) { + stream.out = nil + stream.Error = nil + stream.Attachment = nil + cfg.streamPool.Put(stream) +} + +func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { + iter := cfg.iteratorPool.Get().(*Iterator) + iter.ResetBytes(data) + return iter +} + +func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { + iter.Error = nil + iter.Attachment = nil + cfg.iteratorPool.Put(iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go new file mode 100644 index 00000000..4459e203 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect.go @@ -0,0 +1,332 @@ +package jsoniter + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/modern-go/reflect2" +) + +// ValDecoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValDecoder with json.Decoder. +// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). +// +// Reflection on type to create decoders, which is then cached +// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions +// 1. create instance of new value, for example *int will need a int to be allocated +// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New +// 3. assignment to map, both key and value will be reflect.Value +// For a simple struct binding, it will be reflect.Value free and allocation free +type ValDecoder interface { + Decode(ptr unsafe.Pointer, iter *Iterator) +} + +// ValEncoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValEncoder with json.Encoder. +// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). +type ValEncoder interface { + IsEmpty(ptr unsafe.Pointer) bool + Encode(ptr unsafe.Pointer, stream *Stream) +} + +type checkIsEmpty interface { + IsEmpty(ptr unsafe.Pointer) bool +} + +type ctx struct { + *frozenConfig + prefix string + encoders map[reflect2.Type]ValEncoder + decoders map[reflect2.Type]ValDecoder +} + +func (b *ctx) caseSensitive() bool { + if b.frozenConfig == nil { + // default is case-insensitive + return false + } + return b.frozenConfig.caseSensitive +} + +func (b *ctx) append(prefix string) *ctx { + return &ctx{ + frozenConfig: b.frozenConfig, + prefix: b.prefix + " " + prefix, + encoders: b.encoders, + decoders: b.decoders, + } +} + +// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal +func (iter *Iterator) ReadVal(obj interface{}) { + cacheKey := reflect2.RTypeOf(obj) + decoder := iter.cfg.getDecoderFromCache(cacheKey) + if decoder == nil { + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + iter.ReportError("ReadVal", "can only unmarshal into pointer") + return + } + decoder = iter.cfg.DecoderOf(typ) + } + ptr := reflect2.PtrOf(obj) + if ptr == nil { + iter.ReportError("ReadVal", "can not read into nil pointer") + return + } + decoder.Decode(ptr, iter) +} + +// WriteVal copy the go interface into underlying JSON, same as json.Marshal +func (stream *Stream) WriteVal(val interface{}) { + if nil == val { + stream.WriteNil() + return + } + cacheKey := reflect2.RTypeOf(val) + encoder := stream.cfg.getEncoderFromCache(cacheKey) + if encoder == nil { + typ := reflect2.TypeOf(val) + encoder = stream.cfg.EncoderOf(typ) + } + encoder.Encode(reflect2.PtrOf(val), stream) +} + +func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { + cacheKey := typ.RType() + decoder := cfg.getDecoderFromCache(cacheKey) + if decoder != nil { + return decoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + ptrType := typ.(*reflect2.UnsafePtrType) + decoder = decoderOfType(ctx, ptrType.Elem()) + cfg.addDecoderToCache(cacheKey, decoder) + return decoder +} + +func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfType(ctx, typ) + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + return decoder +} + +func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoders[typ] + if decoder != nil { + return decoder + } + placeholder := &placeholderDecoder{} + ctx.decoders[typ] = placeholder + decoder = _createDecoderOfType(ctx, typ) + placeholder.decoder = decoder + return decoder +} + +func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := createDecoderOfJsonRawMessage(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfJsonNumber(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfMarshaler(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfAny(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfNative(ctx, typ) + if decoder != nil { + return decoder + } + switch typ.Kind() { + case reflect.Interface: + ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) + if isIFace { + return &ifaceDecoder{valType: ifaceType} + } + return &efaceDecoder{} + case reflect.Struct: + return decoderOfStruct(ctx, typ) + case reflect.Array: + return decoderOfArray(ctx, typ) + case reflect.Slice: + return decoderOfSlice(ctx, typ) + case reflect.Map: + return decoderOfMap(ctx, typ) + case reflect.Ptr: + return decoderOfOptional(ctx, typ) + default: + return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { + cacheKey := typ.RType() + encoder := cfg.getEncoderFromCache(cacheKey) + if encoder != nil { + return encoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + encoder = encoderOfType(ctx, typ) + if typ.LikePtr() { + encoder = &onePtrEncoder{encoder} + } + cfg.addEncoderToCache(cacheKey, encoder) + return encoder +} + +type onePtrEncoder struct { + encoder ValEncoder +} + +func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfType(ctx, typ) + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + return encoder +} + +func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoders[typ] + if encoder != nil { + return encoder + } + placeholder := &placeholderEncoder{} + ctx.encoders[typ] = placeholder + encoder = _createEncoderOfType(ctx, typ) + placeholder.encoder = encoder + return encoder +} +func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := createEncoderOfJsonRawMessage(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfJsonNumber(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfMarshaler(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfAny(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return encoderOfStruct(ctx, typ) + case reflect.Array: + return encoderOfArray(ctx, typ) + case reflect.Slice: + return encoderOfSlice(ctx, typ) + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return encoderOfOptional(ctx, typ) + default: + return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +type lazyErrorDecoder struct { + err error +} + +func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.WhatIsNext() != NilValue { + if iter.Error == nil { + iter.Error = decoder.err + } + } else { + iter.Skip() + } +} + +type lazyErrorEncoder struct { + err error +} + +func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if ptr == nil { + stream.WriteNil() + } else if stream.Error == nil { + stream.Error = encoder.err + } +} + +func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type placeholderDecoder struct { + decoder ValDecoder +} + +func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(ptr, iter) +} + +type placeholderEncoder struct { + encoder ValEncoder +} + +func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(ptr, stream) +} + +func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go new file mode 100644 index 00000000..13a0b7b0 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_array.go @@ -0,0 +1,104 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayDecoder{arrayType, decoder} +} + +func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + if arrayType.Len() == 0 { + return emptyArrayEncoder{} + } + encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayEncoder{arrayType, encoder} +} + +type emptyArrayEncoder struct{} + +func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyArray() +} + +func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return true +} + +type arrayEncoder struct { + arrayType *reflect2.UnsafeArrayType + elemEncoder ValEncoder +} + +func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteArrayStart() + elemPtr := unsafe.Pointer(ptr) + encoder.elemEncoder.Encode(elemPtr, stream) + for i := 1; i < encoder.arrayType.Len(); i++ { + stream.WriteMore() + elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) + } +} + +func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type arrayDecoder struct { + arrayType *reflect2.UnsafeArrayType + elemDecoder ValDecoder +} + +func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) + } +} + +func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + arrayType := decoder.arrayType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return + } + if c != '[' { + iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + return + } + iter.unreadByte() + elemPtr := arrayType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + if length >= arrayType.Len() { + iter.Skip() + continue + } + idx := length + length += 1 + elemPtr = arrayType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode array", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go new file mode 100644 index 00000000..8b6bc8b4 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_dynamic.go @@ -0,0 +1,70 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "reflect" + "unsafe" +) + +type dynamicEncoder struct { + valType reflect2.Type +} + +func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + stream.WriteVal(obj) +} + +func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.valType.UnsafeIndirect(ptr) == nil +} + +type efaceDecoder struct { +} + +func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + pObj := (*interface{})(ptr) + obj := *pObj + if obj == nil { + *pObj = iter.Read() + return + } + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + *pObj = iter.Read() + return + } + ptrType := typ.(*reflect2.UnsafePtrType) + ptrElemType := ptrType.Elem() + if iter.WhatIsNext() == NilValue { + if ptrElemType.Kind() != reflect.Ptr { + iter.skipFourBytes('n', 'u', 'l', 'l') + *pObj = nil + return + } + } + if reflect2.IsNil(obj) { + obj := ptrElemType.New() + iter.ReadVal(obj) + *pObj = obj + return + } + iter.ReadVal(obj) +} + +type ifaceDecoder struct { + valType *reflect2.UnsafeIFaceType +} + +func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew()) + return + } + obj := decoder.valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + iter.ReportError("decode non empty interface", "can not unmarshal into nil") + return + } + iter.ReadVal(obj) +} diff --git a/vendor/github.com/json-iterator/go/reflect_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go new file mode 100644 index 00000000..05e8fbf1 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_extension.go @@ -0,0 +1,483 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "reflect" + "sort" + "strings" + "unicode" + "unsafe" +) + +var typeDecoders = map[string]ValDecoder{} +var fieldDecoders = map[string]ValDecoder{} +var typeEncoders = map[string]ValEncoder{} +var fieldEncoders = map[string]ValEncoder{} +var extensions = []Extension{} + +// StructDescriptor describe how should we encode/decode the struct +type StructDescriptor struct { + Type reflect2.Type + Fields []*Binding +} + +// GetField get one field from the descriptor by its name. +// Can not use map here to keep field orders. +func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { + for _, binding := range structDescriptor.Fields { + if binding.Field.Name() == fieldName { + return binding + } + } + return nil +} + +// Binding describe how should we encode/decode the struct field +type Binding struct { + levels []int + Field reflect2.StructField + FromNames []string + ToNames []string + Encoder ValEncoder + Decoder ValDecoder +} + +// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. +// Can also rename fields by UpdateStructDescriptor. +type Extension interface { + UpdateStructDescriptor(structDescriptor *StructDescriptor) + CreateMapKeyDecoder(typ reflect2.Type) ValDecoder + CreateMapKeyEncoder(typ reflect2.Type) ValEncoder + CreateDecoder(typ reflect2.Type) ValDecoder + CreateEncoder(typ reflect2.Type) ValEncoder + DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder + DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder +} + +// DummyExtension embed this type get dummy implementation for all methods of Extension +type DummyExtension struct { +} + +// UpdateStructDescriptor No-op +func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder No-op +func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder No-op +func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type EncoderExtension map[reflect2.Type]ValEncoder + +// UpdateStructDescriptor No-op +func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateDecoder No-op +func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder get encoder from map +func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return extension[typ] +} + +// CreateMapKeyDecoder No-op +func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type DecoderExtension map[reflect2.Type]ValDecoder + +// UpdateStructDescriptor No-op +func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder get decoder from map +func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return extension[typ] +} + +// CreateEncoder No-op +func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type funcDecoder struct { + fun DecoderFunc +} + +func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.fun(ptr, iter) +} + +type funcEncoder struct { + fun EncoderFunc + isEmptyFunc func(ptr unsafe.Pointer) bool +} + +func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.fun(ptr, stream) +} + +func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { + if encoder.isEmptyFunc == nil { + return false + } + return encoder.isEmptyFunc(ptr) +} + +// DecoderFunc the function form of TypeDecoder +type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) + +// EncoderFunc the function form of TypeEncoder +type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) + +// RegisterTypeDecoderFunc register TypeDecoder for a type with function +func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { + typeDecoders[typ] = &funcDecoder{fun} +} + +// RegisterTypeDecoder register TypeDecoder for a typ +func RegisterTypeDecoder(typ string, decoder ValDecoder) { + typeDecoders[typ] = decoder +} + +// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function +func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { + RegisterFieldDecoder(typ, field, &funcDecoder{fun}) +} + +// RegisterFieldDecoder register TypeDecoder for a struct field +func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { + fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder +} + +// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function +func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} +} + +// RegisterTypeEncoder register TypeEncoder for a type +func RegisterTypeEncoder(typ string, encoder ValEncoder) { + typeEncoders[typ] = encoder +} + +// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function +func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) +} + +// RegisterFieldEncoder register TypeEncoder for a struct field +func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { + fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder +} + +// RegisterExtension register extension +func RegisterExtension(extension Extension) { + extensions = append(extensions, extension) +} + +func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := _getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + } + return decoder +} +func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + for _, extension := range extensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + decoder := ctx.decoderExtension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + typeName := typ.String() + decoder = typeDecoders[typeName] + if decoder != nil { + return decoder + } + if typ.Kind() == reflect.Ptr { + ptrType := typ.(*reflect2.UnsafePtrType) + decoder := typeDecoders[ptrType.Elem().String()] + if decoder != nil { + return &OptionalDecoder{ptrType.Elem(), decoder} + } + } + return nil +} + +func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := _getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + } + return encoder +} + +func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + for _, extension := range extensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + encoder := ctx.encoderExtension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + typeName := typ.String() + encoder = typeEncoders[typeName] + if encoder != nil { + return encoder + } + if typ.Kind() == reflect.Ptr { + typePtr := typ.(*reflect2.UnsafePtrType) + encoder := typeEncoders[typePtr.Elem().String()] + if encoder != nil { + return &OptionalEncoder{encoder} + } + } + return nil +} + +func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { + structType := typ.(*reflect2.UnsafeStructType) + embeddedBindings := []*Binding{} + bindings := []*Binding{} + for i := 0; i < structType.NumField(); i++ { + field := structType.Field(i) + tag, hastag := field.Tag().Lookup(ctx.getTagKey()) + if ctx.onlyTaggedField && !hastag && !field.Anonymous() { + continue + } + tagParts := strings.Split(tag, ",") + if tag == "-" { + continue + } + if field.Anonymous() && (tag == "" || tagParts[0] == "") { + if field.Type().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, field.Type()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } else if field.Type().Kind() == reflect.Ptr { + ptrType := field.Type().(*reflect2.UnsafePtrType) + if ptrType.Elem().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, ptrType.Elem()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &dereferenceEncoder{binding.Encoder} + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } + } + } + fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) + fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) + decoder := fieldDecoders[fieldCacheKey] + if decoder == nil { + decoder = decoderOfType(ctx.append(field.Name()), field.Type()) + } + encoder := fieldEncoders[fieldCacheKey] + if encoder == nil { + encoder = encoderOfType(ctx.append(field.Name()), field.Type()) + } + binding := &Binding{ + Field: field, + FromNames: fieldNames, + ToNames: fieldNames, + Decoder: decoder, + Encoder: encoder, + } + binding.levels = []int{i} + bindings = append(bindings, binding) + } + return createStructDescriptor(ctx, typ, bindings, embeddedBindings) +} +func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { + structDescriptor := &StructDescriptor{ + Type: typ, + Fields: bindings, + } + for _, extension := range extensions { + extension.UpdateStructDescriptor(structDescriptor) + } + ctx.encoderExtension.UpdateStructDescriptor(structDescriptor) + ctx.decoderExtension.UpdateStructDescriptor(structDescriptor) + for _, extension := range ctx.extraExtensions { + extension.UpdateStructDescriptor(structDescriptor) + } + processTags(structDescriptor, ctx.frozenConfig) + // merge normal & embedded bindings & sort with original order + allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) + sort.Sort(allBindings) + structDescriptor.Fields = allBindings + return structDescriptor +} + +type sortableBindings []*Binding + +func (bindings sortableBindings) Len() int { + return len(bindings) +} + +func (bindings sortableBindings) Less(i, j int) bool { + left := bindings[i].levels + right := bindings[j].levels + k := 0 + for { + if left[k] < right[k] { + return true + } else if left[k] > right[k] { + return false + } + k++ + } +} + +func (bindings sortableBindings) Swap(i, j int) { + bindings[i], bindings[j] = bindings[j], bindings[i] +} + +func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { + for _, binding := range structDescriptor.Fields { + shouldOmitEmpty := false + tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") + for _, tagPart := range tagParts[1:] { + if tagPart == "omitempty" { + shouldOmitEmpty = true + } else if tagPart == "string" { + if binding.Field.Type().Kind() == reflect.String { + binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} + binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} + } else { + binding.Decoder = &stringModeNumberDecoder{binding.Decoder} + binding.Encoder = &stringModeNumberEncoder{binding.Encoder} + } + } + } + binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} + binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} + } +} + +func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { + // ignore? + if wholeTag == "-" { + return []string{} + } + // rename? + var fieldNames []string + if tagProvidedFieldName == "" { + fieldNames = []string{originalFieldName} + } else { + fieldNames = []string{tagProvidedFieldName} + } + // private? + isNotExported := unicode.IsLower(rune(originalFieldName[0])) + if isNotExported { + fieldNames = []string{} + } + return fieldNames +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go new file mode 100644 index 00000000..98d45c1e --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_number.go @@ -0,0 +1,112 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "strconv" + "unsafe" +) + +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +func CastJsonNumber(val interface{}) (string, bool) { + switch typedVal := val.(type) { + case json.Number: + return string(typedVal), true + case Number: + return string(typedVal), true + } + return "", false +} + +var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() +var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() + +func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +type jsonNumberCodec struct { +} + +func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*json.Number)(ptr)) = json.Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*json.Number)(ptr)) = "" + default: + *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*json.Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.Number)(ptr))) == 0 +} + +type jsoniterNumberCodec struct { +} + +func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*Number)(ptr)) = Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*Number)(ptr)) = "" + default: + *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*Number)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go new file mode 100644 index 00000000..f2619936 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go @@ -0,0 +1,60 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "unsafe" +) + +var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem() +var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem() + +func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +type jsonRawMessageCodec struct { +} + +func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*json.RawMessage)(ptr)))) +} + +func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 +} + +type jsoniterRawMessageCodec struct { +} + +func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*RawMessage)(ptr)))) +} + +func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*RawMessage)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go new file mode 100644 index 00000000..547b4421 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_map.go @@ -0,0 +1,338 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "sort" + "unsafe" +) + +func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder { + mapType := typ.(*reflect2.UnsafeMapType) + keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()) + elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem()) + return &mapDecoder{ + mapType: mapType, + keyType: mapType.Key(), + elemType: mapType.Elem(), + keyDecoder: keyDecoder, + elemDecoder: elemDecoder, + } +} + +func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder { + mapType := typ.(*reflect2.UnsafeMapType) + if ctx.sortMapKeys { + return &sortKeysMapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } + } + return &mapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } +} + +func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + } + switch typ.Kind() { + case reflect.String: + return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyDecoder{decoderOfType(ctx, typ)} + default: + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(unmarshalerType) { + return &referenceDecoder{ + &unmarshalerDecoder{ + valType: ptrType, + }, + } + } + if typ.Implements(unmarshalerType) { + return &unmarshalerDecoder{ + valType: typ, + } + } + if ptrType.Implements(textUnmarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ + valType: ptrType, + }, + } + } + if typ.Implements(textUnmarshalerType) { + return &textUnmarshalerDecoder{ + valType: typ, + } + } + return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + } + switch typ.Kind() { + case reflect.String: + return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyEncoder{encoderOfType(ctx, typ)} + default: + if typ == textMarshalerType { + return &directTextMarshalerEncoder{ + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + if typ.Implements(textMarshalerType) { + return &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + if typ.Kind() == reflect.Interface { + return &dynamicMapKeyEncoder{ctx, typ} + } + return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +type mapDecoder struct { + mapType *reflect2.UnsafeMapType + keyType reflect2.Type + elemType reflect2.Type + keyDecoder ValDecoder + elemDecoder ValDecoder +} + +func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + mapType := decoder.mapType + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + *(*unsafe.Pointer)(ptr) = nil + mapType.UnsafeSet(ptr, mapType.UnsafeNew()) + return + } + if mapType.UnsafeIsNil(ptr) { + mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0)) + } + if c != '{' { + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return + } + c = iter.nextToken() + if c == '}' { + return + } + if c != '"' { + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) + return + } + iter.unreadByte() + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + } + if c != '}' { + iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c})) + } +} + +type numericMapKeyDecoder struct { + decoder ValDecoder +} + +func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } + decoder.decoder.Decode(ptr, iter) + c = iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } +} + +type numericMapKeyEncoder struct { + encoder ValEncoder +} + +func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.encoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type dynamicMapKeyEncoder struct { + ctx *ctx + valType reflect2.Type +} + +func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) +} + +func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + obj := encoder.valType.UnsafeIndirect(ptr) + return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) +} + +type mapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + iter := encoder.mapType.UnsafeIterate(ptr) + for i := 0; iter.HasNext(); i++ { + if i != 0 { + stream.WriteMore() + } + key, elem := iter.UnsafeNext() + encoder.keyEncoder.Encode(key, stream) + if stream.indention > 0 { + stream.writeTwoBytes(byte(':'), byte(' ')) + } else { + stream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, stream) + } + stream.WriteObjectEnd() +} + +func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type sortKeysMapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *(*unsafe.Pointer)(ptr) == nil { + stream.WriteNil() + return + } + stream.WriteObjectStart() + mapIter := encoder.mapType.UnsafeIterate(ptr) + subStream := stream.cfg.BorrowStream(nil) + subIter := stream.cfg.BorrowIterator(nil) + keyValues := encodedKeyValues{} + for mapIter.HasNext() { + subStream.buf = make([]byte, 0, 64) + key, elem := mapIter.UnsafeNext() + encoder.keyEncoder.Encode(key, subStream) + if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { + stream.Error = subStream.Error + } + encodedKey := subStream.Buffer() + subIter.ResetBytes(encodedKey) + decodedKey := subIter.ReadString() + if stream.indention > 0 { + subStream.writeTwoBytes(byte(':'), byte(' ')) + } else { + subStream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, subStream) + keyValues = append(keyValues, encodedKV{ + key: decodedKey, + keyValue: subStream.Buffer(), + }) + } + sort.Sort(keyValues) + for i, keyValue := range keyValues { + if i != 0 { + stream.WriteMore() + } + stream.Write(keyValue.keyValue) + } + stream.WriteObjectEnd() + stream.cfg.ReturnStream(subStream) + stream.cfg.ReturnIterator(subIter) +} + +func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type encodedKeyValues []encodedKV + +type encodedKV struct { + key string + keyValue []byte +} + +func (sv encodedKeyValues) Len() int { return len(sv) } +func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key } diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go new file mode 100644 index 00000000..fea50719 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_marshaler.go @@ -0,0 +1,217 @@ +package jsoniter + +import ( + "encoding" + "encoding/json" + "github.com/modern-go/reflect2" + "unsafe" +) + +var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() +var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem() +var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem() +var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem() + +func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(unmarshalerType) { + return &referenceDecoder{ + &unmarshalerDecoder{ptrType}, + } + } + if ptrType.Implements(textUnmarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ptrType}, + } + } + return nil +} + +func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == marshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + } + return encoder + } + if typ.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &marshalerEncoder{ + valType: typ, + checkIsEmpty: checkIsEmpty, + } + return encoder + } + ptrType := reflect2.PtrTo(typ) + if ctx.prefix != "" && ptrType.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &marshalerEncoder{ + valType: ptrType, + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + if typ == textMarshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directTextMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + return encoder + } + if typ.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return encoder + } + // if prefix is empty, the type is the root type + if ctx.prefix != "" && ptrType.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: ptrType, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + return nil +} + +type marshalerEncoder struct { + checkIsEmpty checkIsEmpty + valType reflect2.Type +} + +func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + bytes, err := json.Marshal(obj) + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} + +func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directMarshalerEncoder struct { + checkIsEmpty checkIsEmpty +} + +func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*json.Marshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} + +func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type textMarshalerEncoder struct { + valType reflect2.Type + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + marshaler := (obj).(encoding.TextMarshaler) + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directTextMarshalerEncoder struct { + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*encoding.TextMarshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type unmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + unmarshaler := obj.(json.Unmarshaler) + iter.nextToken() + iter.unreadByte() // skip spaces + bytes := iter.SkipAndReturnBytes() + err := unmarshaler.UnmarshalJSON(bytes) + if err != nil { + iter.ReportError("unmarshalerDecoder", err.Error()) + } +} + +type textUnmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + ptrType := valType.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elem := elemType.UnsafeNew() + ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem)) + obj = valType.UnsafeIndirect(ptr) + } + unmarshaler := (obj).(encoding.TextUnmarshaler) + str := iter.ReadString() + err := unmarshaler.UnmarshalText([]byte(str)) + if err != nil { + iter.ReportError("textUnmarshalerDecoder", err.Error()) + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go new file mode 100644 index 00000000..9042eb0c --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_native.go @@ -0,0 +1,451 @@ +package jsoniter + +import ( + "encoding/base64" + "reflect" + "strconv" + "unsafe" + + "github.com/modern-go/reflect2" +) + +const ptrSize = 32 << uintptr(^uintptr(0)>>63) + +func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + kind := typ.Kind() + switch kind { + case reflect.String: + if typeName != "string" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + switch typ.Kind() { + case reflect.String: + if typeName != "string" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +type stringCodec struct { +} + +func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*string)(ptr)) = iter.ReadString() +} + +func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteString(str) +} + +func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +type int8Codec struct { +} + +func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int8)(ptr)) = iter.ReadInt8() + } +} + +func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt8(*((*int8)(ptr))) +} + +func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int8)(ptr)) == 0 +} + +type int16Codec struct { +} + +func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int16)(ptr)) = iter.ReadInt16() + } +} + +func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt16(*((*int16)(ptr))) +} + +func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int16)(ptr)) == 0 +} + +type int32Codec struct { +} + +func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int32)(ptr)) = iter.ReadInt32() + } +} + +func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt32(*((*int32)(ptr))) +} + +func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int32)(ptr)) == 0 +} + +type int64Codec struct { +} + +func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int64)(ptr)) = iter.ReadInt64() + } +} + +func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt64(*((*int64)(ptr))) +} + +func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int64)(ptr)) == 0 +} + +type uint8Codec struct { +} + +func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint8)(ptr)) = iter.ReadUint8() + } +} + +func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint8(*((*uint8)(ptr))) +} + +func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint8)(ptr)) == 0 +} + +type uint16Codec struct { +} + +func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint16)(ptr)) = iter.ReadUint16() + } +} + +func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint16(*((*uint16)(ptr))) +} + +func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint16)(ptr)) == 0 +} + +type uint32Codec struct { +} + +func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint32)(ptr)) = iter.ReadUint32() + } +} + +func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint32(*((*uint32)(ptr))) +} + +func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint32)(ptr)) == 0 +} + +type uint64Codec struct { +} + +func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint64)(ptr)) = iter.ReadUint64() + } +} + +func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint64(*((*uint64)(ptr))) +} + +func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint64)(ptr)) == 0 +} + +type float32Codec struct { +} + +func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float32)(ptr)) = iter.ReadFloat32() + } +} + +func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32(*((*float32)(ptr))) +} + +func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type float64Codec struct { +} + +func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float64)(ptr)) = iter.ReadFloat64() + } +} + +func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64(*((*float64)(ptr))) +} + +func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +type boolCodec struct { +} + +func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*bool)(ptr)) = iter.ReadBool() + } +} + +func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteBool(*((*bool)(ptr))) +} + +func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { + return !(*((*bool)(ptr))) +} + +type base64Codec struct { + sliceType *reflect2.UnsafeSliceType + sliceDecoder ValDecoder +} + +func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + codec.sliceType.UnsafeSetNil(ptr) + return + } + switch iter.WhatIsNext() { + case StringValue: + src := iter.ReadString() + dst, err := base64.StdEncoding.DecodeString(src) + if err != nil { + iter.ReportError("decode base64", err.Error()) + } else { + codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst)) + } + case ArrayValue: + codec.sliceDecoder.Decode(ptr, iter) + default: + iter.ReportError("base64Codec", "invalid input") + } +} + +func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + src := *((*[]byte)(ptr)) + if len(src) == 0 { + stream.WriteNil() + return + } + encoding := base64.StdEncoding + stream.writeByte('"') + size := encoding.EncodedLen(len(src)) + buf := make([]byte, size) + encoding.Encode(buf, src) + stream.buf = append(stream.buf, buf...) + stream.writeByte('"') +} + +func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*[]byte)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go new file mode 100644 index 00000000..43ec71d6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_optional.go @@ -0,0 +1,133 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "reflect" + "unsafe" +) + +func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + decoder := decoderOfType(ctx, elemType) + if ctx.prefix == "" && elemType.Kind() == reflect.Ptr { + return &dereferenceDecoder{elemType, decoder} + } + return &OptionalDecoder{elemType, decoder} +} + +func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elemEncoder := encoderOfType(ctx, elemType) + encoder := &OptionalEncoder{elemEncoder} + return encoder +} + +type OptionalDecoder struct { + ValueType reflect2.Type + ValueDecoder ValDecoder +} + +func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + *((*unsafe.Pointer)(ptr)) = nil + } else { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.ValueType.UnsafeNew() + decoder.ValueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } + } +} + +type dereferenceDecoder struct { + // only to deference a pointer + valueType reflect2.Type + valueDecoder ValDecoder +} + +func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.valueType.UnsafeNew() + decoder.valueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } +} + +type OptionalEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*unsafe.Pointer)(ptr)) == nil +} + +type dereferenceEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + dePtr := *((*unsafe.Pointer)(ptr)) + if dePtr == nil { + return true + } + return encoder.ValueEncoder.IsEmpty(dePtr) +} + +func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + deReferenced := *((*unsafe.Pointer)(ptr)) + if deReferenced == nil { + return true + } + isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := unsafe.Pointer(deReferenced) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type referenceEncoder struct { + encoder ValEncoder +} + +func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +type referenceDecoder struct { + decoder ValDecoder +} + +func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(unsafe.Pointer(&ptr), iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go new file mode 100644 index 00000000..9441d79d --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_slice.go @@ -0,0 +1,99 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceDecoder{sliceType, decoder} +} + +func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceEncoder{sliceType, encoder} +} + +type sliceEncoder struct { + sliceType *reflect2.UnsafeSliceType + elemEncoder ValEncoder +} + +func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if encoder.sliceType.UnsafeIsNil(ptr) { + stream.WriteNil() + return + } + length := encoder.sliceType.UnsafeLengthOf(ptr) + if length == 0 { + stream.WriteEmptyArray() + return + } + stream.WriteArrayStart() + encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream) + for i := 1; i < length; i++ { + stream.WriteMore() + elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error()) + } +} + +func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.sliceType.UnsafeLengthOf(ptr) == 0 +} + +type sliceDecoder struct { + sliceType *reflect2.UnsafeSliceType + elemDecoder ValDecoder +} + +func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error()) + } +} + +func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + sliceType := decoder.sliceType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + sliceType.UnsafeSetNil(ptr) + return + } + if c != '[' { + iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0)) + return + } + iter.unreadByte() + sliceType.UnsafeGrow(ptr, 1) + elemPtr := sliceType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + idx := length + length += 1 + sliceType.UnsafeGrow(ptr, length) + elemPtr = sliceType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode slice", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go new file mode 100644 index 00000000..355d2d11 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go @@ -0,0 +1,1048 @@ +package jsoniter + +import ( + "fmt" + "io" + "strings" + "unsafe" + + "github.com/modern-go/reflect2" +) + +func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { + bindings := map[string]*Binding{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, fromName := range binding.FromNames { + old := bindings[fromName] + if old == nil { + bindings[fromName] = binding + continue + } + ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) + if ignoreOld { + delete(bindings, fromName) + } + if !ignoreNew { + bindings[fromName] = binding + } + } + } + fields := map[string]*structFieldDecoder{} + for k, binding := range bindings { + fields[k] = binding.Decoder.(*structFieldDecoder) + } + + if !ctx.caseSensitive() { + for k, binding := range bindings { + if _, found := fields[strings.ToLower(k)]; !found { + fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) + } + } + } + + return createStructDecoder(ctx, typ, fields) +} + +func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { + if ctx.disallowUnknownFields { + return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} + } + knownHash := map[int64]struct{}{ + 0: {}, + } + + switch len(fields) { + case 0: + return &skipObjectDecoder{typ} + case 1: + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} + } + case 2: + var fieldHash1 int64 + var fieldHash2 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldHash1 == 0 { + fieldHash1 = fieldHash + fieldDecoder1 = fieldDecoder + } else { + fieldHash2 = fieldHash + fieldDecoder2 = fieldDecoder + } + } + return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} + case 3: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } + } + return &threeFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3} + case 4: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } + } + return &fourFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4} + case 5: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } + } + return &fiveFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5} + case 6: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } + } + return &sixFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6} + case 7: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } + } + return &sevenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7} + case 8: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } + } + return &eightFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8} + case 9: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } + } + return &nineFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9} + case 10: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldName10 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + var fieldDecoder10 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else if fieldName9 == 0 { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } else { + fieldName10 = fieldHash + fieldDecoder10 = fieldDecoder + } + } + return &tenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9, + fieldName10, fieldDecoder10} + } + return &generalStructDecoder{typ, fields, false} +} + +type generalStructDecoder struct { + typ reflect2.Type + fields map[string]*structFieldDecoder + disallowUnknownFields bool +} + +func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + var c byte + for c = ','; c == ','; c = iter.nextToken() { + decoder.decodeOneField(ptr, iter) + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + if c != '}' { + iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) + } +} + +func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { + var field string + var fieldDecoder *structFieldDecoder + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes := iter.ReadStringAsSlice() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } else { + field = iter.ReadString() + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } + if fieldDecoder == nil { + msg := "found unknown field: " + field + if decoder.disallowUnknownFields { + iter.ReportError("ReadObject", msg) + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + iter.Skip() + return + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + fieldDecoder.Decode(ptr, iter) +} + +type skipObjectDecoder struct { + typ reflect2.Type +} + +func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valueType := iter.WhatIsNext() + if valueType != ObjectValue && valueType != NilValue { + iter.ReportError("skipObjectDecoder", "expect object or null") + return + } + iter.Skip() +} + +type oneFieldStructDecoder struct { + typ reflect2.Type + fieldHash int64 + fieldDecoder *structFieldDecoder +} + +func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + if iter.readFieldHash() == decoder.fieldHash { + decoder.fieldDecoder.Decode(ptr, iter) + } else { + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type twoFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder +} + +func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type threeFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder +} + +func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type fourFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder +} + +func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type fiveFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder +} + +func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type sixFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder +} + +func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type sevenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder +} + +func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type eightFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder +} + +func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type nineFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder +} + +func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type tenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder + fieldHash10 int64 + fieldDecoder10 *structFieldDecoder +} + +func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + case decoder.fieldHash10: + decoder.fieldDecoder10.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type structFieldDecoder struct { + field reflect2.StructField + fieldDecoder ValDecoder +} + +func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + fieldPtr := decoder.field.UnsafeGet(ptr) + decoder.fieldDecoder.Decode(fieldPtr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error()) + } +} + +type stringModeStringDecoder struct { + elemDecoder ValDecoder + cfg *frozenConfig +} + +func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.elemDecoder.Decode(ptr, iter) + str := *((*string)(ptr)) + tempIter := decoder.cfg.BorrowIterator([]byte(str)) + defer decoder.cfg.ReturnIterator(tempIter) + *((*string)(ptr)) = tempIter.ReadString() +} + +type stringModeNumberDecoder struct { + elemDecoder ValDecoder +} + +func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } + decoder.elemDecoder.Decode(ptr, iter) + if iter.Error != nil { + return + } + c = iter.readByte() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go new file mode 100644 index 00000000..d0759cf6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go @@ -0,0 +1,210 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "unsafe" +) + +func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { + type bindingTo struct { + binding *Binding + toName string + ignored bool + } + orderedBindings := []*bindingTo{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, toName := range binding.ToNames { + new := &bindingTo{ + binding: binding, + toName: toName, + } + for _, old := range orderedBindings { + if old.toName != toName { + continue + } + old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) + } + orderedBindings = append(orderedBindings, new) + } + } + if len(orderedBindings) == 0 { + return &emptyStructEncoder{} + } + finalOrderedFields := []structFieldTo{} + for _, bindingTo := range orderedBindings { + if !bindingTo.ignored { + finalOrderedFields = append(finalOrderedFields, structFieldTo{ + encoder: bindingTo.binding.Encoder.(*structFieldEncoder), + toName: bindingTo.toName, + }) + } + } + return &structEncoder{typ, finalOrderedFields} +} + +func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { + encoder := createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return &structEncoder{typ: typ} + case reflect.Array: + return &arrayEncoder{} + case reflect.Slice: + return &sliceEncoder{} + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return &OptionalEncoder{} + default: + return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} + } +} + +func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { + newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" + oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" + if newTagged { + if oldTagged { + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } else { + return true, false + } + } else { + if oldTagged { + return true, false + } + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } +} + +type structFieldEncoder struct { + field reflect2.StructField + fieldEncoder ValEncoder + omitempty bool +} + +func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + fieldPtr := encoder.field.UnsafeGet(ptr) + encoder.fieldEncoder.Encode(fieldPtr, stream) + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) + } +} + +func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { + fieldPtr := encoder.field.UnsafeGet(ptr) + return encoder.fieldEncoder.IsEmpty(fieldPtr) +} + +func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := encoder.field.UnsafeGet(ptr) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type IsEmbeddedPtrNil interface { + IsEmbeddedPtrNil(ptr unsafe.Pointer) bool +} + +type structEncoder struct { + typ reflect2.Type + fields []structFieldTo +} + +type structFieldTo struct { + encoder *structFieldEncoder + toName string +} + +func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + isNotFirst := false + for _, field := range encoder.fields { + if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { + continue + } + if field.encoder.IsEmbeddedPtrNil(ptr) { + continue + } + if isNotFirst { + stream.WriteMore() + } + stream.WriteObjectField(field.toName) + field.encoder.Encode(ptr, stream) + isNotFirst = true + } + stream.WriteObjectEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) + } +} + +func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type emptyStructEncoder struct { +} + +func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyObject() +} + +func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type stringModeNumberEncoder struct { + elemEncoder ValEncoder +} + +func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.elemEncoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} + +type stringModeStringEncoder struct { + elemEncoder ValEncoder + cfg *frozenConfig +} + +func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + tempStream := encoder.cfg.BorrowStream(nil) + defer encoder.cfg.ReturnStream(tempStream) + encoder.elemEncoder.Encode(ptr, tempStream) + stream.WriteString(string(tempStream.Buffer())) +} + +func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/stream.go new file mode 100644 index 00000000..17662fde --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream.go @@ -0,0 +1,211 @@ +package jsoniter + +import ( + "io" +) + +// stream is a io.Writer like object, with JSON specific write functions. +// Error is not returned as return value, but stored as Error member on this stream instance. +type Stream struct { + cfg *frozenConfig + out io.Writer + buf []byte + Error error + indention int + Attachment interface{} // open for customized encoder +} + +// NewStream create new stream instance. +// cfg can be jsoniter.ConfigDefault. +// out can be nil if write to internal buffer. +// bufSize is the initial size for the internal buffer in bytes. +func NewStream(cfg API, out io.Writer, bufSize int) *Stream { + return &Stream{ + cfg: cfg.(*frozenConfig), + out: out, + buf: make([]byte, 0, bufSize), + Error: nil, + indention: 0, + } +} + +// Pool returns a pool can provide more stream with same configuration +func (stream *Stream) Pool() StreamPool { + return stream.cfg +} + +// Reset reuse this stream instance by assign a new writer +func (stream *Stream) Reset(out io.Writer) { + stream.out = out + stream.buf = stream.buf[:0] +} + +// Available returns how many bytes are unused in the buffer. +func (stream *Stream) Available() int { + return cap(stream.buf) - len(stream.buf) +} + +// Buffered returns the number of bytes that have been written into the current buffer. +func (stream *Stream) Buffered() int { + return len(stream.buf) +} + +// Buffer if writer is nil, use this method to take the result +func (stream *Stream) Buffer() []byte { + return stream.buf +} + +// SetBuffer allows to append to the internal buffer directly +func (stream *Stream) SetBuffer(buf []byte) { + stream.buf = buf +} + +// Write writes the contents of p into the buffer. +// It returns the number of bytes written. +// If nn < len(p), it also returns an error explaining +// why the write is short. +func (stream *Stream) Write(p []byte) (nn int, err error) { + stream.buf = append(stream.buf, p...) + if stream.out != nil { + nn, err = stream.out.Write(stream.buf) + stream.buf = stream.buf[nn:] + return + } + return len(p), nil +} + +// WriteByte writes a single byte. +func (stream *Stream) writeByte(c byte) { + stream.buf = append(stream.buf, c) +} + +func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { + stream.buf = append(stream.buf, c1, c2) +} + +func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { + stream.buf = append(stream.buf, c1, c2, c3) +} + +func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4) +} + +func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4, c5) +} + +// Flush writes any buffered data to the underlying io.Writer. +func (stream *Stream) Flush() error { + if stream.out == nil { + return nil + } + if stream.Error != nil { + return stream.Error + } + n, err := stream.out.Write(stream.buf) + if err != nil { + if stream.Error == nil { + stream.Error = err + } + return err + } + stream.buf = stream.buf[n:] + return nil +} + +// WriteRaw write string out without quotes, just like []byte +func (stream *Stream) WriteRaw(s string) { + stream.buf = append(stream.buf, s...) +} + +// WriteNil write null to stream +func (stream *Stream) WriteNil() { + stream.writeFourBytes('n', 'u', 'l', 'l') +} + +// WriteTrue write true to stream +func (stream *Stream) WriteTrue() { + stream.writeFourBytes('t', 'r', 'u', 'e') +} + +// WriteFalse write false to stream +func (stream *Stream) WriteFalse() { + stream.writeFiveBytes('f', 'a', 'l', 's', 'e') +} + +// WriteBool write true or false into stream +func (stream *Stream) WriteBool(val bool) { + if val { + stream.WriteTrue() + } else { + stream.WriteFalse() + } +} + +// WriteObjectStart write { with possible indention +func (stream *Stream) WriteObjectStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('{') + stream.writeIndention(0) +} + +// WriteObjectField write "field": with possible indention +func (stream *Stream) WriteObjectField(field string) { + stream.WriteString(field) + if stream.indention > 0 { + stream.writeTwoBytes(':', ' ') + } else { + stream.writeByte(':') + } +} + +// WriteObjectEnd write } with possible indention +func (stream *Stream) WriteObjectEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte('}') +} + +// WriteEmptyObject write {} +func (stream *Stream) WriteEmptyObject() { + stream.writeByte('{') + stream.writeByte('}') +} + +// WriteMore write , with possible indention +func (stream *Stream) WriteMore() { + stream.writeByte(',') + stream.writeIndention(0) + stream.Flush() +} + +// WriteArrayStart write [ with possible indention +func (stream *Stream) WriteArrayStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('[') + stream.writeIndention(0) +} + +// WriteEmptyArray write [] +func (stream *Stream) WriteEmptyArray() { + stream.writeTwoBytes('[', ']') +} + +// WriteArrayEnd write ] with possible indention +func (stream *Stream) WriteArrayEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte(']') +} + +func (stream *Stream) writeIndention(delta int) { + if stream.indention == 0 { + return + } + stream.writeByte('\n') + toWrite := stream.indention - delta + for i := 0; i < toWrite; i++ { + stream.buf = append(stream.buf, ' ') + } +} diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go new file mode 100644 index 00000000..f318d2c5 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_float.go @@ -0,0 +1,94 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var pow10 []uint64 + +func init() { + pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} +} + +// WriteFloat32 write float32 to stream +func (stream *Stream) WriteFloat32(val float32) { + abs := math.Abs(float64(val)) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if float32(abs) < 1e-6 || float32(abs) >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) +} + +// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat32Lossy(val float32) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat32(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(float64(val)*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} + +// WriteFloat64 write float64 to stream +func (stream *Stream) WriteFloat64(val float64) { + abs := math.Abs(val) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) +} + +// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat64Lossy(val float64) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat64(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(val*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go new file mode 100644 index 00000000..d1059ee4 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_int.go @@ -0,0 +1,190 @@ +package jsoniter + +var digits []uint32 + +func init() { + digits = make([]uint32, 1000) + for i := uint32(0); i < 1000; i++ { + digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0' + if i < 10 { + digits[i] += 2 << 24 + } else if i < 100 { + digits[i] += 1 << 24 + } + } +} + +func writeFirstBuf(space []byte, v uint32) []byte { + start := v >> 24 + if start == 0 { + space = append(space, byte(v>>16), byte(v>>8)) + } else if start == 1 { + space = append(space, byte(v>>8)) + } + space = append(space, byte(v)) + return space +} + +func writeBuf(buf []byte, v uint32) []byte { + return append(buf, byte(v>>16), byte(v>>8), byte(v)) +} + +// WriteUint8 write uint8 to stream +func (stream *Stream) WriteUint8(val uint8) { + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteInt8 write int8 to stream +func (stream *Stream) WriteInt8(nval int8) { + var val uint8 + if nval < 0 { + val = uint8(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint8(nval) + } + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteUint16 write uint16 to stream +func (stream *Stream) WriteUint16(val uint16) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return +} + +// WriteInt16 write int16 to stream +func (stream *Stream) WriteInt16(nval int16) { + var val uint16 + if nval < 0 { + val = uint16(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint16(nval) + } + stream.WriteUint16(val) +} + +// WriteUint32 write uint32 to stream +func (stream *Stream) WriteUint32(val uint32) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + } else { + r3 := q2 - q3*1000 + stream.buf = append(stream.buf, byte(q3+'0')) + stream.buf = writeBuf(stream.buf, digits[r3]) + } + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt32 write int32 to stream +func (stream *Stream) WriteInt32(nval int32) { + var val uint32 + if nval < 0 { + val = uint32(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint32(nval) + } + stream.WriteUint32(val) +} + +// WriteUint64 write uint64 to stream +func (stream *Stream) WriteUint64(val uint64) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r3 := q2 - q3*1000 + q4 := q3 / 1000 + if q4 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q3]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r4 := q3 - q4*1000 + q5 := q4 / 1000 + if q5 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q4]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r5 := q4 - q5*1000 + q6 := q5 / 1000 + if q6 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q5]) + } else { + stream.buf = writeFirstBuf(stream.buf, digits[q6]) + r6 := q5 - q6*1000 + stream.buf = writeBuf(stream.buf, digits[r6]) + } + stream.buf = writeBuf(stream.buf, digits[r5]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt64 write int64 to stream +func (stream *Stream) WriteInt64(nval int64) { + var val uint64 + if nval < 0 { + val = uint64(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint64(nval) + } + stream.WriteUint64(val) +} + +// WriteInt write int to stream +func (stream *Stream) WriteInt(val int) { + stream.WriteInt64(int64(val)) +} + +// WriteUint write uint to stream +func (stream *Stream) WriteUint(val uint) { + stream.WriteUint64(uint64(val)) +} diff --git a/vendor/github.com/json-iterator/go/stream_str.go b/vendor/github.com/json-iterator/go/stream_str.go new file mode 100644 index 00000000..54c2ba0b --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_str.go @@ -0,0 +1,372 @@ +package jsoniter + +import ( + "unicode/utf8" +) + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML