lib/ably/rest/client.rb in ably-0.8.15 vs lib/ably/rest/client.rb in ably-1.0.0

- old
+ new

@@ -1,8 +1,9 @@ require 'faraday' require 'json' require 'logger' +require 'uri' require 'ably/rest/middleware/exceptions' module Ably module Rest @@ -22,12 +23,12 @@ DOMAIN = 'rest.ably.io' # Configuration for HTTP timeouts and HTTP request reattempts to fallback hosts HTTP_DEFAULTS = { open_timeout: 4, - request_timeout: 15, - max_retry_duration: 10, + request_timeout: 10, + max_retry_duration: 15, max_retry_count: 3 }.freeze def_delegators :auth, :client_id, :auth_options @@ -101,16 +102,16 @@ # @option options [Hash] :auth_params a set of application-specific query params to be added to any request made to the +auth_url+ # @option options [Symbol] :auth_method (:get) HTTP method to use with +auth_url+, must be either +:get+ or +:post+ # @option options [Proc] :auth_callback when provided, the Proc will be called with the token params hash as the first argument, whenever a new token is required. # The Proc should return a token string, {Ably::Models::TokenDetails} or JSON equivalent, {Ably::Models::TokenRequest} or JSON equivalent # @option options [Boolean] :query_time when true will query the {https://www.ably.io Ably} system for the current time instead of using the local time - # @option options [Hash] :token_params convenience to pass in +token_params+ that will be used as a default for all token requests. See {Auth#create_token_request} + # @option options [Hash] :default_token_params convenience to pass in +token_params+ that will be used as a default for all token requests. See {Auth#create_token_request} # # @option options [Integer] :http_open_timeout (4 seconds) timeout in seconds for opening an HTTP connection for all HTTP requests - # @option options [Integer] :http_request_timeout (15 seconds) timeout in seconds for any single complete HTTP request and response + # @option options [Integer] :http_request_timeout (10 seconds) timeout in seconds for any single complete HTTP request and response # @option options [Integer] :http_max_retry_count (3) maximum number of fallback host retries for HTTP requests that fail due to network issues or server problems - # @option options [Integer] :http_max_retry_duration (10 seconds) maximum elapsed time in which fallback host retries for HTTP requests will be attempted i.e. if the first default host attempt takes 5s, and then the subsequent fallback retry attempt takes 7s, no further fallback host attempts will be made as the total elapsed time of 12s exceeds the default 10s limit + # @option options [Integer] :http_max_retry_duration (15 seconds) maximum elapsed time in which fallback host retries for HTTP requests will be attempted i.e. if the first default host attempt takes 5s, and then the subsequent fallback retry attempt takes 7s, no further fallback host attempts will be made as the total elapsed time of 12s exceeds the default 10s limit # # @option options [Boolean] :fallback_hosts_use_default (false) When true, forces the user of fallback hosts even if a non-default production endpoint is being used # @option options [Array<String>] :fallback_hosts When an array of fallback hosts are provided, these fallback hosts are always used if a request fails to the primary endpoint. If an empty array is provided, the fallback host functionality is disabled # # @return [Ably::Rest::Client] @@ -125,17 +126,18 @@ def initialize(options) raise ArgumentError, 'Options Hash is expected' if options.nil? options = options.clone if options.kind_of?(String) - options = if options.match(/^[\w-]{2,}\.[\w-]{2,}:[\w-]{2,}$/) + options = if options.match(Auth::API_KEY_REGEX) { key: options } else { token: options } end end + @realtime_client = options.delete(:realtime_client) @tls = options.delete(:tls) == false ? false : true @environment = options.delete(:environment) # nil is production @environment = nil if [:production, 'production'].include?(@environment) @protocol = options.delete(:protocol) || :msgpack @debug_http = options.delete(:debug_http) @@ -180,11 +182,11 @@ @protocol = :json end end raise ArgumentError, 'Protocol is invalid. Must be either :msgpack or :json' unless [:msgpack, :json].include?(@protocol) - token_params = options.delete(:token_params) || {} + token_params = options.delete(:default_token_params) || {} @options = options @auth = Auth.new(self, token_params, options) @channels = Ably::Rest::Channels.new(self) @encoders = [] @@ -283,18 +285,18 @@ def request(method, path, params = {}, body = nil, headers = {}, options = {}) raise "Method #{method.to_s.upcase} not supported" unless [:get, :put, :post].include?(method.to_sym) response = case method.to_sym when :get - reauthorise_on_authorisation_failure do + reauthorize_on_authorisation_failure do send_request(method, path, params, headers: headers) end when :post path_with_params = Addressable::URI.new path_with_params.query_values = params || {} query = path_with_params.query - reauthorise_on_authorisation_failure do + reauthorize_on_authorisation_failure do send_request(method, "#{path}#{"?#{query}" unless query.nil? || query.empty?}", body, headers: headers) end end paginated_options = { @@ -344,22 +346,12 @@ # # @param [Ably::Models::MessageEncoders::Base] encoder # @return [void] # # @api private - def register_encoder(encoder) - encoder_klass = if encoder.kind_of?(String) - encoder.split('::').inject(Kernel) do |base, klass_name| - base.public_send(:const_get, klass_name) - end - else - encoder - end - - raise "Encoder must inherit from `Ably::Models::MessageEncoders::Base`" unless encoder_klass.ancestors.include?(Ably::Models::MessageEncoders::Base) - - encoders << encoder_klass.new(self) + def register_encoder(encoder, options = {}) + encoders << Ably::Models::MessageEncoders.encoder_from(encoder, options) end # @!attribute [r] protocol_binary? # @return [Boolean] True of the transport #protocol communicates with Ably with a binary protocol def protocol_binary? @@ -409,17 +401,29 @@ Ably.lib_variant, Ably::VERSION ].compact.join('-') end + # Allowable duration for an external auth request + # For REST client this defaults to request_timeout + # For Realtime clients this defaults to realtime_request_timeout + # @api private + def auth_request_timeout + if @realtime_client + @realtime_client.connection.defaults.fetch(:realtime_request_timeout) + else + http_defaults.fetch(:request_timeout) + end + end + private def raw_request(method, path, params = {}, options = {}) options = options.clone - if options.delete(:disable_automatic_reauthorise) == true + if options.delete(:disable_automatic_reauthorize) == true send_request(method, path, params, options) else - reauthorise_on_authorisation_failure do + reauthorize_on_authorisation_failure do send_request(method, path, params, options) end end end @@ -447,11 +451,11 @@ rescue Faraday::TimeoutError, Faraday::ClientError, Ably::Exceptions::ServerError => error time_passed = Time.now - requested_at if can_fallback_to_alternate_ably_host? && retry_count < max_retry_count && time_passed <= max_retry_duration retry_count += 1 - logger.warn "Ably::Rest::Client - Retry #{retry_count} for #{method} #{path} #{params} as initial attempt failed: #{error}" + logger.warn { "Ably::Rest::Client - Retry #{retry_count} for #{method} #{path} #{params} as initial attempt failed: #{error}" } retry end case error when Faraday::TimeoutError @@ -462,15 +466,15 @@ raise error end end end - def reauthorise_on_authorisation_failure + def reauthorize_on_authorisation_failure yield rescue Ably::Exceptions::TokenExpired => e if auth.token_renewable? - auth.authorise(nil, force: true) + auth.authorize yield else raise e end end @@ -533,10 +537,10 @@ def can_fallback_to_alternate_ably_host? fallback_hosts && !fallback_hosts.empty? end def initialize_default_encoders - Ably::Models::MessageEncoders.register_default_encoders self + Ably::Models::MessageEncoders.register_default_encoders self, binary_protocol: protocol == :msgpack end end end end