From a1c29241894269cda717e7c5893ec9b6d614097d Mon Sep 17 00:00:00 2001 From: Joenio Costa Date: Tue, 19 Apr 2016 12:30:50 -0300 Subject: [PATCH] isolate proxy settings among multiple environments --- app/models/external_feed.rb | 2 ++ lib/feed_handler.rb | 35 ++++++++++++++++++----------------- test/unit/feed_handler_test.rb | 63 +++++++++++++++++++++++++++++++++++++++++---------------------- 3 files changed, 61 insertions(+), 39 deletions(-) diff --git a/app/models/external_feed.rb b/app/models/external_feed.rb index e3111fd..b2a1eb5 100644 --- a/app/models/external_feed.rb +++ b/app/models/external_feed.rb @@ -12,6 +12,8 @@ class ExternalFeed < ActiveRecord::Base attr_accessible :address, :enabled, :only_once + delegate :environment, :to => :blog, :allow_nil => true + def add_item(title, link, date, content) return if content.blank? doc = Nokogiri::HTML.fragment content diff --git a/lib/feed_handler.rb b/lib/feed_handler.rb index 6824f8a..1c5305a 100644 --- a/lib/feed_handler.rb +++ b/lib/feed_handler.rb @@ -31,7 +31,7 @@ class FeedHandler end end - def fetch(address) + def fetch(address, header = {}) begin content = "" block = lambda { |s| content = s.read } @@ -42,21 +42,7 @@ class FeedHandler if !valid_url?(address) raise InvalidUrl.new("\"%s\" is not a valid URL" % address) end - - header = {"User-Agent" => "Noosfero/#{Noosfero::VERSION}"} - - environment = Environment.default - - if environment.enable_feed_proxy - if address.starts_with?("https://") - header.merge!(:proxy => environment.https_feed_proxy) if environment.https_feed_proxy - else - header.merge!(:proxy => environment.http_feed_proxy) if environment.http_feed_proxy - end - end - - header.merge!(:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) if environment.disable_feed_ssl - + header.merge!("User-Agent" => "Noosfero/#{Noosfero::VERSION}") open(address, header, &block) end return content @@ -65,6 +51,17 @@ class FeedHandler end end + def fetch_through_proxy(address, environment) + header = {} + if address.starts_with?("https://") + header.merge!(:proxy => environment.https_feed_proxy) if environment.https_feed_proxy + else + header.merge!(:proxy => environment.http_feed_proxy) if environment.http_feed_proxy + end + header.merge!(:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) if environment.disable_feed_ssl + fetch(address, header) + end + def process(container) begin container.class.transaction do @@ -105,7 +102,11 @@ class FeedHandler def actually_process_container(container) container.clear - content = fetch(container.address) + if container.environment.enable_feed_proxy + content = fetch_through_proxy(container.address, container.environment) + else + content = fetch(container.address) + end container.fetched_at = Time.now parsed_feed = parse(content) container.feed_title = parsed_feed.title diff --git a/test/unit/feed_handler_test.rb b/test/unit/feed_handler_test.rb index 4da7c83..f62ee7d 100644 --- a/test/unit/feed_handler_test.rb +++ b/test/unit/feed_handler_test.rb @@ -27,6 +27,7 @@ class FeedHandlerTest < ActiveSupport::TestCase end should 'process feed and populate container' do + container.stubs(:environment).returns(Environment.new) handler.process(container) assert_equal 'Feed for unit tests', container.feed_title assert_equivalent ["First POST", "Second POST", "Last POST"], container.feed_items.map {|item| item[:title]} @@ -61,6 +62,7 @@ class FeedHandlerTest < ActiveSupport::TestCase end should 'save only latest N posts from feed' do + container.stubs(:environment).returns(Environment.new) container.limit = 1 handler.process(container) assert_equal 1, container.feed_items.size @@ -83,9 +85,6 @@ class FeedHandlerTest < ActiveSupport::TestCase end should 'identifies itself as noosfero user agent' do - Environment.any_instance.expects(:enable_feed_proxy).returns(false) - Environment.any_instance.expects(:disable_feed_ssl).returns(false) - handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}"}, anything).returns('bli content') assert_equal 'bli content', handler.fetch('http://site.org/feed.xml') @@ -154,52 +153,72 @@ class FeedHandlerTest < ActiveSupport::TestCase end should 'set proxy when http_feed_proxy is setted from env' do - Environment.any_instance.expects(:enable_feed_proxy).returns(true) - Environment.any_instance.expects(:disable_feed_ssl).returns(false) - Environment.any_instance.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128') + env = Environment.new + env.expects(:disable_feed_ssl).returns(false) + env.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128') handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content') - assert_equal 'bli content', handler.fetch('http://site.org/feed.xml') + assert_equal 'bli content', handler.fetch_through_proxy('http://site.org/feed.xml', env) end should 'set proxy when https_feed_proxy is setted from env' do - Environment.any_instance.expects(:enable_feed_proxy).returns(true) - Environment.any_instance.expects(:disable_feed_ssl).returns(false) - Environment.any_instance.expects(:https_feed_proxy).twice.returns('http://127.0.0.1:3128') + env = Environment.new + env.expects(:disable_feed_ssl).returns(false) + env.expects(:https_feed_proxy).twice.returns('http://127.0.0.1:3128') handler.expects(:open).with('https://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content') - assert_equal 'bli content', handler.fetch('https://site.org/feed.xml') + assert_equal 'bli content', handler.fetch_through_proxy('https://site.org/feed.xml', env) end should 'use https proxy for https address when both env variables were defined' do - Environment.any_instance.expects(:enable_feed_proxy).returns(true) - Environment.any_instance.expects(:disable_feed_ssl).returns(false) - Environment.any_instance.expects(:https_feed_proxy).twice.returns('http://127.0.0.2:3128') + env = Environment.new + env.expects(:disable_feed_ssl).returns(false) + env.expects(:https_feed_proxy).twice.returns('http://127.0.0.2:3128') handler.expects(:open).with('https://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.2:3128'}, anything).returns('bli content') - assert_equal 'bli content', handler.fetch('https://site.org/feed.xml') + assert_equal 'bli content', handler.fetch_through_proxy('https://site.org/feed.xml', env) end should 'use http proxy for http address when both env variables were defined' do - Environment.any_instance.expects(:enable_feed_proxy).returns(true) - Environment.any_instance.expects(:disable_feed_ssl).returns(false) - Environment.any_instance.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128') + env = Environment.new + env.expects(:disable_feed_ssl).returns(false) + env.expects(:http_feed_proxy).twice.returns('http://127.0.0.1:3128') handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :proxy => 'http://127.0.0.1:3128'}, anything).returns('bli content') - assert_equal 'bli content', handler.fetch('http://site.org/feed.xml') + assert_equal 'bli content', handler.fetch_through_proxy('http://site.org/feed.xml', env) end should 'not verify ssl when define env parameter SSL_VERIFY_NONE' do - Environment.any_instance.expects(:enable_feed_proxy).returns(false) - Environment.any_instance.expects(:disable_feed_ssl).returns(true) + env = Environment.new + env.expects(:disable_feed_ssl).returns(true) handler.expects(:open).with('http://site.org/feed.xml', {"User-Agent" => "Noosfero/#{Noosfero::VERSION}", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE}, anything) - handler.fetch('http://site.org/feed.xml') + handler.fetch_through_proxy('http://site.org/feed.xml', env) + end + + [:external_feed, :feed_reader_block].each do |container_class| + should "not use proxy settings for #{container_class} from one environment on another" do + one = create(:environment) + one.expects(:enable_feed_proxy).returns(true) + container_one = create(container_class) + container_one.stubs(:environment).returns(one) + + handler.expects(:fetch_through_proxy).with(container_one.address, one) + handler.process(container_one) + + another = create(:environment) + another.expects(:enable_feed_proxy).returns(false) + container_another = create(container_class) + container_another.stubs(:environment).returns(another) + + handler.expects(:fetch_through_proxy).never.with(container_another.address, another) + handler.process(container_another) + end end end -- libgit2 0.21.2