require "net/http" require "cgi" require "uri" require "rubygems" require "json" require "longurl/constants" require "longurl/exceptions" module LongURL class Service def initialize(params = {}) @@cache = params[:cache] || Hash.new @@supported_services = cached_or_fetch_supported_services end def query_supported_service_only(url) check url raise LongURL::UnsupportedService unless service_supported?(url) cached_query url end def cached_query(url) @@cache[url] ||= query(url) end def query(url) escaped_url = check_and_escape(url) Net::HTTP.start(EndPoint.host, EndPoint.port) do |http| handle_response http.get("#{EndPoint.path}?format=json&url=#{escaped_url}") end rescue Timeout::Error, Errno::ENETUNREACH, Errno::ETIMEDOUT, SocketError raise LongURL::NetworkError end def service_supported?(url) @@supported_services.include? URI.parse(url).host.downcase end def check(url) raise LongURL::InvalidURL if url.nil? or url.empty? end protected def cached_or_fetch_supported_services @@cache['supported_services'] ||= fetch_supported_services end def check_and_escape(url) check url CGI.escape url end def fetch_supported_services Net::HTTP.start(ServiceEndPoint.host, ServiceEndPoint.port) do |http| response = http.get("#{ServiceEndPoint.path}?format=json") parsed = JSON.parse(response.body) parsed.values.flatten end rescue Timeout::Error, Errno::ENETUNREACH, Errno::ETIMEDOUT, SocketError raise LongURL::NetworkError end def handle_response(response) parsed = JSON.parse(response.body) if parsed['long_url'] parsed['long_url'] elsif parsed['message'] # Error raise LongURL::UnsupportedService if parsed['messages']['message'] == 'Unsupported service.' else raise LongURL::UnknownError end end end end