lib/link_thumbnailer/processor.rb in link_thumbnailer-3.3.2 vs lib/link_thumbnailer/processor.rb in link_thumbnailer-3.4.0

- old
+ new

@@ -15,10 +15,16 @@ @http = ::Net::HTTP::Persistent.new super(config) end + def start(url) + result = call(url) + shutdown + result + end + def call(url = '', redirect_count = 0, headers = {}) self.url = url @redirect_count = redirect_count raise ::LinkThumbnailer::RedirectLimit if too_many_redirections? @@ -26,16 +32,20 @@ with_valid_url do set_http_headers(headers) set_http_options perform_request end - rescue ::Net::HTTPExceptions, ::SocketError, ::Timeout::Error => e + rescue ::Net::HTTPExceptions, ::SocketError, ::Timeout::Error, ::Net::HTTP::Persistent::Error => e raise ::LinkThumbnailer::HTTPError.new(e.message) end private + def shutdown + http.shutdown + end + def with_valid_url raise ::LinkThumbnailer::BadUriFormat unless valid_url_format? yield if block_given? end @@ -51,11 +61,11 @@ http.read_timeout = http_read_timeout http.proxy = :ENV end def perform_request - response = http.request(url) + response = request_in_chunks headers = {} headers['Cookie'] = response['Set-Cookie'] if response['Set-Cookie'].present? raise ::LinkThumbnailer::FormatNotSupported.new(response['Content-Type']) unless valid_response_format?(response) @@ -71,10 +81,23 @@ else response.error! end end + def request_in_chunks + body = String.new + response = http.request(url) do |resp| + raise ::LinkThumbnailer::DownloadSizeLimit if too_big_download_size?(resp.content_length) + resp.read_body do |chunk| + body.concat(chunk) + raise ::LinkThumbnailer::DownloadSizeLimit if too_big_download_size?(body.length) + end + end + response.body = body + response + end + def resolve_relative_url(location) location.start_with?('http') ? location : build_absolute_url_for(location) end def build_absolute_url_for(relative_url) @@ -99,10 +122,14 @@ def ssl_required? config.verify_ssl end + def download_size_limit + config.download_size_limit + end + def too_many_redirections? redirect_count > redirect_limit end def valid_url_format? @@ -116,9 +143,13 @@ return true if response['Content-Type'] =~ /application\/xhtml\+xml/ return true if response['Content-Type'] =~ /application\/xml/ return true if response['Content-Type'] =~ /text\/xml/ return true if response['Content-Type'] =~ /text\/plain/ false + end + + def too_big_download_size?(size) + size.to_i > download_size_limit.to_i end def url=(url) @url = ::URI.parse(url.to_s) end