dnsimple-ruby icon indicating copy to clipboard operation
dnsimple-ruby copied to clipboard

This PR fixes a bug where providing `base_url: "api.dnsimple.com"` results in broken requests

Open mweitzel opened this issue 1 year ago • 0 comments

A user provided base_url is never normalized and results in downstream errors. This PR addresses the issue.

Both

  • Client.new base_url: nil
  • Client.new base_url: "https://api.dnsimple.com"

Result in

  • client.base_url # => "https://api.dnsimple.com"

However, passing

  • Client.new base_url: "api.dnsimple.com", or
  • Client.new base_url: ""

Are not normalized and do not error until requests are made. The errors are fairly opaque in nature. Because of the use of HTTParty, and its use of net/http, passing "api.dnsimple.com" to the constructor results in the error:

Failed to open TCP connection to :80 (Connection refused - connect(2) for nil port 80) (Errno::ECONNREFUSED)

It looks like the api.dnsimple.com is interpreted as a path component, and assumes http and port 80.

To ensure https as the default scheme, this PR adds nominal normalization for the base_url when passed as an option. It also coerces "" to nil, to results in the fallback/default base_url. This doesn't change the normalization for base_url on the client. It only adds it to the options[:base_url] which is passed to the client.


Full logs of this error are below:

reproduction demo-user-$ cat Gemfile
gem "dnsimple", path: '../dnsimple-ruby'
reproduction demo-user-$ bundle exec irb
irb(main):001> require 'dnsimple'
=> true
irb(main):002> client = Dnsimple::Client.new base_url: 'api.dnsimple.com'
=> 
#<Dnsimple::Client:0x00007f4159b101b0
...
irb(main):003> client.identity.whoami
/home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1603:in `initialize': Failed to open TCP connection to :80 (Connection refused - connect(2) for nil port 80) (Errno::ECONNREFUSED)
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1603:in `open'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1603:in `block in connect'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/timeout.rb:186:in `block in timeout'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/timeout.rb:193:in `timeout'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1601:in `connect'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1580:in `do_start'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1569:in `start'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:2297:in `request'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty/request.rb:156:in `perform'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty.rb:611:in `perform_request'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty.rb:521:in `get'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty.rb:644:in `get'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client.rb:199:in `request'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client.rb:164:in `execute'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client.rb:110:in `get'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client/identity.rb:15:in `whoami'
        ... 20 levels...
/home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1603:in `initialize': Connection refused - connect(2) for nil port 80 (Errno::ECONNREFUSED)
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1603:in `open'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1603:in `block in connect'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/timeout.rb:186:in `block in timeout'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/timeout.rb:193:in `timeout'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1601:in `connect'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1580:in `do_start'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:1569:in `start'
        from /home/demo-user/.rubies/ruby-3.3.0/lib/ruby/3.3.0/net/http.rb:2297:in `request'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty/request.rb:156:in `perform'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty.rb:611:in `perform_request'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty.rb:521:in `get'
        from /home/demo-user/.gem/ruby/3.3.0/gems/httparty-0.22.0/lib/httparty.rb:644:in `get'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client.rb:199:in `request'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client.rb:164:in `execute'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client.rb:110:in `get'
        from /home/demo-user/projects/dnsimple-ruby/lib/dnsimple/client/identity.rb:15:in `whoami'
        ... 20 levels...

mweitzel avatar Sep 12 '24 18:09 mweitzel