tencentcloud-sdk-common 1.0.199

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 860333f84b5b6c07088a6348b3e9998f5ca736cf
4
+ data.tar.gz: d954ff249bf9164d8fd2d5938966f44377019f30
5
+ SHA512:
6
+ metadata.gz: 6d96a82ccd871524957bc4db9fa26c5471641a7e4c8690d0e29a06d1b959e8be00fc5f17e913b6fe910f458c7ed225aaac7b3a38ef5c9e1923ef61d9554905c8
7
+ data.tar.gz: 6a9917086e1bc39178c0a117c7bad59e248e172f3cd5a46b98d174891a8db535b848279a9cfbcb3cee74a429f9a682936a367b215a6f6c3c89dd54fc62d887ef
data/lib/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.199
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'uri'
5
+ require 'json'
6
+ require 'securerandom'
7
+ require 'digest'
8
+
9
+ module TencentCloud
10
+ module Common
11
+ # common client
12
+ class AbstractClient
13
+ include Log
14
+
15
+ def initialize(credential, region, api_version, api_endpoint, sdk_version, profile = nil)
16
+ raise TencentCloudSDKException.new('InvalidCredential', 'Credential is None or invalid') unless credential
17
+
18
+ @credential = credential
19
+ @region = region
20
+ @api_version = api_version
21
+ @endpoint = api_endpoint
22
+ @sdk_version = sdk_version
23
+ @profile = profile || ClientProfile.new
24
+ @request = ApiRequset.new(@profile.http_profile.scheme, endpoint, nil, @profile.http_profile.req_timeout, @profile.http_profile.proxy)
25
+ end
26
+
27
+ def send_request(action, params, options = {})
28
+ request_data = BaseRequest.new(@profile.http_profile.scheme, endpoint, @profile.http_profile.req_method, REQUEST_PATH)
29
+ build_req(action, params, request_data, options)
30
+ logger.debug("Request: [\n#{request_data.to_s}]") if @profile.debug
31
+ resp = @request.send_request(request_data)
32
+ logger.debug("Response: [\n#{resp.to_s}]") if @profile.debug
33
+ raise TencentCloudSDKException.new('ServerNetworkError', resp.data) if resp.code != '200'
34
+
35
+ resp.data
36
+ end
37
+
38
+ private
39
+
40
+ REQUEST_PATH = '/'
41
+ JSON_CONTENT = 'application/json'
42
+ MULTIPART_CONTENT = 'multipart/form-data'
43
+ FORM_URLENCODED_CONTENT = 'application/x-www-form-urlencoded'
44
+
45
+ def endpoint
46
+ @profile.http_profile.endpoint || @endpoint
47
+ end
48
+
49
+ def build_req(action, params, req, options = {})
50
+ if %w[HmacSHA1 HmacSHA256].include? @profile.sign_method
51
+ build_req_with_v1_signature(action, params, req)
52
+ elsif @profile.sign_method == 'TC3-HMAC-SHA256' || options['IsMultipart']
53
+ build_req_with_v3_signature(action, params, req, options)
54
+ else
55
+ raise TencentCloudSDKException.new('ClientError', 'Invalid signature method')
56
+ end
57
+ end
58
+
59
+ def build_req_with_v1_signature(action, params, req)
60
+ params = AbstractModel.format_params(nil, params)
61
+ params['Action'] = action
62
+ params['RequestClient'] = "SDK_RUBY_#{@sdk_version}"
63
+ params['Nonce'] = Random.rand(1..1 << 32)
64
+ params['Timestamp'] = Time.now.to_i
65
+ params['Version'] = @api_version
66
+ params['Region'] = @region
67
+ params['Token'] = @credential.token if @credential.token
68
+ params['SecretId'] = @credential.secret_id
69
+ params['SignatureMethod'] = @profile.sign_method
70
+ params['Language'] = @profile.language
71
+ params['Signature'] = Sign.sign_v1(@profile.http_profile.req_method, endpoint, req.uri,
72
+ params, @credential.secret_key, @profile.sign_method)
73
+ req.data = URI.encode_www_form(params)
74
+ req.header['Content-Type'] = FORM_URLENCODED_CONTENT
75
+ end
76
+
77
+ def build_req_with_v3_signature(action, params, req, options = {})
78
+ content_type = req.method == 'GET' ? FORM_URLENCODED_CONTENT : JSON_CONTENT
79
+ content_type = MULTIPART_CONTENT if options['IsMultipart']
80
+ timestamp = Time.now.to_i
81
+ req.header['Content-Type'] = content_type
82
+ req.header['Host'] = endpoint
83
+ req.header['X-TC-Action'] = action
84
+ req.header['X-TC-Timestamp'] = timestamp
85
+ req.header['X-TC-Version'] = @api_version
86
+ req.header['X-TC-Region'] = @region
87
+ req.header['X-TC-Language'] = @profile.language
88
+ req.header['X-TC-Token'] = @credential.token if @credential.token
89
+ req.header['X-TC-Content-SHA256'] = 'UNSIGNED-PAYLOAD' if @profile.unsigned_payload
90
+ if req.method == 'GET'
91
+ params = AbstractModel.format_params(nil, params)
92
+ req.data = URI.encode_www_form(params)
93
+ canonical_querystring = req.data
94
+ payload = ''
95
+ else
96
+ case content_type
97
+ when JSON_CONTENT
98
+ req.data = JSON.generate(params, { 'ascii_only' => true, 'space' => ' ' })
99
+ when MULTIPART_CONTENT
100
+ binparas = options['binparas'] || []
101
+ boundary = SecureRandom.hex
102
+ req.header['Content-Type'] += '; boundary=' + boundary
103
+ body = ''
104
+ params.each do |k, v|
105
+ body += "--#{boundary}\r\n"
106
+ body += "Content-Disposition: form-data; name=\"#{k}\""
107
+ if binparas.include? k
108
+ body += "; filename=\"File\"\r\n"
109
+ else
110
+ body += "\r\n"
111
+ if v.is_a?(Array) || v.is_a?(Hash)
112
+ v = JSON.generate(v, { 'ascii_only' => true, 'space' => ' ' })
113
+ body += "Content-Type: application/json\r\n"
114
+ end
115
+ end
116
+ body += "\r\n#{v}\r\n"
117
+ end
118
+ body += "--#{boundary}--\r\n" unless body.empty?
119
+ req.data = body
120
+ # req.is_multipart = options['IsMultipart']
121
+ else
122
+ raise TencentCloudSDKException.new('ContentTypeError', "Unsupported content type: #{content_type}")
123
+ end
124
+ payload = req.data
125
+ canonical_querystring = ''
126
+ end
127
+ payload = 'UNSIGNED-PAYLOAD' if @profile.unsigned_payload
128
+ hashed_payload = Digest::SHA256.hexdigest(payload)
129
+
130
+ authorization = Sign.sign_v3(content_type, endpoint, @profile.http_profile.req_method, req.uri,
131
+ canonical_querystring, hashed_payload, req.header['X-TC-Timestamp'],
132
+ @credential.secret_id, @credential.secret_key)
133
+ req.header['Authorization'] = authorization
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TencentCloud
4
+ module Common
5
+ # common credential
6
+ class Credential
7
+ attr_accessor :secret_id, :secret_key, :token
8
+
9
+ def initialize(secret_id, secret_key, token = nil)
10
+ if secret_id.nil? || secret_id.strip.empty?
11
+ raise TencentCloudSDKException.new('InvalidCredential', 'secret id should not be none or empty')
12
+ elsif secret_id.strip != secret_id
13
+ raise TencentCloudSDKException.new('InvalidCredential', 'secret id should not contain spaces')
14
+ end
15
+
16
+ @secret_id = secret_id
17
+
18
+ if secret_key.nil? || secret_key.strip.empty?
19
+ raise TencentCloudSDKException.new('InvalidCredential', 'secret id should not be none or empty')
20
+ elsif secret_key.strip != secret_key
21
+ raise TencentCloudSDKException.new('InvalidCredential', 'secret id should not contain spaces')
22
+ end
23
+
24
+ @secret_key = secret_key
25
+ @token = token
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TencentCloud
4
+ module Common
5
+ # TencentCloud exception
6
+ class TencentCloudSDKException < StandardError
7
+ attr_accessor :code, :message, :request_id
8
+
9
+ def initialize(code = nil, message = nil, request_id = nil)
10
+ @code = code
11
+ @message = message
12
+ @request_id = request_id
13
+ end
14
+
15
+ def to_s
16
+ "[TencentCloudSDKError] Code=#{@code}, Message=#{@message}, RequestId=#{@request_id}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'net/http'
5
+
6
+ module TencentCloud
7
+ module Common
8
+ # common http request class
9
+ class ApiRequset
10
+ def initialize(scheme, host, port = nil, timeout = 60, proxy = nil)
11
+ port = 443 if scheme == 'https'
12
+ if proxy.nil?
13
+ @conn = Net::HTTP.new(host, port)
14
+ else
15
+ p = URI(proxy)
16
+ @conn = Net::HTTP.new(host, port, p.host, p.port, p.user, p.pass)
17
+ end
18
+ @conn.use_ssl = scheme == 'https'
19
+ @conn.read_timeout = timeout
20
+ end
21
+
22
+ def send_request(request, keep_alive = false)
23
+ uri = URI("#{request.scheme}://#{request.host}#{request.uri}")
24
+ @conn.keep_alive_timeout = 20 if keep_alive
25
+ @conn.start do |http|
26
+ case request.method
27
+ when 'GET'
28
+ uri.query = request.data
29
+ req = Net::HTTP::Get.new uri
30
+ when 'POST'
31
+ req = Net::HTTP::Post.new uri
32
+ req.body = request.data
33
+ else
34
+ raise TencentCloudSDKException.new('ClientParamsError', 'Method only support (GET, POST)')
35
+ end
36
+ request.header.each do |k, v|
37
+ req[k] = v
38
+ end
39
+ resp = http.request req
40
+ BaseResponse.new(resp.code, resp.each_header.to_h, resp.read_body)
41
+ end
42
+ end
43
+ end
44
+
45
+ # base class of http request data
46
+ class BaseRequest
47
+ attr_accessor :scheme, :host, :method, :uri, :header, :data, :is_multipart
48
+
49
+ def initialize(scheme = '', host = '', method = '', uri = '', header = {}, data = nil)
50
+ @scheme = scheme
51
+ @host = host
52
+ @method = method
53
+ @uri = uri
54
+ @header = header
55
+ @data = data
56
+ @is_multipart = false
57
+ end
58
+
59
+ def to_s
60
+ s = "Host: #{@host}\nMethod: #{method}\nUri: #{@uri}\nHeader: \n"
61
+ @header ||= {}
62
+ @header.each do |k, v|
63
+ s += "#{k}: #{v}\n"
64
+ end
65
+ s += "Data: #{@data}\n"
66
+ end
67
+ end
68
+
69
+ # base class of http response data
70
+ class BaseResponse
71
+ attr_accessor :code, :header, :data
72
+
73
+ def initialize(code = 200, header = nil, data = "")
74
+ @code = code
75
+ @header = header
76
+ @data = data
77
+ end
78
+
79
+ def to_s
80
+ s = "Status: #{@code}\nHeader: \n"
81
+ @header ||= {}
82
+ @header.each do |k, v|
83
+ s += "#{k}: #{v}\n"
84
+ end
85
+ s += "Data: #{@data}\n"
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module TencentCloud
6
+ module Common
7
+ # common logger
8
+ module Log
9
+ def logger
10
+ @logger ||= Logger.new(STDOUT)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TencentCloud
4
+ module Common
5
+ # common model
6
+ class AbstractModel
7
+ def serialize
8
+ flat(self)
9
+ end
10
+
11
+ def self.format_params(prefix = nil, params)
12
+ d = {}
13
+ case params
14
+ when Hash
15
+ params.each do |k, v|
16
+ key = prefix ? "#{prefix}.#{k}" : k.to_s
17
+ d.update(format_params(key, v))
18
+ end
19
+ when Array
20
+ params.each_with_index do |v, i|
21
+ key = prefix ? "#{prefix}.#{i}" : i.to_s
22
+ d.update(format_params(key, v))
23
+ end
24
+ else
25
+ d[prefix] = params
26
+ end
27
+ d
28
+ end
29
+
30
+ private
31
+
32
+ def flat(obj)
33
+ case obj
34
+ when AbstractModel
35
+ params = nil
36
+ keys = obj.instance_variables
37
+ keys.each do |k|
38
+ value = obj.instance_variable_get k
39
+ key = k.to_s.split('@').at 1
40
+ next unless value
41
+
42
+ r = flat(value)
43
+ unless r.nil?
44
+ params ||= {}
45
+ params[key] = r
46
+ end
47
+ end
48
+ params
49
+ when Array
50
+ arr = nil
51
+ obj.each do |v|
52
+ r = flat(v)
53
+ unless r.nil?
54
+ arr ||= []
55
+ arr << r
56
+ end
57
+ end
58
+ arr
59
+ else
60
+ obj
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TencentCloud
4
+ module Common
5
+ # basic httpprofile
6
+ class ClientProfile
7
+ attr_accessor :http_profile, :sign_method, :language, :unsigned_payload, :debug
8
+
9
+ def initialize(sign_method = 'TC3-HMAC-SHA256', http_profile = nil,
10
+ language = 'zh-CN', debug = false)
11
+ @sign_method = sign_method
12
+ @http_profile = http_profile || HttpProfile.new
13
+ valid_language = %w[zh-CN en-US]
14
+ unless valid_language.include? language
15
+ raise TencentCloudSDKException.new('ClientError', "Language invalid, choices: #{valid_language}")
16
+ end
17
+
18
+ @language = language
19
+ @debug = debug
20
+ @unsigned_payload = false
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TencentCloud
4
+ module Common
5
+ # basic httpprofile
6
+ class HttpProfile
7
+ attr_accessor :scheme, :endpoint, :req_method, :req_timeout, :keep_alive, :proxy
8
+
9
+ def initialize(scheme = 'https', endpoint = nil, req_method = 'POST',
10
+ req_timeout = 60, keep_alive = false, proxy = nil)
11
+ @scheme = scheme
12
+ @endpoint = endpoint
13
+ @req_method = req_method
14
+ @req_timeout = req_timeout
15
+ @keep_alive = keep_alive
16
+ @proxy = proxy
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+ require 'base64'
5
+
6
+ module TencentCloud
7
+ module Common
8
+ # sign class
9
+ class Sign
10
+ class << self
11
+ def sign_v1(method, endpoint, path, data, secret_key, sign_method)
12
+ sign = method + endpoint + path + '?'
13
+ params = []
14
+ data.sort.each do |item|
15
+ params << "#{item[0]}=#{item[1]}"
16
+ end
17
+ sign += params.join('&')
18
+ case sign_method
19
+ when 'HmacSHA256'
20
+ digest = OpenSSL::Digest.new('sha256')
21
+ when 'HmacSHA1'
22
+ digest = OpenSSL::Digest.new('sha1')
23
+ else
24
+ raise TencentCloudSDKException.new('signMethod invalid', 'signMethod only support (HmacSHA1, HmacSHA256)')
25
+ end
26
+ Base64.encode64(OpenSSL::HMAC.digest(digest, secret_key, sign))
27
+ end
28
+
29
+ def sign_v3(content_type, endpoint, method, uri, query, payload, timestamp, secret_id, secret_key)
30
+ canonical_headers = "content-type:#{content_type}\nhost:#{endpoint}\n"
31
+ signed_headers = 'content-type;host'
32
+ canonical_request = [
33
+ method,
34
+ uri,
35
+ query,
36
+ canonical_headers,
37
+ signed_headers,
38
+ payload,
39
+ ].join("\n")
40
+ service = endpoint.split('.')[0]
41
+
42
+ date = Time.at(timestamp).utc.strftime('%Y-%m-%d')
43
+ credential_scope = date + '/' + service + '/' + 'tc3_request'
44
+ algorithm = 'TC3-HMAC-SHA256'
45
+ hashed_request_payload = Digest::SHA256.hexdigest(canonical_request)
46
+ string_to_sign = [
47
+ algorithm,
48
+ timestamp,
49
+ credential_scope,
50
+ hashed_request_payload,
51
+ ].join("\n")
52
+
53
+ digest = OpenSSL::Digest.new('sha256')
54
+ secret_date = OpenSSL::HMAC.digest(digest, 'TC3' + secret_key, date)
55
+ secret_service = OpenSSL::HMAC.digest(digest, secret_date, service)
56
+ secret_signing = OpenSSL::HMAC.digest(digest, secret_service, 'tc3_request')
57
+ signature = OpenSSL::HMAC.hexdigest(digest, secret_signing, string_to_sign)
58
+ "#{algorithm} Credential=#{secret_id}/#{credential_scope}, SignedHeaders=#{signed_headers}, Signature=#{signature}"
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'tencentcloud-sdk-common/exception'
4
+ require_relative 'tencentcloud-sdk-common/log'
5
+ require_relative 'tencentcloud-sdk-common/profile/client_profile'
6
+ require_relative 'tencentcloud-sdk-common/profile/http_profile'
7
+ require_relative 'tencentcloud-sdk-common/credential'
8
+ require_relative 'tencentcloud-sdk-common/models'
9
+ require_relative 'tencentcloud-sdk-common/sign'
10
+ require_relative 'tencentcloud-sdk-common/http/request'
11
+ require_relative 'tencentcloud-sdk-common/client'
12
+
13
+ module TencentCloud
14
+ # sdk common module
15
+ module Common
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tencentcloud-sdk-common
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.199
5
+ platform: ruby
6
+ authors:
7
+ - Tencent Cloud
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-11-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Tencent Cloud Ruby SDK is the official software development kit, which
14
+ allows Ruby developers to write software that makes use of Tencent Cloud service.
15
+ email:
16
+ - tencentcloudapi@tencent.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/VERSION
22
+ - lib/tencentcloud-sdk-common.rb
23
+ - lib/tencentcloud-sdk-common/client.rb
24
+ - lib/tencentcloud-sdk-common/credential.rb
25
+ - lib/tencentcloud-sdk-common/exception.rb
26
+ - lib/tencentcloud-sdk-common/http/request.rb
27
+ - lib/tencentcloud-sdk-common/log.rb
28
+ - lib/tencentcloud-sdk-common/models.rb
29
+ - lib/tencentcloud-sdk-common/profile/client_profile.rb
30
+ - lib/tencentcloud-sdk-common/profile/http_profile.rb
31
+ - lib/tencentcloud-sdk-common/sign.rb
32
+ homepage: https://github.com/TencentCloud/tencentcloud-sdk-ruby
33
+ licenses:
34
+ - Apache-2.0
35
+ metadata:
36
+ source_code_uri: https://github.com/TencentCloud/tencentcloud-sdk-ruby/tencentcloud-sdk-common
37
+ changelog_uri: https://github.com/TencentCloud/tencentcloud-sdk-ruby/blob/master/CHANGELOG.md
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 2.6.14
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: Tencent Cloud SDK for Ruby - Common
58
+ test_files: []