lib/tickethub/request.rb in tickethub-0.3.51 vs lib/tickethub/request.rb in tickethub-0.3.52

- old
+ new

@@ -1,32 +1,35 @@ require 'securerandom' module Tickethub class Request - attr_reader :options, :format, :url - attr_accessor :params, :body, :method, :headers - # Connection options - attr_accessor :proxy, :user, :password, :auth_type, :timeout, :retries, :ssl_options + attr_accessor :params, :body, :method, :headers, + :proxy, :user, :password, :retries, + :auth_type, :timeout, :ssl_options, + :max_attempts, :follow_redirection def initialize(url, options = {}) @url = url.to_s @id = SecureRandom.uuid @retries = 3 @timeout = 10 - @options = options + @options = { + :method => :get, + :params => {}, + :headers => {}, + :format => :form, + :max_attempts => 5, + :follow_redirection => true + }.merge(options) + @options.each do |key, val| method = "#{key}=" send(method, val) if respond_to?(method) end - - self.method ||= :get - self.params ||= {} - self.headers ||= {} - self.format ||= :form end def format=(mime_or_format) @format = mime_or_format.is_a?(Symbol) ? Formats[mime_or_format].new : mime_or_format @@ -44,54 +47,90 @@ url = @url.match(/\Ahttps?:\/\//) ? @url : "http://#{@url}" @uri = URI.parse(url) @uri.path = '/' if @uri.path.empty? - if @uri.query - @params.merge!(Helpers.from_param(@uri.query)) - @uri.query = nil - end - @uri end + def uri_params + uri.query ? Helpers.from_param(uri.query) : {} + end + def path uri.path end - def execute - if encoded? - result = connection.send(method, path, encoded, build_headers) - else - result = connection.send(method, query_path, build_headers) + def query_path + query_path = path.dup + query_params = uri_params.dup + query_params.merge!(params) unless encoded? + + if query_params.any? + query_path += '?' + Helpers.to_url_param(query_params) end - Response.new(result) + query_path + end - rescue TimeoutError, ServerError, SSLError => err - raise err if (@retries -= 1) == 0 - execute - rescue Redirection => error - raise error unless error.response['Location'] - location = URI.parse(error.response['Location']) + def encoded? + [:post, :put].include?(method) + end - # Path is relative - unless location.host - location = URI.join(uri, location) - end + def encoded + params.any? ? format.encode(params) : body + end - self.url = location.to_s + def execute + with_redirection do + if encoded? + result = connection.send(method, query_path, encoded, build_headers) + else + result = connection.send(method, query_path, build_headers) + end + + Response.new(result, uri) + end + rescue ServerError, RequestError => err + raise err if (@retries -= 1) == 0 execute end protected + def with_redirection(&block) + attempts = 1 + + begin + yield + rescue Redirection => error + raise error unless follow_redirection + + attempts += 1 + + raise error unless error.response['Location'] + raise RedirectionLoop.new(self, error.response) if attempts > max_attempts + + location = error.response['Location'].scrub + location = URI.parse(location) + + # Path is relative + unless location.host + location = URI.join(uri, location) + end + + self.url = location.to_s + retry + end + end + def connection Connection.new(uri, :proxy => proxy, :timeout => timeout, - :ssl_options => ssl_options + :ssl_options => ssl_options, + :request => self ) end def content_type_headers if encoded? @@ -114,26 +153,8 @@ def build_headers auth_headers .merge(content_type_headers) .merge(headers) .merge('X-Request-ID' => @id) - end - - def query_path - query_path = path - - if params.any? - query_path += '?' + Helpers.to_param(params) - end - - query_path - end - - def encoded? - [:post, :patch].include?(method) - end - - def encoded - params.any? ? format.encode(params) : body end end end \ No newline at end of file