lib/eat.rb in eat-0.0.7 vs lib/eat.rb in eat-0.1.0

- old
+ new

@@ -1,43 +1,69 @@ require 'uri' require 'singleton' +# http://weblog.jamisbuck.org/2007/2/7/infinity +unless defined?(::Infinity) + ::Infinity = 1.0/0 +end + module Eat - def self.config - ::Eat::Config.instance - end - - class Config - include ::Singleton - attr_writer :remote_timeout - def remote_timeout - @remote_timeout || 2 #seconds - end - end - module ObjectExtensions - def eat(filesystem_path_or_uri) - uri = ::URI.parse filesystem_path_or_uri.to_s + # <tt>url</tt> can be filesystem or http/https + # + # Options: + # * <tt>:timeout</tt> in seconds + # * <tt>:limit</tt> is characters (bytes in Ruby 1.8) + # + # Example: + # eat('http://brighterplanet.com') #=> '...' + # eat('http://brighterplanet.com', :timeout => 10) #=> '...' + # eat('http://brighterplanet.com', :limit => 1) #=> '.' + def eat(url, options = {}) + timeout = options[:timeout] || options['timeout'] || 2 + limit = options[:limit] || options['limit'] || ::Infinity + uri = ::URI.parse url.to_s + + body = [] + read_so_far = 0 + case uri.scheme + when 'file', nil - if ::File.readable? uri.path - ::File.read uri.path - else - `sudo /bin/cat #{uri.path}` + chunk_size = limit < 1_048_576 ? limit : 1_048_576 + ::File.open(uri.path, 'r') do |f| + while chunk = f.read(chunk_size) + break if read_so_far > limit + read_so_far += chunk_size + body << chunk + end end + when 'http', 'https' require 'net/http' require 'net/https' if uri.scheme == 'https' - (defined?(::SystemTimer) ? ::SystemTimer : ::Timeout).timeout(::Eat.config.remote_timeout) do + (defined?(::SystemTimer) ? ::SystemTimer : ::Timeout).timeout(timeout) do http = ::Net::HTTP.new uri.host, uri.port if uri.scheme == 'https' http.use_ssl = true # if you were trying to be real safe, you wouldn't use this library http.verify_mode = ::OpenSSL::SSL::VERIFY_NONE end - http.start { |session| session.get uri.request_uri } - end.body + http.start do |session| + catch :stop do + session.get(uri.request_uri, 'Accept-Encoding' => '') do |chunk| + throw :stop if read_so_far > limit + read_so_far += chunk.length + body << chunk + end + session.finish + end + end + end + end + + limit == ::Infinity ? body.join : body.join[0...limit] end end end ::Object.send(:include, ::Eat::ObjectExtensions) unless ::Object.method_defined?(:eat)