Permalink
Browse files

Add a logger. Update APIOperatorCached. Uses some Ruby 1.9 features

  • Loading branch information...
1 parent 04a1ee6 commit 76e895c21cf0b84a49f6b6672268497377947f44 curtis committed Jun 17, 2011
@@ -11,121 +11,117 @@ module Sevendigital
#deals with OAuth signing requests that require signature, making sure parameters are in correct format etc
class ApiOperator # :nodoc:
- RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~]/
+ RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~]/
- def initialize(client)
- @client = client
- end
+ def initialize(client)
+ @client = client
+ end
- def call_api(api_request)
- api_response = make_http_request_and_digest(api_request)
- puts api_response.content.to_s if @client.very_verbose?
- api_response
- end
+ def call_api(api_request)
+ make_http_request_and_digest(api_request).tap do |api_response|
+ @client.log(:verbose) { "ApiOperator: API Response: #{api_response}" }
+ end
+ end
- def get_request_uri(api_request)
- api_request.signature_scheme = :query_string if api_request.requires_signature?
- http_client, http_request = create_http_request(api_request)
- path = http_request.instance_variable_get("@path")
- host = http_client.instance_variable_get("@address")
- port = http_client.instance_variable_get("@port")
- scheme = port == 443 ? "https" : "http"
- return "#{scheme}://#{host}#{path}"
- end
+ def get_request_uri(api_request)
+ api_request.signature_scheme = :query_string if api_request.requires_signature?
+ http_client, http_request = create_http_request(api_request)
+ path = http_request.instance_variable_get("@path")
+ host = http_client.instance_variable_get("@address")
+ port = http_client.instance_variable_get("@port")
+ scheme = port == 443 ? "https" : "http"
+ "#{scheme}://#{host}#{path}"
+ end
- def make_http_request_and_digest(api_request)
+ def make_http_request_and_digest(api_request)
digest_http_response(make_http_request(api_request))
- end
-
- def make_http_request(api_request)
-
- http_client, http_request = create_http_request(api_request)
-
- http_client.set_debug_output($stdout) if @client.very_verbose?
- log_request(http_request) if @client.verbose?
+ end
- http_client.request(http_request)
- end
+ def make_http_request(api_request)
+ http_client, http_request = create_http_request(api_request)
+ @client.log(:verbose) { "ApiOperator: Making HTTP Request..." }
+ http_client.request(http_request).tap do |response|
+ @client.log(:verbose) { "ApiOperator: Response Headers: #{response.header.to_yaml}" }
+ end
+ end
- def digest_http_response(http_response)
- api_response = @client.api_response_digestor.from_http_response(http_response)
- raise Sevendigital::SevendigitalError.new(api_response.error_code, api_response.error_message), "#{api_response.error_code} - #{api_response.error_message}" if !api_response.ok?
- api_response
- end
+ def digest_http_response(http_response)
+ @client.api_response_digestor.from_http_response(http_response).tap do |api_response|
+ unless api_response.ok?
+ raise Sevendigital::SevendigitalError.new(api_response.error_code, api_response.error_message), "#{api_response.error_code} - #{api_response.error_message}"
+ end
+ end
+ end
- def create_http_request(api_request)
- http_client, http_request = create_standard_http_request(api_request)
- if (api_request.requires_signature?) then
- oauth_sign_request(http_client, http_request, api_request)
- else
+ def create_http_request(api_request)
+ http_client, http_request = create_standard_http_request(api_request)
+ if (api_request.requires_signature?)
+ oauth_sign_request(http_client, http_request, api_request)
+ else
+ end
+ [http_client, http_request]
end
- return http_client, http_request
- end
- def oauth_sign_request(http_client, http_request, api_request)
- http_request.oauth!( \
- http_client, \
- @client.oauth_consumer, \
- api_request.token, \
- {:scheme => api_request.signature_scheme}
- )
- return http_request
- end
+ def oauth_sign_request(http_client, http_request, api_request)
+ http_request.oauth!( \
+ http_client, \
+ @client.oauth_consumer, \
+ api_request.token, \
+ {:scheme => api_request.signature_scheme}
+ )
+ http_request
+ end
- def create_standard_http_request(api_request)
- request_uri = create_request_uri(api_request)
- http_client = Net::HTTP.new(request_uri.host, request_uri.port)
+ def create_standard_http_request(api_request)
+ request_uri = create_request_uri(api_request)
+ http_client = Net::HTTP.new(request_uri.host, request_uri.port)
- if !api_request.requires_signature? then
- request_uri.query ||= ""
- request_uri.query += "&oauth_consumer_key=#{@client.configuration.oauth_consumer_key}"
- end
+ if !api_request.requires_signature?
+ request_uri.query ||= ""
+ request_uri.query += "&oauth_consumer_key=#{@client.configuration.oauth_consumer_key}"
+ end
- http_request = new_http_request(request_uri.request_uri, api_request.http_method)
+ http_request = new_http_request(request_uri.request_uri, api_request.http_method)
- ensure_secure_connection(http_client) if api_request.requires_secure_connection?
- add_form_parameters(http_request, api_request)
+ ensure_secure_connection(http_client) if api_request.requires_secure_connection?
+ add_form_parameters(http_request, api_request)
- return http_client, http_request
- end
+ @client.log(:verbose) { "ApiOperator: Creating HTTP Request: #{request_uri}" }
- def ensure_secure_connection(http_client)
- http_client.use_ssl = true
- http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
- end
+ [http_client, http_request]
+ end
- def create_request_uri(api_request)
- host, version = @client.api_host_and_version(api_request.api_service)
- path = "/#{version}/#{api_request.api_method}"
- query = api_request.parameters.map{ |k,v| "#{escape(k)}=#{escape(v)}" }.join("&")
- query = nil if query == ""
- if api_request.requires_secure_connection? then
- URI::HTTPS.build(:host => host, :path => path, :query =>query)
- else
- URI::HTTP.build(:host => host, :path => path, :query =>query)
+ def ensure_secure_connection(http_client)
+ http_client.use_ssl = true
+ http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
- end
- def new_http_request(request_uri, http_method)
- request_type = Kernel.const_get("Net").const_get("HTTP").const_get(http_method.to_s.capitalize)
- request_type.new(request_uri, {"user-agent" => @client.user_agent_info})
- end
+ def create_request_uri(api_request)
+ host, version = @client.api_host_and_version(api_request.api_service)
+ path = "/#{version}/#{api_request.api_method}"
+ query = api_request.parameters.map{ |k,v| "#{escape(k)}=#{escape(v)}" }.join("&")
+ query = nil if query == ""
+ if api_request.requires_secure_connection? then
+ URI::HTTPS.build(:host => host, :path => path, :query =>query)
+ else
+ URI::HTTP.build(:host => host, :path => path, :query =>query)
+ end
+ end
- def add_form_parameters(http_request, api_request)
- http_request.body = api_request.form_parameters.map {|k, v| "#{escape(k)}=#{escape(v)}" }.flatten.join('&')
- http_request.content_type = 'application/x-www-form-urlencoded'
- end
+ def new_http_request(request_uri, http_method)
+ request_type = Kernel.const_get("Net").const_get("HTTP").const_get(http_method.to_s.capitalize)
+ request_type.new(request_uri, {"user-agent" => @client.user_agent_info})
+ end
- def escape(value)
- URI::escape(value.to_s, RESERVED_CHARACTERS)
- rescue ArgumentError
- URI::escape(value.to_s.force_encoding(Encoding::UTF_8), RESERVED_CHARACTERS)
- end
+ def add_form_parameters(http_request, api_request)
+ http_request.body = api_request.form_parameters.map {|k, v| "#{escape(k)}=#{escape(v)}" }.flatten.join('&')
+ http_request.content_type = 'application/x-www-form-urlencoded'
+ end
- def log_request(request)
- puts "ApiOperator calling #{request.inspect}" if @client.verbose?
+ def escape(value)
+ URI::escape(value.to_s, RESERVED_CHARACTERS)
+ rescue ArgumentError
+ URI::escape(value.to_s.force_encoding(Encoding::UTF_8), RESERVED_CHARACTERS)
+ end
end
-
end
-
-end
@@ -11,35 +11,59 @@ def initialize(client, cache)
end
def call_api(api_request)
- request_cache_key = create_request_uri(api_request)
- if !api_request.requires_signature?
- http_response = @cache.respond_to?(:read) ? @cache.read(request_cache_key.to_s) : @cache.get(request_cache_key.to_s)
- end
- puts "ApiOperatorCached: Got from cache #{request_cache_key}" if @client.verbose? && http_response
- puts "but the response is out of date" if @client.verbose? && http_response && response_out_of_date?(http_response)
- if (!http_response || response_out_of_date?(http_response)) then
- http_response = make_http_request(api_request)
- if !api_request.requires_signature?
- @cache.respond_to?(:write) ? @cache.write(request_cache_key.to_s, http_response) : @cache.set(request_cache_key.to_s, http_response)
- end
- end
- api_response = digest_http_response(http_response)
- p api_response if @client.very_verbose?
- api_response
- end
+ http_response = retrieve_from_cache(api_request)
+ http_response = cache_response(api_request) if response_out_of_date?(http_response)
- def response_out_of_date?(http_response, current_time=nil)
- header_invalid?(http_response.header) || cache_expired?(http_response.header, current_time)
+ digest_http_response(http_response).tap do |api_response|
+ @client.log(:verbose) { "ApiOperatorCached: API Response: #{api_response}" }
+ end
end
private
def header_invalid?(header)
- header.nil? || header["Date"].nil? || header["cache-control"].nil? || !(header["cache-control"] =~ /max-age=([0-9]+)/)
+ header["Date"].nil? || header["cache-control"].nil? || !(header["cache-control"] =~ /max-age=([0-9]+)/)
end
def cache_expired?(header, current_time=nil)
(Time.parse(header["Date"]) + (/max-age=([0-9]+)/.match(header["cache-control"])[1].to_i)) < (current_time || Time.now.utc)
end
+
+ def cache_response(api_request)
+ make_http_request(api_request).tap do |response|
+ # Enforce configuration option to cache for a time period.
+ unless @client.configuration.default_cache_period.blank?
+ if header_invalid?(response.header)
+ response.header['cache-control'] = "private, max-age=#{@client.configuration.default_cache_period.to_i}"
+ @client.log(:verbose) { "ApiOperatorCached: Updating cache-control header with: #{@client.configuration.default_cache_period.to_i} seconds" }
+ end
+ end
+
+ unless api_request.requires_signature?
+ key = request_cache_key(api_request)
+ @cache.respond_to?(:write) ? @cache.write(key, response) : @cache.set(key, response)
+ @client.log(:verbose) { "ApiOperatorCached: Storing response in cache..." }
+ end
+ end
+ end
+
+ def request_cache_key(api_request)
+ create_request_uri(api_request).to_s
+ end
+
+ def response_out_of_date?(http_response, current_time=nil)
+ (http_response.blank? || header_invalid?(http_response.header) || cache_expired?(http_response.header, current_time)).tap do |expired|
+ @client.log(:verbose) { "ApiOperatorCached: Cache response out of date" if expired }
+ end
+ end
+
+ def retrieve_from_cache(api_request)
+ unless api_request.requires_signature?
+ key = request_cache_key(api_request)
+ (@cache.respond_to?(:read) ? @cache.read(key) : @cache.get(key)).tap do |response|
+ @client.log(:verbose) { "ApiOperatorCached: Got from cache #{key}" if response }
+ end
+ end
+ end
end
end
Oops, something went wrong.

0 comments on commit 76e895c

Please sign in to comment.