Faraday: Ability to ignore env proxy settings for a single connection

Created on 22 Aug 2019  ·  3Comments  ·  Source: lostisland/faraday

Basic Info

  • Faraday Version: 0.15.4
  • Ruby Version: 2.4.3

Issue description

We're running a pretty large app with hundreds of sub-components that use Faraday to some extent. Most of these components expect to configure Faraday with the environment variables http_proxy and so on; they don't pass an explicit :proxy setting to the connection constructors.

Some components (2 or 3 out of about 100) however, must use a Faraday connection without a proxy. That means we can't use Faraday.ignore_env_proxy = true, otherwise the remaining ~100 components break.

What I'd like to have is a way for those few components to be able to create a Faraday connection object that does not use a proxy, neither from the environment nor otherwise.

Steps to reproduce

Similar to #752, this yields a faraday object that will use the proxy settings from the environment when it makes connections:

c = Faraday.new('https://www.google.com', proxy: nil)

I also tried being Very Smart and passing an empty hash as the Proxy Options instead, like so:

c = Faraday.new('https://www.google.com', proxy: {})

but using this connection errors with:

NoMethodError: undefined method `hostname' for nil:NilClass
from vendor/bundle/ruby/2.4.0/gems/faraday-0.15.4/lib/faraday/adapter/net_http.rb:97:in `net_http_connection'

I believe having this (or another way of saying "don't use a proxy" via :proxy settings) be supported would fully resolve this issue for me.

info

Most helpful comment

OMG, that's definitely a work-around. What we did so far was a middleware like this (for our use of Octokit):

    # A Faraday middleware that throws out any configured proxy away
    # from the request environment, to make connections to GHE work
    # (those must not be proxied).
    class ProxyDroppingMiddleware < Faraday::Middleware
      def call(request_env)
        request_env[:request][:proxy] = nil
        @app.call(request_env)
      end
    end

And then, when it comes time to initialize octokit:

        stack = Faraday::RackBuilder.new do |builder|
          builder.use ProxyDroppingMiddleware
          # What follows is the default octokit middleware:
          builder.use Faraday::Request::Retry, exceptions: [Octokit::ServerError]
          builder.use Octokit::Middleware::FollowRedirects
          builder.use Octokit::Response::RaiseError
          builder.use Octokit::Response::FeedParser
          builder.adapter Faraday.default_adapter
        end
        options[:middleware] = stack

From what I can tell, the middleware work-around will work more nicely with octokit, otherwise we'd have to make an octokit wrapper to patch the Faraday object after creation.

All 3 comments

@asf-stripe I have never tried doing this (it's usually all or none), but I think you can try setting the proxy to nil AFTER the connection initialisation with the setter (https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb#L397)

c = Faraday.new('https://www.google.com')
c.proxy = nil

This should set the @manual_proxy env to true and force Faraday to ignore the env for that particular connection.
Please let me know if that works 😄

OMG, that's definitely a work-around. What we did so far was a middleware like this (for our use of Octokit):

    # A Faraday middleware that throws out any configured proxy away
    # from the request environment, to make connections to GHE work
    # (those must not be proxied).
    class ProxyDroppingMiddleware < Faraday::Middleware
      def call(request_env)
        request_env[:request][:proxy] = nil
        @app.call(request_env)
      end
    end

And then, when it comes time to initialize octokit:

        stack = Faraday::RackBuilder.new do |builder|
          builder.use ProxyDroppingMiddleware
          # What follows is the default octokit middleware:
          builder.use Faraday::Request::Retry, exceptions: [Octokit::ServerError]
          builder.use Octokit::Middleware::FollowRedirects
          builder.use Octokit::Response::RaiseError
          builder.use Octokit::Response::FeedParser
          builder.adapter Faraday.default_adapter
        end
        options[:middleware] = stack

From what I can tell, the middleware work-around will work more nicely with octokit, otherwise we'd have to make an octokit wrapper to patch the Faraday object after creation.

Ah yes, my solution only works if you have access to the actual connection (either using a wrapper or things like instance_variable_get). I assumed that was the case looking at the attempts you mentioned on your first post.

Glad to hear my suggestion works and you even have a custom middleware for other cases.
I'll close this issue but please reach out if you still need any help 😄

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mvastola picture mvastola  ·  4Comments

t3hk0d3 picture t3hk0d3  ·  3Comments

luizkowalski picture luizkowalski  ·  3Comments

ioquatix picture ioquatix  ·  4Comments

QuinnWilton picture QuinnWilton  ·  4Comments