| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  | # Copyright 2015 Google Inc. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # 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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require 'addressable/uri' | 
					
						
							|  |  |  | require 'addressable/template' | 
					
						
							|  |  |  | require 'google/apis/options' | 
					
						
							|  |  |  | require 'google/apis/errors' | 
					
						
							|  |  |  | require 'retriable' | 
					
						
							|  |  |  | require 'google/apis/core/logging' | 
					
						
							|  |  |  | require 'pp' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Google | 
					
						
							|  |  |  |   module Apis | 
					
						
							|  |  |  |     module Core | 
					
						
							|  |  |  |       # Command for HTTP request/response. | 
					
						
							|  |  |  |       class HttpCommand | 
					
						
							|  |  |  |         include Logging | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RETRIABLE_ERRORS = [Google::Apis::ServerError, Google::Apis::RateLimitError, Google::Apis::TransmissionError] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 20:23:11 +00:00
										 |  |  |         begin | 
					
						
							|  |  |  |           require 'opencensus' | 
					
						
							|  |  |  |           OPENCENSUS_AVAILABLE = true | 
					
						
							|  |  |  |         rescue LoadError | 
					
						
							|  |  |  |           OPENCENSUS_AVAILABLE = false | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         # Request options | 
					
						
							|  |  |  |         # @return [Google::Apis::RequestOptions] | 
					
						
							|  |  |  |         attr_accessor :options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # HTTP request URL | 
					
						
							|  |  |  |         # @return [String, Addressable::URI] | 
					
						
							|  |  |  |         attr_accessor :url | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # HTTP headers | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         # @return [Hash] | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         attr_accessor :header | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Request body | 
					
						
							|  |  |  |         # @return [#read] | 
					
						
							|  |  |  |         attr_accessor :body | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # HTTP method | 
					
						
							|  |  |  |         # @return [symbol] | 
					
						
							|  |  |  |         attr_accessor :method | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # HTTP Client | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         # @return [HTTPClient] | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         attr_accessor :connection | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Query params | 
					
						
							|  |  |  |         # @return [Hash] | 
					
						
							|  |  |  |         attr_accessor :query | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Path params for URL Template | 
					
						
							|  |  |  |         # @return [Hash] | 
					
						
							|  |  |  |         attr_accessor :params | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # @param [symbol] method | 
					
						
							|  |  |  |         #   HTTP method | 
					
						
							|  |  |  |         # @param [String,Addressable::URI, Addressable::Template] url | 
					
						
							|  |  |  |         #   HTTP URL or template | 
					
						
							|  |  |  |         # @param [String, #read] body | 
					
						
							|  |  |  |         #   Request body | 
					
						
							|  |  |  |         def initialize(method, url, body: nil) | 
					
						
							|  |  |  |           self.options = Google::Apis::RequestOptions.default.dup | 
					
						
							|  |  |  |           self.url = url | 
					
						
							|  |  |  |           self.url = Addressable::Template.new(url) if url.is_a?(String) | 
					
						
							|  |  |  |           self.method = method | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |           self.header = Hash.new | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           self.body = body | 
					
						
							|  |  |  |           self.query = {} | 
					
						
							|  |  |  |           self.params = {} | 
					
						
							| 
									
										
										
										
											2018-10-10 20:23:11 +00:00
										 |  |  |           @opencensus_span = nil | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Execute the command, retrying as necessary | 
					
						
							|  |  |  |         # | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         # @param [HTTPClient] client | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         #   HTTP client | 
					
						
							|  |  |  |         # @yield [result, err] Result or error if block supplied | 
					
						
							|  |  |  |         # @return [Object] | 
					
						
							|  |  |  |         # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried | 
					
						
							|  |  |  |         # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification | 
					
						
							|  |  |  |         # @raise [Google::Apis::AuthorizationError] Authorization is required | 
					
						
							|  |  |  |         def execute(client) | 
					
						
							|  |  |  |           prepare! | 
					
						
							| 
									
										
										
										
											2018-10-10 20:23:11 +00:00
										 |  |  |           opencensus_begin_span | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           begin | 
					
						
							|  |  |  |             Retriable.retriable tries: options.retries + 1, | 
					
						
							|  |  |  |                                 base_interval: 1, | 
					
						
							|  |  |  |                                 multiplier: 2, | 
					
						
							|  |  |  |                                 on: RETRIABLE_ERRORS do |try| | 
					
						
							|  |  |  |               # This 2nd level retriable only catches auth errors, and supports 1 retry, which allows | 
					
						
							|  |  |  |               # auth to be re-attempted without having to retry all sorts of other failures like | 
					
						
							|  |  |  |               # NotFound, etc | 
					
						
							|  |  |  |               auth_tries = (try == 1 && authorization_refreshable? ? 2 : 1) | 
					
						
							|  |  |  |               Retriable.retriable tries: auth_tries, | 
					
						
							| 
									
										
										
										
											2018-09-24 18:46:31 +00:00
										 |  |  |                                   on: [Google::Apis::AuthorizationError, Signet::AuthorizationError, Signet::RemoteServerError, Signet::UnexpectedStatusError], | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |                                   on_retry: proc { |*| refresh_authorization } do | 
					
						
							| 
									
										
										
										
											2015-11-20 14:32:43 +00:00
										 |  |  |                 execute_once(client).tap do |result| | 
					
						
							|  |  |  |                   if block_given? | 
					
						
							|  |  |  |                     yield result, nil | 
					
						
							|  |  |  |                   end | 
					
						
							|  |  |  |                 end | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |               end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           rescue => e | 
					
						
							| 
									
										
										
										
											2015-11-20 14:32:43 +00:00
										 |  |  |             if block_given? | 
					
						
							|  |  |  |               yield nil, e | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               raise e | 
					
						
							|  |  |  |             end | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           end | 
					
						
							|  |  |  |         ensure | 
					
						
							| 
									
										
										
										
											2018-10-10 20:23:11 +00:00
										 |  |  |           opencensus_end_span | 
					
						
							|  |  |  |           @http_res = nil | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           release! | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Refresh the authorization authorization after a 401 error | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # @private | 
					
						
							|  |  |  |         # @return [void] | 
					
						
							|  |  |  |         def refresh_authorization | 
					
						
							|  |  |  |           # Handled implicitly by auth lib, here in case need to override | 
					
						
							|  |  |  |           logger.debug('Retrying after authentication failure') | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check if attached credentials can be automatically refreshed | 
					
						
							|  |  |  |         # @return [Boolean] | 
					
						
							|  |  |  |         def authorization_refreshable? | 
					
						
							|  |  |  |           options.authorization.respond_to?(:apply!) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Prepare the request (e.g. calculate headers, serialize data, etc) before sending | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # @private | 
					
						
							|  |  |  |         # @return [void] | 
					
						
							|  |  |  |         def prepare! | 
					
						
							| 
									
										
										
										
											2017-03-30 19:33:49 +00:00
										 |  |  |           normalize_unicode = true | 
					
						
							|  |  |  |           if options | 
					
						
							|  |  |  |             header.update(options.header) if options.header | 
					
						
							|  |  |  |             normalize_unicode = options.normalize_unicode | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           self.url = url.expand(params, nil, normalize_unicode) if url.is_a?(Addressable::Template) | 
					
						
							| 
									
										
										
										
											2015-12-14 02:16:31 +00:00
										 |  |  |           url.query_values = query.merge(url.query_values || {}) | 
					
						
							| 
									
										
										
										
											2016-02-25 17:35:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-08 20:40:30 +00:00
										 |  |  |           if allow_form_encoding? | 
					
						
							| 
									
										
										
										
											2016-02-25 17:35:38 +00:00
										 |  |  |             @form_encoded = true | 
					
						
							|  |  |  |             self.body = Addressable::URI.form_encode(url.query_values(Array)) | 
					
						
							|  |  |  |             self.header['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8' | 
					
						
							|  |  |  |             self.url.query_values = {} | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             @form_encoded = false | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2017-03-31 21:59:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 22:26:51 +00:00
										 |  |  |           self.body = '' unless self.body | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Release any resources used by this command | 
					
						
							|  |  |  |         # @private | 
					
						
							|  |  |  |         # @return [void] | 
					
						
							|  |  |  |         def release! | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check the response and either decode body or raise error | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # @param [Fixnum] status | 
					
						
							|  |  |  |         #   HTTP status code of response | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         # @param [Hash] header | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         #   Response headers | 
					
						
							|  |  |  |         # @param [String, #read] body | 
					
						
							|  |  |  |         #  Response body | 
					
						
							|  |  |  |         # @return [Object] | 
					
						
							|  |  |  |         #   Response object | 
					
						
							|  |  |  |         # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried | 
					
						
							|  |  |  |         # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification | 
					
						
							|  |  |  |         # @raise [Google::Apis::AuthorizationError] Authorization is required | 
					
						
							|  |  |  |         def process_response(status, header, body) | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |           check_status(status, header, body) | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |           decode_response_body(header['Content-Type'].first, body) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check the response and raise error if needed | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # @param [Fixnum] status | 
					
						
							|  |  |  |         #   HTTP status code of response | 
					
						
							| 
									
										
										
										
											2015-10-02 20:31:19 +00:00
										 |  |  |         # @param | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         # @param [Hash] header | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |         #   HTTP response headers | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         # @param [String] body | 
					
						
							|  |  |  |         #   HTTP response body | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |         # @param [String] message | 
					
						
							|  |  |  |         #   Error message text | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         # @return [void] | 
					
						
							|  |  |  |         # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried | 
					
						
							|  |  |  |         # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification | 
					
						
							|  |  |  |         # @raise [Google::Apis::AuthorizationError] Authorization is required | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |         def check_status(status, header = nil, body = nil, message = nil) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           # TODO: 304 Not Modified depends on context... | 
					
						
							|  |  |  |           case status | 
					
						
							|  |  |  |           when 200...300
 | 
					
						
							|  |  |  |             nil | 
					
						
							|  |  |  |           when 301, 302, 303, 307
 | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |             message ||= sprintf('Redirect to %s', header['Location']) | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |             raise Google::Apis::RedirectError.new(message, status_code: status, header: header, body: body) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           when 401
 | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |             message ||= 'Unauthorized' | 
					
						
							|  |  |  |             raise Google::Apis::AuthorizationError.new(message, status_code: status, header: header, body: body) | 
					
						
							| 
									
										
										
										
											2016-08-17 20:58:07 +00:00
										 |  |  |           when 429
 | 
					
						
							|  |  |  |             message ||= 'Rate limit exceeded' | 
					
						
							|  |  |  |             raise Google::Apis::RateLimitError.new(message, status_code: status, header: header, body: body) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           when 304, 400, 402...500
 | 
					
						
							| 
									
										
										
										
											2015-10-02 20:31:19 +00:00
										 |  |  |             message ||= 'Invalid request' | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |             raise Google::Apis::ClientError.new(message, status_code: status, header: header, body: body) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           when 500...600
 | 
					
						
							| 
									
										
										
										
											2015-10-02 20:31:19 +00:00
										 |  |  |             message ||= 'Server error' | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |             raise Google::Apis::ServerError.new(message, status_code: status, header: header, body: body) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           else | 
					
						
							|  |  |  |             logger.warn(sprintf('Encountered unexpected status code %s', status)) | 
					
						
							| 
									
										
										
										
											2015-07-20 19:36:13 +00:00
										 |  |  |             message ||= 'Unknown error' | 
					
						
							|  |  |  |             raise Google::Apis::TransmissionError.new(message, status_code: status, header: header, body: body) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Process the actual response body. Intended to be overridden by subclasses | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # @param [String] _content_type | 
					
						
							|  |  |  |         #  Content type of body | 
					
						
							|  |  |  |         # @param [String, #read] body | 
					
						
							|  |  |  |         #  Response body | 
					
						
							|  |  |  |         # @return [Object] | 
					
						
							|  |  |  |         def decode_response_body(_content_type, body) | 
					
						
							|  |  |  |           body | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Process a success response | 
					
						
							|  |  |  |         # @param [Object] result | 
					
						
							|  |  |  |         #  Result object | 
					
						
							|  |  |  |         # @return [Object] result if no block given | 
					
						
							|  |  |  |         # @yield [result, nil] if block given | 
					
						
							|  |  |  |         def success(result, &block) | 
					
						
							| 
									
										
										
										
											2019-01-04 06:48:27 +00:00
										 |  |  |           logger.debug { sprintf('Success - %s', safe_object_representation(result)) } | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           block.call(result, nil) if block_given? | 
					
						
							|  |  |  |           result | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Process an error response | 
					
						
							|  |  |  |         # @param [StandardError] err | 
					
						
							|  |  |  |         #  Error object | 
					
						
							|  |  |  |         # @param [Boolean] rethrow | 
					
						
							|  |  |  |         #  True if error should be raised again after handling | 
					
						
							|  |  |  |         # @return [void] | 
					
						
							|  |  |  |         # @yield [nil, err] if block given | 
					
						
							|  |  |  |         # @raise [StandardError] if no block | 
					
						
							|  |  |  |         def error(err, rethrow: false, &block) | 
					
						
							|  |  |  |           logger.debug { sprintf('Error - %s', PP.pp(err, '')) } | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |           if err.is_a?(HTTPClient::BadResponseError) | 
					
						
							|  |  |  |             begin | 
					
						
							|  |  |  |               res = err.res | 
					
						
							|  |  |  |               check_status(res.status.to_i, res.header, res.body) | 
					
						
							|  |  |  |             rescue Google::Apis::Error => e | 
					
						
							|  |  |  |               err = e | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           elsif err.is_a?(HTTPClient::TimeoutError) || err.is_a?(SocketError) | 
					
						
							|  |  |  |             err = Google::Apis::TransmissionError.new(err) | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           block.call(nil, err) if block_given? | 
					
						
							|  |  |  |           fail err if rethrow || block.nil? | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Execute the command once. | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # @private | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         # @param [HTTPClient] client | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         #   HTTP client | 
					
						
							|  |  |  |         # @return [Object] | 
					
						
							|  |  |  |         # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried | 
					
						
							|  |  |  |         # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification | 
					
						
							|  |  |  |         # @raise [Google::Apis::AuthorizationError] Authorization is required | 
					
						
							| 
									
										
										
										
											2015-11-20 14:32:43 +00:00
										 |  |  |         def execute_once(client) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           body.rewind if body.respond_to?(:rewind) | 
					
						
							|  |  |  |           begin | 
					
						
							|  |  |  |             logger.debug { sprintf('Sending HTTP %s %s', method, url) } | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |             request_header = header.dup | 
					
						
							|  |  |  |             apply_request_options(request_header) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 20:23:11 +00:00
										 |  |  |             @http_res = client.request(method.to_s.upcase, | 
					
						
							|  |  |  |                                        url.to_s, | 
					
						
							|  |  |  |                                        query: nil, | 
					
						
							|  |  |  |                                        body: body, | 
					
						
							|  |  |  |                                        header: request_header, | 
					
						
							|  |  |  |                                        follow_redirect: true) | 
					
						
							|  |  |  |             logger.debug { @http_res.status } | 
					
						
							|  |  |  |             logger.debug { @http_res.inspect } | 
					
						
							|  |  |  |             response = process_response(@http_res.status.to_i, @http_res.header, @http_res.body) | 
					
						
							| 
									
										
										
										
											2015-11-20 14:32:43 +00:00
										 |  |  |             success(response) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           rescue => e | 
					
						
							|  |  |  |             logger.debug { sprintf('Caught error %s', e) } | 
					
						
							| 
									
										
										
										
											2015-11-20 14:32:43 +00:00
										 |  |  |             error(e, rethrow: true) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Update the request with any specified options. | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         # @param [Hash] header | 
					
						
							|  |  |  |         #  HTTP headers | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         # @return [void] | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |         def apply_request_options(req_header) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           if options.authorization.respond_to?(:apply!) | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |             options.authorization.apply!(req_header) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           elsif options.authorization.is_a?(String) | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |             req_header['Authorization'] = sprintf('Bearer %s', options.authorization) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2016-08-17 20:51:09 +00:00
										 |  |  |           req_header.update(header) | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-12-20 23:22:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-08 20:40:30 +00:00
										 |  |  |         def allow_form_encoding? | 
					
						
							|  |  |  |           [:post, :put].include?(method) && body.nil? | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-20 23:22:13 +00:00
										 |  |  |         private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-04 06:48:27 +00:00
										 |  |  |         UNSAFE_CLASS_NAMES = [ | 
					
						
							|  |  |  |           "Google::Apis::CloudkmsV1::DecryptResponse" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def safe_object_representation obj | 
					
						
							|  |  |  |           name = obj.class.name | 
					
						
							|  |  |  |           if UNSAFE_CLASS_NAMES.include? name | 
					
						
							|  |  |  |             "#<#{name} (fields redacted)>" | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             PP.pp(obj, "") | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 20:23:11 +00:00
										 |  |  |         def opencensus_begin_span | 
					
						
							|  |  |  |           return unless OPENCENSUS_AVAILABLE && options.use_opencensus | 
					
						
							|  |  |  |           return if @opencensus_span | 
					
						
							|  |  |  |           return unless OpenCensus::Trace.span_context | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @opencensus_span = OpenCensus::Trace.start_span url.path.to_s | 
					
						
							|  |  |  |           @opencensus_span.kind = OpenCensus::Trace::SpanBuilder::CLIENT | 
					
						
							|  |  |  |           @opencensus_span.put_attribute "http.host", url.host.to_s | 
					
						
							|  |  |  |           @opencensus_span.put_attribute "http.method", method.to_s.upcase | 
					
						
							|  |  |  |           @opencensus_span.put_attribute "http.path", url.path.to_s | 
					
						
							|  |  |  |           if body.respond_to? :bytesize | 
					
						
							|  |  |  |             @opencensus_span.put_message_event \ | 
					
						
							|  |  |  |               OpenCensus::Trace::SpanBuilder::SENT, 1, body.bytesize | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           formatter = OpenCensus::Trace.config.http_formatter | 
					
						
							|  |  |  |           if formatter.respond_to? :header_name | 
					
						
							|  |  |  |             header[formatter.header_name] = formatter.serialize @opencensus_span.context.trace_context | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         rescue StandardError => e | 
					
						
							|  |  |  |           # Log exceptions and continue, so opencensus failures don't cause | 
					
						
							|  |  |  |           # the entire request to fail. | 
					
						
							|  |  |  |           logger.debug { sprintf('Error opening OpenCensus span: %s', e) } | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def opencensus_end_span | 
					
						
							|  |  |  |           return unless OPENCENSUS_AVAILABLE | 
					
						
							|  |  |  |           return unless @opencensus_span | 
					
						
							|  |  |  |           return unless OpenCensus::Trace.span_context | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if @http_res.body.respond_to? :bytesize | 
					
						
							|  |  |  |             @opencensus_span.put_message_event \ | 
					
						
							|  |  |  |               OpenCensus::Trace::SpanBuilder::RECEIVED, 1, @http_res.body.bytesize | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           status = @http_res.status.to_i | 
					
						
							|  |  |  |           if status > 0
 | 
					
						
							|  |  |  |             @opencensus_span.set_status map_http_status status | 
					
						
							|  |  |  |             @opencensus_span.put_attribute "http.status_code", status | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           OpenCensus::Trace.end_span @opencensus_span | 
					
						
							|  |  |  |           @opencensus_span = nil | 
					
						
							|  |  |  |         rescue StandardError => e | 
					
						
							|  |  |  |           # Log exceptions and continue, so failures don't cause leaks by | 
					
						
							|  |  |  |           # aborting cleanup. | 
					
						
							|  |  |  |           logger.debug { sprintf('Error finishing OpenCensus span: %s', e) } | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 17:35:38 +00:00
										 |  |  |         def form_encoded? | 
					
						
							|  |  |  |           @form_encoded | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 20:23:11 +00:00
										 |  |  |         def map_http_status http_status | 
					
						
							|  |  |  |           case http_status | 
					
						
							|  |  |  |           when 200..399 then 0 # OK | 
					
						
							|  |  |  |           when 400 then 3 # INVALID_ARGUMENT | 
					
						
							|  |  |  |           when 401 then 16 # UNAUTHENTICATED | 
					
						
							|  |  |  |           when 403 then 7 # PERMISSION_DENIED | 
					
						
							|  |  |  |           when 404 then 5 # NOT_FOUND | 
					
						
							|  |  |  |           when 429 then 8 # RESOURCE_EXHAUSTED | 
					
						
							|  |  |  |           when 501 then 12 # UNIMPLEMENTED | 
					
						
							|  |  |  |           when 503 then 14 # UNAVAILABLE | 
					
						
							|  |  |  |           when 504 then 4 # DEADLINE_EXCEEDED | 
					
						
							|  |  |  |           else 2 # UNKNOWN | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-20 23:22:13 +00:00
										 |  |  |         def normalize_query_value(v) | 
					
						
							|  |  |  |           case v | 
					
						
							|  |  |  |           when Array | 
					
						
							|  |  |  |             v.map { |v2| normalize_query_value(v2) } | 
					
						
							|  |  |  |           when nil | 
					
						
							|  |  |  |             nil | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             v.to_s | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-04-17 00:28:38 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |