aspose_pdf_cloud 18.2.0 → 18.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,523 +1,475 @@
1
- =begin
2
- --------------------------------------------------------------------------------------------------------------------
3
- Copyright (c) 2018 Aspose.Pdf for Cloud
4
- Permission is hereby granted, free of charge, to any person obtaining a copy
5
- of this software and associated documentation files (the "Software"), to deal
6
- in the Software without restriction, including without limitation the rights
7
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the Software is
9
- furnished to do so, subject to the following conditions:
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18
- SOFTWARE.
19
- --------------------------------------------------------------------------------------------------------------------
20
- =end
21
-
22
- require 'date'
23
- require 'json'
24
- require 'logger'
25
- require 'tempfile'
26
- require 'typhoeus'
27
- require 'uri'
28
- require 'openssl'
29
- require 'base64'
30
- require 'rexml/document'
31
-
32
- module AsposePdfCloud
33
- class ApiClient
34
-
35
- include AsposeStorageCloud
36
-
37
- # The Configuration object holding settings to be used in the API client.
38
- attr_accessor :config
39
-
40
- # Defines the headers to be used in HTTP requests of all API calls by default.
41
- #
42
- # @return [Hash]
43
- attr_accessor :default_headers
44
-
45
- # Initializes the ApiClient
46
- # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
47
- def initialize(config = Configuration.default)
48
- @config = config
49
- @user_agent = "Swagger-Codegen/#{VERSION}/ruby"
50
- @default_headers = {
51
- 'Content-Type' => "application/json",
52
- 'User-Agent' => @user_agent
53
- }
54
- end
55
-
56
- def self.default
57
- @@default ||= ApiClient.new
58
- end
59
-
60
- # Call an API with given options.
61
- #
62
- # @return [Array<(Object, Fixnum, Hash)>] an array of 3 elements:
63
- # the data deserialized from response body (could be nil), response status code and response headers.
64
- def call_api(http_method, path, opts = {})
65
- request = build_request(http_method, path, opts)
66
- response = request.run
67
-
68
- if @config.debugging
69
- @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
70
- end
71
-
72
- unless response.success?
73
- if response.timed_out?
74
- fail ApiError.new('Connection timed out')
75
- elsif response.code == 0
76
- # Errors from libcurl will be made visible here
77
- fail ApiError.new(:code => 0,
78
- :message => response.return_message)
79
- else
80
- fail ApiError.new(:code => response.code,
81
- :response_headers => response.headers,
82
- :response_body => response.body),
83
- response.status_message
84
- end
85
- end
86
-
87
- if opts[:return_type]
88
- data = deserialize(response, opts[:return_type])
89
- else
90
- data = nil
91
- end
92
- return data, response.code, response.headers
93
- end
94
-
95
- # Builds the HTTP request
96
- #
97
- # @param [String] http_method HTTP method/verb (e.g. POST)
98
- # @param [String] path URL path (e.g. /account/new)
99
- # @option opts [Hash] :header_params Header parameters
100
- # @option opts [Hash] :query_params Query parameters
101
- # @option opts [Hash] :form_params Query parameters
102
- # @option opts [Object] :body HTTP body (JSON/XML)
103
- # @return [Typhoeus::Request] A Typhoeus Request
104
- def build_request(http_method, path, opts = {})
105
- url = build_request_url(path)
106
- http_method = http_method.to_sym.downcase
107
-
108
- header_params = @default_headers.merge(opts[:header_params] || {})
109
- query_params = {}
110
- form_params = opts[:form_params] || {}
111
-
112
- update_params_for_auth! header_params, query_params, opts[:auth_names]
113
-
114
- # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
115
- _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
116
-
117
- req_opts = {
118
- :method => http_method,
119
- :headers => header_params,
120
- :params => query_params,
121
- :params_encoding => @config.params_encoding,
122
- :timeout => @config.timeout,
123
- :ssl_verifypeer => @config.verify_ssl,
124
- :ssl_verifyhost => _verify_ssl_host,
125
- :sslcert => @config.cert_file,
126
- :sslkey => @config.key_file,
127
- :verbose => @config.debugging
128
- }
129
-
130
- # set custom cert, if provided
131
- req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
132
-
133
- if [:post, :patch, :put, :delete].include?(http_method)
134
- req_body = build_request_body(header_params, form_params, opts[:body])
135
- req_opts.update :body => req_body
136
- if @config.debugging
137
- @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
138
- end
139
- end
140
-
141
- if @config.auth_type == Configuration::AUTH_TYPE_REQUEST_SIGNATURE
142
- url = sign(url, opts[:query_params])
143
- elsif @config.auth_type == Configuration::AUTH_TYPE_O_AUTH_2
144
- # OAuth 2.0
145
- req_opts[:params] = opts[:query_params]
146
- if @config.access_token.nil?
147
- request_token
148
- end
149
- add_o_auth_token(req_opts)
150
- end
151
-
152
- request = Typhoeus::Request.new(url, req_opts)
153
- download_file(request) if opts[:return_type] == 'File'
154
- request
155
- end
156
-
157
- # Signs a URI with your appSID and Key.
158
- # * :url describes the URL to sign
159
-
160
- def sign(url, query_params)
161
-
162
- fail "Please set Aspose App key and SID first. You can get App key and App SID from https://cloud.aspose.com" if AsposeApp.app_key.nil? || AsposeApp.app_sid.nil?
163
-
164
- url = url[0..-2] if url[-1].eql? '/'
165
-
166
- unless query_params.empty?
167
- url = "#{url}?"
168
- query_params.each { |key, value|
169
- url = "#{url}#{key}=#{value}&"
170
- }
171
- url = url[0..-2]
172
- end
173
-
174
- parsed_url = URI.parse(url)
175
-
176
- url_to_sign = "#{parsed_url.scheme}://#{parsed_url.host}#{parsed_url.path}"
177
- url_to_sign += "?#{parsed_url.query}" if parsed_url.query
178
- if parsed_url.query
179
- url_to_sign += "&appSID=#{AsposeApp.app_sid}"
180
- else
181
- url_to_sign += "?appSID=#{AsposeApp.app_sid}"
182
- end
183
-
184
- # create a signature using the private key and the URL
185
- raw_signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), AsposeApp.app_key, url_to_sign)
186
-
187
- #Convert raw to encoded string
188
- signature = Base64.strict_encode64(raw_signature).tr('+/', '-_')
189
-
190
- #remove invalid character
191
- signature = signature.gsub(/[=_-]/, '=' => '', '_' => '%2f', '-' => '%2b')
192
-
193
- #Define expression
194
- pat = Regexp.new('%[0-9a-f]{2}')
195
-
196
- #Replace the portion matched to the above pattern to upper case
197
- 6.times do
198
- signature = signature.sub(pat, pat.match(signature).to_s.upcase)
199
- end
200
-
201
- # prepend the server and append the signature.
202
- url_to_sign + "&signature=#{signature}"
203
-
204
- end
205
-
206
- # Check if the given MIME is a JSON MIME.
207
- # JSON MIME examples:
208
- # application/json
209
- # application/json; charset=UTF8
210
- # APPLICATION/JSON
211
- # */*
212
- # @param [String] mime MIME
213
- # @return [Boolean] True if the MIME is application/json
214
- def json_mime?(mime)
215
- (mime == "*/*") || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
216
- end
217
-
218
- # Deserialize the response to the given return type.
219
- #
220
- # @param [Response] response HTTP response
221
- # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
222
- def deserialize(response, return_type)
223
- body = response.body
224
-
225
- # handle file downloading - return the File instance processed in request callbacks
226
- # note that response body is empty when the file is written in chunks in request on_body callback
227
- return @tempfile if return_type == 'File'
228
-
229
- return nil if body.nil? || body.empty?
230
-
231
- # return response body directly for String return type
232
- return body if return_type == 'String'
233
-
234
- # ensuring a default content type
235
- content_type = response.headers['Content-Type'] || 'application/json'
236
-
237
- fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
238
-
239
- begin
240
- data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
241
- rescue JSON::ParserError => e
242
- if %w(String Date DateTime).include?(return_type)
243
- data = body
244
- else
245
- raise e
246
- end
247
- end
248
-
249
- convert_to_type data, return_type
250
- end
251
-
252
- # Convert data to the given return type.
253
- # @param [Object] data Data to be converted
254
- # @param [String] return_type Return type
255
- # @return [Mixed] Data in a particular type
256
- def convert_to_type(data, return_type)
257
- return nil if data.nil?
258
- case return_type
259
- when 'String'
260
- data.to_s
261
- when 'Integer'
262
- data.to_i
263
- when 'Float'
264
- data.to_f
265
- when 'BOOLEAN'
266
- data == true
267
- when 'DateTime'
268
- # parse date time (expecting ISO 8601 format)
269
- DateTime.parse data
270
- when 'Date'
271
- # parse date time (expecting ISO 8601 format)
272
- Date.parse data
273
- when 'Object'
274
- # generic object (usually a Hash), return directly
275
- data
276
- when /\AArray<(.+)>\z/
277
- # e.g. Array<Pet>
278
- sub_type = $1
279
- data.map {|item| convert_to_type(item, sub_type) }
280
- when /\AHash\<String, (.+)\>\z/
281
- # e.g. Hash<String, Integer>
282
- sub_type = $1
283
- {}.tap do |hash|
284
- data.each {|k, v| hash[k] = convert_to_type(v, sub_type) }
285
- end
286
- else
287
- # models, e.g. Pet
288
- AsposePdfCloud.const_get(return_type).new.tap do |model|
289
- model.build_from_hash data
290
- end
291
- end
292
- end
293
-
294
- # Save response body into a file in (the defined) temporary folder, using the filename
295
- # from the "Content-Disposition" header if provided, otherwise a random filename.
296
- # The response body is written to the file in chunks in order to handle files which
297
- # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
298
- # process can use.
299
- #
300
- # @see Configuration#temp_folder_path
301
- def download_file(request)
302
- tempfile = nil
303
- encoding = nil
304
- request.on_headers do |response|
305
- content_disposition = response.headers['Content-Disposition']
306
- if content_disposition and content_disposition =~ /filename=/i
307
- filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
308
- prefix = sanitize_filename(filename)
309
- else
310
- prefix = 'download-'
311
- end
312
- prefix = prefix + '-' unless prefix.end_with?('-')
313
- encoding = response.body.encoding
314
- tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
315
- @tempfile = tempfile
316
- end
317
- request.on_body do |chunk|
318
- chunk.force_encoding(encoding)
319
- tempfile.write(chunk)
320
- end
321
- request.on_complete do |response|
322
- tempfile.close
323
- @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
324
- "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
325
- "will be deleted automatically with GC. It's also recommended to delete the temp file "\
326
- "explicitly with `tempfile.delete`"
327
- end
328
- end
329
-
330
- # Sanitize filename by removing path.
331
- # e.g. ../../sun.gif becomes sun.gif
332
- #
333
- # @param [String] filename the filename to be sanitized
334
- # @return [String] the sanitized filename
335
- def sanitize_filename(filename)
336
- filename.gsub(/.*[\/\\]/, '')
337
- end
338
-
339
- def build_request_url(path)
340
- # Add leading and trailing slashes to path
341
- path = "/#{path}".gsub(/\/+/, '/')
342
- URI.encode(@config.base_url + path)
343
- end
344
-
345
- # Builds the HTTP request body
346
- #
347
- # @param [Hash] header_params Header parameters
348
- # @param [Hash] form_params Query parameters
349
- # @param [Object] body HTTP body (JSON/XML)
350
- # @return [String] HTTP body data in the form of string
351
- def build_request_body(header_params, form_params, body)
352
- # http form
353
- if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
354
- header_params['Content-Type'] == 'multipart/form-data'
355
- data = {}
356
- form_params.each do |key, value|
357
- case value
358
- when File, Array, nil
359
- # let typhoeus handle File, Array and nil parameters
360
- data[key] = value
361
- else
362
- data[key] = value.to_s
363
- end
364
- end
365
- elsif body
366
- data = body.is_a?(String) ? body : body.to_json
367
- else
368
- data = nil
369
- end
370
- data
371
- end
372
-
373
- # Update hearder and query params based on authentication settings.
374
- #
375
- # @param [Hash] header_params Header parameters
376
- # @param [Hash] query_params Query parameters
377
- # @param [String] auth_names Authentication scheme name
378
- def update_params_for_auth!(header_params, query_params, auth_names)
379
- Array(auth_names).each do |auth_name|
380
- auth_setting = @config.auth_settings[auth_name]
381
- next unless auth_setting
382
- case auth_setting[:in]
383
- when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
384
- when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
385
- else fail ArgumentError, 'Authentication token must be in `query` of `header`'
386
- end
387
- end
388
- end
389
-
390
- # Sets user agent in HTTP header
391
- #
392
- # @param [String] user_agent User agent (e.g. swagger-codegen/ruby/1.0.0)
393
- def user_agent=(user_agent)
394
- @user_agent = user_agent
395
- @default_headers['User-Agent'] = @user_agent
396
- end
397
-
398
- # Return Accept header based on an array of accepts provided.
399
- # @param [Array] accepts array for Accept
400
- # @return [String] the Accept header (e.g. application/json)
401
- def select_header_accept(accepts)
402
- return nil if accepts.nil? || accepts.empty?
403
- # use JSON when present, otherwise use all of the provided
404
- json_accept = accepts.find { |s| json_mime?(s) }
405
- return json_accept || accepts.join(',')
406
- end
407
-
408
- # Return Content-Type header based on an array of content types provided.
409
- # @param [Array] content_types array for Content-Type
410
- # @return [String] the Content-Type header (e.g. application/json)
411
- def select_header_content_type(content_types)
412
- # use application/json by default
413
- return 'application/json' if content_types.nil? || content_types.empty?
414
- # use JSON when present, otherwise use the first one
415
- json_content_type = content_types.find { |s| json_mime?(s) }
416
- return json_content_type || content_types.first
417
- end
418
-
419
- # Convert object (array, hash, object, etc) to JSON string.
420
- # @param [Object] model object to be converted into JSON string
421
- # @return [String] JSON string representation of the object
422
- def object_to_http_body(model)
423
- return model if model.nil? || model.is_a?(String)
424
- local_body = nil
425
- if model.is_a?(Array)
426
- local_body = model.map{|m| object_to_hash(m) }
427
- else
428
- local_body = object_to_hash(model)
429
- end
430
- local_body.to_json
431
- end
432
-
433
- # Convert object(non-array) to hash.
434
- # @param [Object] obj object to be converted into JSON string
435
- # @return [String] JSON string representation of the object
436
- def object_to_hash(obj)
437
- if obj.respond_to?(:to_hash)
438
- obj.to_hash
439
- else
440
- obj
441
- end
442
- end
443
-
444
- # Build parameter value according to the given collection format.
445
- # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
446
- def build_collection_param(param, collection_format)
447
- case collection_format
448
- when :csv
449
- param.join(',')
450
- when :ssv
451
- param.join(' ')
452
- when :tsv
453
- param.join("\t")
454
- when :pipes
455
- param.join('|')
456
- when :multi
457
- # return the array directly as typhoeus will handle it as expected
458
- param
459
- else
460
- fail "unknown collection format: #{collection_format.inspect}"
461
- end
462
- end
463
-
464
- # Request access and refresh tokens
465
- def request_token
466
- # resource path
467
- local_var_path = "/oauth2/token"
468
-
469
- # query parameters
470
- query_params = {}
471
-
472
- # header parameters
473
- header_params = {}
474
- # HTTP header 'Content-Type'
475
- header_params['Content-Type'] = select_header_content_type(['application/x-www-form-urlencoded'])
476
-
477
- # form parameters
478
- form_params = {}
479
- form_params["grant_type"] = 'client_credentials'
480
- form_params["client_id"] = AsposeApp.app_sid
481
- form_params["client_secret"] = AsposeApp.app_key
482
-
483
-
484
- url = build_request_url(local_var_path).gsub(@config.base_path, '')
485
- http_method = :POST.to_sym.downcase
486
-
487
-
488
- # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
489
- _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
490
-
491
- req_opts = {
492
- :method => http_method,
493
- :headers => header_params,
494
- :params => query_params,
495
- :params_encoding => @config.params_encoding,
496
- :timeout => @config.timeout,
497
- :ssl_verifypeer => @config.verify_ssl,
498
- :ssl_verifyhost => _verify_ssl_host,
499
- :sslcert => @config.cert_file,
500
- :sslkey => @config.key_file,
501
- :verbose => @config.debugging,
502
- :body => form_params
503
- }
504
-
505
- # set custom cert, if provided
506
- req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
507
-
508
- request = Typhoeus::Request.new(url, req_opts)
509
- response = request.run
510
-
511
- data = JSON.parse("[#{response.body}]", :symbolize_names => true)[0]
512
-
513
- @config.access_token = data[:access_token]
514
- @config.refresh_token = data[:refresh_token]
515
- end
516
-
517
- # Adds OAuth2.0 token
518
- def add_o_auth_token(req_opts)
519
- req_opts[:headers][:Authorization] = "Bearer " + @config.access_token
520
- end
521
-
522
- end
523
- end
1
+ =begin
2
+ --------------------------------------------------------------------------------------------------------------------
3
+ Copyright (c) 2018 Aspose.Pdf for Cloud
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18
+ SOFTWARE.
19
+ --------------------------------------------------------------------------------------------------------------------
20
+ =end
21
+
22
+ require 'date'
23
+ require 'json'
24
+ require 'logger'
25
+ require 'tempfile'
26
+ require 'uri'
27
+ require 'typhoeus'
28
+ require 'faraday'
29
+ require_relative 'version'
30
+ require_relative 'api_error'
31
+
32
+ module AsposePdfCloud
33
+ #
34
+ # api client is mainly responsible for making the HTTP call to the API backend.
35
+ #
36
+ class ApiClient
37
+
38
+ include AsposeStorageCloud
39
+ # The Configuration object holding settings to be used in the API client.
40
+ attr_accessor :config
41
+
42
+ # Defines the headers to be used in HTTP requests of all API calls by default.
43
+ #
44
+ # @return [Hash]
45
+ attr_accessor :default_headers
46
+
47
+ # Initializes the ApiClient
48
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
49
+ def initialize(config = Configuration.default)
50
+ @config = config
51
+ @default_headers = {
52
+ 'Content-Type' => "application/json",
53
+ 'x-aspose-client' => "ruby sdk",
54
+ 'x-aspose-version' => "#{ AsposePdfCloud::VERSION }"
55
+ }
56
+ end
57
+
58
+ def self.default
59
+ @@default ||= ApiClient.new
60
+ end
61
+
62
+ # Call an API with given options.
63
+ #
64
+ # @return [Array<(Object, Fixnum, Hash)>] an array of 3 elements:
65
+ # the data deserialized from response body (could be nil), response status code and response headers.
66
+ def call_api(http_method, path, opts = {})
67
+ response = build_request(http_method, path, opts)
68
+ download_file response if opts[:return_type] == 'File'
69
+ if @config.debugging
70
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
71
+ end
72
+
73
+ unless response.success?
74
+ if response.status == 0
75
+ # Errors from libcurl will be made visible here
76
+ fail ApiError.new(:code => 0,
77
+ :message => response.reason_phrase)
78
+ else
79
+ fail ApiError.new(:code => response.status,
80
+ :response_headers => response.headers,
81
+ :response_body => response.body),
82
+ response.reason_phrase
83
+ end
84
+ end
85
+
86
+ if opts[:return_type]
87
+ data = deserialize(response, opts[:return_type])
88
+ else
89
+ data = nil
90
+ end
91
+ [data, response.status, response.headers]
92
+ end
93
+
94
+ # Builds the HTTP request
95
+ #
96
+ # @param [String] http_method HTTP method/verb (e.g. POST)
97
+ # @param [String] path URL path (e.g. /account/new)
98
+ # @option opts [Hash] :header_params Header parameters
99
+ # @option opts [Hash] :query_params Query parameters
100
+ # @option opts [Hash] :form_params Query parameters
101
+ # @option opts [Object] :body HTTP body (JSON/XML)
102
+ # @return [Faraday::Response] A Faraday Response
103
+ def build_request(http_method, path, opts = {})
104
+ url = build_request_url(path)
105
+ http_method = http_method.to_sym.downcase
106
+
107
+ header_params = @default_headers.merge(opts[:header_params] || {})
108
+ query_params = opts[:query_params] || {}
109
+ form_params = opts[:form_params] || {}
110
+ body = opts[:body] || {}
111
+
112
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
113
+
114
+ req_opts = {
115
+ :method => http_method,
116
+ :headers => header_params,
117
+ :params => query_params,
118
+ :body => body
119
+ }
120
+
121
+ if [:post, :patch, :put, :delete].include?(http_method)
122
+ req_body = build_request_body(header_params, form_params, opts[:body])
123
+ req_opts.update :body => req_body
124
+ if @config.debugging
125
+ @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
126
+ end
127
+ end
128
+
129
+ # OAuth 2.0
130
+ req_opts[:params] = opts[:query_params]
131
+ if @config.access_token.nil?
132
+ request_token
133
+ end
134
+ add_o_auth_token(req_opts)
135
+
136
+
137
+ conn = Faraday.new url, {:params => query_params, :headers => header_params} do |f|
138
+ f.request :multipart
139
+ f.request :url_encoded
140
+ f.adapter Faraday.default_adapter
141
+ end
142
+
143
+ if req_opts[:body] == {}
144
+ req_opts[:body] = nil
145
+ end
146
+
147
+ case http_method
148
+ when :post
149
+ return conn.post url, req_opts[:body]
150
+ when :put
151
+ return conn.put url, req_opts[:body]
152
+ when :get
153
+ return conn.get url, req_opts[:body]
154
+ else
155
+ return conn.delete url do |c|
156
+ c.body = req_opts[:body]
157
+ end
158
+ end
159
+ end
160
+
161
+ # Check if the given MIME is a JSON MIME.
162
+ # JSON MIME examples:
163
+ # application/json
164
+ # application/json; charset=UTF8
165
+ # APPLICATION/JSON
166
+ # */*
167
+ # @param [String] mime MIME
168
+ # @return [Boolean] True if the MIME is application/json
169
+ def json_mime?(mime)
170
+ (mime == "*/*") || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
171
+ end
172
+
173
+ # Deserialize the response to the given return type.
174
+ #
175
+ # @param [Response] response HTTP response
176
+ # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
177
+ def deserialize(response, return_type)
178
+ body = response.body
179
+
180
+ # handle file downloading - return the File instance processed in request callbacks
181
+ # note that response body is empty when the file is written in chunks in request on_body callback
182
+ return @tempfile if return_type == 'File'
183
+
184
+ return nil if body.nil? || body.empty?
185
+
186
+ # return response body directly for String return type
187
+ return body if return_type == 'String'
188
+
189
+ # ensuring a default content type
190
+ content_type = response.headers['Content-Type'] || 'application/json'
191
+
192
+ raise "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
193
+
194
+ begin
195
+ data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
196
+ rescue JSON::ParserError => e
197
+ if %w(String Date DateTime).include?(return_type)
198
+ data = body
199
+ else
200
+ raise e
201
+ end
202
+ end
203
+
204
+ convert_to_type data, return_type
205
+ end
206
+
207
+ # Convert data to the given return type.
208
+ # @param [Object] data Data to be converted
209
+ # @param [String] return_type Return type
210
+ # @return [Mixed] Data in a particular type
211
+ def convert_to_type(data, return_type)
212
+ return nil if data.nil?
213
+ case return_type
214
+ when 'String'
215
+ data.to_s
216
+ when 'Integer'
217
+ data.to_i
218
+ when 'Float'
219
+ data.to_f
220
+ when 'BOOLEAN'
221
+ data == true
222
+ when 'DateTime'
223
+ # parse date time (expecting ISO 8601 format)
224
+ DateTime.parse data
225
+ when 'Date'
226
+ # parse date time (expecting ISO 8601 format)
227
+ Date.parse data
228
+ when 'Object'
229
+ # generic object (usually a Hash), return directly
230
+ data
231
+ when /\AArray<(.+)>\z/
232
+ # e.g. Array<Pet>
233
+ sub_type = $1
234
+ data.map {|item| convert_to_type(item, sub_type) }
235
+ when /\AHash\<String, (.+)\>\z/
236
+ # e.g. Hash<String, Integer>
237
+ sub_type = $1
238
+ {}.tap do |hash|
239
+ data.each {|k, v| hash[k] = convert_to_type(v, sub_type) }
240
+ end
241
+ else
242
+ # models, e.g. Pet
243
+ AsposePdfCloud.const_get(return_type).new.tap do |model|
244
+ model.build_from_hash data
245
+ end
246
+ end
247
+ end
248
+
249
+ # Save response body into a file in (the defined) temporary folder, using the filename
250
+ # from the "Content-Disposition" header if provided, otherwise a random filename.
251
+ # The response body is written to the file in chunks in order to handle files which
252
+ # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
253
+ # process can use.
254
+ #
255
+ # @see Configuration#temp_folder_path
256
+ def download_file(response)
257
+ tempfile = nil
258
+ encoding = nil
259
+ content_disposition = response.headers['Content-Disposition']
260
+ if content_disposition and content_disposition =~ /filename=/i
261
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
262
+ prefix = sanitize_filename(filename)
263
+ else
264
+ prefix = 'download-'
265
+ end
266
+ prefix = prefix + '-' unless prefix.end_with?('-')
267
+ encoding = response.body.encoding
268
+ tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
269
+ @tempfile = tempfile
270
+ tempfile.write(response.body)
271
+ response.on_complete do |resp|
272
+ tempfile.close
273
+ @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
274
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
275
+ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
276
+ "explicitly with `tempfile.delete`"
277
+ end
278
+ end
279
+
280
+ # Sanitize filename by removing path.
281
+ # e.g. ../../sun.gif becomes sun.gif
282
+ #
283
+ # @param [String] filename the filename to be sanitized
284
+ # @return [String] the sanitized filename
285
+ def sanitize_filename(filename)
286
+ filename.gsub(/.*[\/\\]/, '')
287
+ end
288
+
289
+ def build_request_url(path)
290
+ # Add leading and trailing slashes to path
291
+ path = "/#{path}".gsub(/\/+/, '/')
292
+ URI.encode(@config.base_url + path)
293
+ end
294
+
295
+ # Builds the HTTP request body
296
+ #
297
+ # @param [Hash] header_params Header parameters
298
+ # @param [Hash] form_params Query parameters
299
+ # @param [Object] body HTTP body (JSON/XML)
300
+ # @return [String] HTTP body data in the form of string
301
+ def build_request_body(header_params, form_params, body)
302
+ # http form
303
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
304
+ header_params['Content-Type'] == 'multipart/form-data'
305
+ data = {}
306
+ form_params.each do |key, value|
307
+ case value
308
+ when ::File
309
+ data[key] = Faraday::UploadIO.new(value.path, MimeMagic.by_magic(value).to_s, key)
310
+ when ::Array, nil
311
+ data[key] = value
312
+ else
313
+ data[key] = value.to_s
314
+ end
315
+ end
316
+ elsif body
317
+ data = body.is_a?(String) ? body : body.to_json
318
+ else
319
+ data = nil
320
+ end
321
+ data
322
+ end
323
+
324
+ # Update hearder and query params based on authentication settings.
325
+ #
326
+ # @param [Hash] header_params Header parameters
327
+ # @param [Hash] query_params Query parameters
328
+ # @param [String] auth_names Authentication scheme name
329
+ def update_params_for_auth!(header_params, query_params, auth_names)
330
+ Array(auth_names).each do |auth_name|
331
+ auth_setting = @config.auth_settings[auth_name]
332
+ next unless auth_setting
333
+ case auth_setting[:in]
334
+ when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
335
+ when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
336
+ else raise ArgumentError, 'Authentication token must be in `query` of `header`'
337
+ end
338
+ end
339
+ end
340
+
341
+ # Sets user agent in HTTP header
342
+ #
343
+ # @param [String] user_agent User agent (e.g. swagger-codegen/ruby/1.0.0)
344
+ def user_agent=(user_agent)
345
+ @user_agent = user_agent
346
+ @default_headers['User-Agent'] = @user_agent
347
+ end
348
+
349
+ # Return Accept header based on an array of accepts provided.
350
+ # @param [Array] accepts array for Accept
351
+ # @return [String] the Accept header (e.g. application/json)
352
+ def select_header_accept(accepts)
353
+ return nil if accepts.nil? || accepts.empty?
354
+ # use JSON when present, otherwise use all of the provided
355
+ json_accept = accepts.find { |s| json_mime?(s) }
356
+ return json_accept || accepts.join(',')
357
+ end
358
+
359
+ # Return Content-Type header based on an array of content types provided.
360
+ # @param [Array] content_types array for Content-Type
361
+ # @return [String] the Content-Type header (e.g. application/json)
362
+ def select_header_content_type(content_types)
363
+ # use application/json by default
364
+ return 'application/json' if content_types.nil? || content_types.empty?
365
+ # use JSON when present, otherwise use the first one
366
+ json_content_type = content_types.find { |s| json_mime?(s) }
367
+ return json_content_type || content_types.first
368
+ end
369
+
370
+ # Convert object (array, hash, object, etc) to JSON string.
371
+ # @param [Object] model object to be converted into JSON string
372
+ # @return [String] JSON string representation of the object
373
+ def object_to_http_body(model)
374
+ return '"' + model + '"' if model.is_a?(String)
375
+ return model if model.nil?
376
+ local_body = nil
377
+ if model.is_a?(Array)
378
+ local_body = model.map{|m| object_to_hash(m) }
379
+ else
380
+ local_body = object_to_hash(model)
381
+ end
382
+ local_body.to_json
383
+ end
384
+
385
+ # Convert object(non-array) to hash.
386
+ # @param [Object] obj object to be converted into JSON string
387
+ # @return [String] JSON string representation of the object
388
+ def object_to_hash(obj)
389
+ if obj.respond_to?(:to_hash)
390
+ obj.to_hash
391
+ else
392
+ obj
393
+ end
394
+ end
395
+
396
+ # Build parameter value according to the given collection format.
397
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
398
+ def build_collection_param(param, collection_format)
399
+ case collection_format
400
+ when :csv
401
+ param.join(',')
402
+ when :ssv
403
+ param.join(' ')
404
+ when :tsv
405
+ param.join("\t")
406
+ when :pipes
407
+ param.join('|')
408
+ when :multi
409
+ # return the array directly as faraday will handle it as expected
410
+ param
411
+ else
412
+ fail "unknown collection format: #{collection_format.inspect}"
413
+ end
414
+ end
415
+ # Request access and refresh tokens
416
+ def request_token
417
+ # resource path
418
+ local_var_path = "/oauth2/token"
419
+
420
+ # query parameters
421
+ query_params = {}
422
+
423
+ # header parameters
424
+ header_params = {}
425
+ # HTTP header 'Content-Type'
426
+ header_params['Content-Type'] = select_header_content_type(['application/x-www-form-urlencoded'])
427
+
428
+ # form parameters
429
+ form_params = {}
430
+ form_params["grant_type"] = 'client_credentials'
431
+ form_params["client_id"] = AsposeApp.app_sid
432
+ form_params["client_secret"] = AsposeApp.app_key
433
+
434
+
435
+ url = build_request_url(local_var_path).gsub(@config.base_path, '')
436
+ http_method = :POST.to_sym.downcase
437
+
438
+
439
+ # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
440
+ _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
441
+
442
+ req_opts = {
443
+ :method => http_method,
444
+ :headers => header_params,
445
+ :params => query_params,
446
+ :params_encoding => @config.params_encoding,
447
+ :timeout => @config.timeout,
448
+ :ssl_verifypeer => @config.verify_ssl,
449
+ :ssl_verifyhost => _verify_ssl_host,
450
+ :sslcert => @config.cert_file,
451
+ :sslkey => @config.key_file,
452
+ :verbose => @config.debugging,
453
+ :body => form_params
454
+ }
455
+
456
+ # set custom cert, if provided
457
+ req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
458
+
459
+ request = Typhoeus::Request.new(url, req_opts)
460
+ response = request.run
461
+
462
+ data = JSON.parse("[#{response.body}]", :symbolize_names => true)[0]
463
+
464
+ @config.access_token = data[:access_token]
465
+ @config.refresh_token = data[:refresh_token]
466
+ end
467
+
468
+ # Adds OAuth2.0 token
469
+ def add_o_auth_token(req_opts)
470
+ req_opts[:headers][:Authorization] = "Bearer " + @config.access_token
471
+ end
472
+
473
+
474
+ end
475
+ end