# frozen_string_literal: true require "spec_helper" require "json" begin require "webrick" rescue LoadError # nop end require "evil-proxy" require "evil-proxy/async" describe ProxyFetcher::Client do before :all do ProxyFetcher.configure do |config| config.provider = :xroxy config.client_timeout = 5 config.logger = ProxyFetcher::NullLogger.new end quiet = ENV.key?("LOG_MITM") ? ENV["LOG_MITM"] == "false" : true @server = EvilProxy::MITMProxyServer.new Port: 3128, Quiet: quiet @server.start end after :all do @server.shutdown end let(:local_proxy) { ProxyFetcher::Proxy.new(addr: "127.0.0.1", port: 3128, type: "HTTP, HTTPS") } # Use local proxy server in order to avoid side effects, non-working proxies, etc before :each do ProxyFetcher::Client::ProxiesRegistry.manager.instance_variable_set(:'@proxies', [local_proxy]) allow_any_instance_of(ProxyFetcher::Providers::Base).to receive(:fetch_proxies).and_return([local_proxy]) end context "GET request with the valid proxy" do it "successfully returns page content for HTTP" do content = ProxyFetcher::Client.get("http://httpbin.org/get") expect(content).not_to be_empty end # TODO: oh this SSL / MITM proxies .... xit "successfully returns page content for HTTPS" do content = ProxyFetcher::Client.get("https://httpbin.org/get") expect(content).not_to be_empty end it "successfully returns page content using custom proxy" do content = ProxyFetcher::Client.get("http://httpbin.org/get", options: { proxy: local_proxy }) expect(content).not_to be_empty end end context "POST request with the valid proxy" do it "successfully returns page content for HTTP" do headers = { "X-Proxy-Fetcher-Version" => ProxyFetcher::VERSION::STRING } content = ProxyFetcher::Client.post( "http://httpbin.org/post", { param: "value" }, headers: headers ) expect(content).not_to be_empty json = JSON.parse(content) expect(json["headers"]["X-Proxy-Fetcher-Version"]).to eq(ProxyFetcher::VERSION::STRING) expect(json["headers"]["User-Agent"]).to eq(ProxyFetcher.config.user_agent) end end # TODO: EvilProxy incompatible with latest Ruby/Webrick # @see https://github.com/bbtfr/evil-proxy/issues/10 if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.6") context "PUT request with the valid proxy" do it "successfully returns page content for HTTP" do content = ProxyFetcher::Client.put("http://httpbin.org/put", "param=PutValue") expect(content).not_to be_empty json = JSON.parse(content) expect(json["form"]["param"]).to eq("PutValue") end end context "PATCH request with the valid proxy" do it "successfully returns page content for HTTP" do content = ProxyFetcher::Client.patch("http://httpbin.org/patch", param: "value") expect(content).not_to be_empty json = JSON.parse(content) expect(json["form"]["param"]).to eq("value") end end end context "DELETE request with the valid proxy" do it "successfully returns page content for HTTP" do content = ProxyFetcher::Client.delete("http://httpbin.org/delete") expect(content).not_to be_empty end end context "HEAD request with the valid proxy" do it "successfully works" do content = ProxyFetcher::Client.head("http://httpbin.org") expect(content).to be_empty end end context "retries" do it "raises an error when reaches max retries limit" do allow(ProxyFetcher::Client::Request).to receive(:execute).and_raise(StandardError) expect { ProxyFetcher::Client.get("http://httpbin.org", options: { max_retries: 10 }) } .to raise_error(ProxyFetcher::Exceptions::MaximumRetriesReached) end xit "raises an error when http request returns an error" do allow_any_instance_of(HTTP::Client).to receive(:get).and_return(StandardError.new) expect { ProxyFetcher::Client.get("http://httpbin.org") } .to raise_error(ProxyFetcher::Exceptions::MaximumRetriesReached) end it "refreshes proxy lists if no proxy found" do allow(ProxyFetcher::Manager.new).to receive(:proxies).and_return([]) expect { ProxyFetcher::Client.get("http://httpbin.org") } .not_to raise_error end end xcontext "redirects" do it "follows redirect when present" do content = ProxyFetcher::Client.get("http://httpbin.org/absolute-redirect/2") expect(content).not_to be_empty end it "raises an error when reaches max redirects limit" do expect { ProxyFetcher::Client.get("http://httpbin.org/absolute-redirect/11") } .to raise_error(ProxyFetcher::Exceptions::MaximumRedirectsReached) end end end