stephenpearson / kitchen-oci

Kitchen driver for Oracle Cloud Infrastructure
Other
12 stars 9 forks source link

Environmentally based no_proxy variable causes nil variable error. #24

Closed biz812 closed 5 months ago

biz812 commented 4 years ago

Line 144 of oci.rb attempts to find the proxy settings using URI.parse like so:

URI.parse('http://').find_proxy

This is fine unless there is a no_proxy environment variable set. The existence of this env var causes the following code in URI::generic to trigger:

      name = 'no_proxy'
      if no_proxy = env[name] || env[name.upcase]
        return nil unless URI::Generic.use_proxy?(self.hostname, addr, self.port, no_proxy)
      end
      URI.parse(proxy_uri)
    end

    def self.use_proxy?(hostname, addr, port, no_proxy) # :nodoc:
      hostname = hostname.downcase
      dothostname = ".#{hostname}"
      no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) {|p_host, p_port|
        if !p_port || port == p_port.to_i
          if p_host.start_with?('.')
            return false if hostname.end_with?(p_host.downcase)
          else
            return false if dothostname.end_with?(".#{p_host.downcase}")
          end
          if addr
            begin
              return false if IPAddr.new(p_host).include?(addr)
            rescue IPAddr::InvalidAddressError
              next
            end
          end
        end
      }
      true
    end

Because URI.parse is called with just 'http://' the hostname.downcase element of this code fails with NoMethodError (undefined methoddowncase' for nil:NilClass)`

This could be resolved by doing something like this instead:

URI.parse('http://example.com').find_proxy

Although I'm a sysadmin not a developer so I'm not sure if that is the right solution.

justintsteele commented 6 months ago

confirmed this fix. will include in the upcoming release. thanks for submitting this.

justintsteele commented 6 months ago

interestingly, upon testing this, it works on Linux, but on Windows, the instance is able to provision, but the transport service never gets an ack back on the wait_until_ready so it just hangs indefinitely (until timeout). I will include the fix describe above, but will also add validation that warns the user that an environment proxy is set and behavior may be unpredictable.

justintsteele commented 6 months ago

it appears that because the final message from instance.transport.connection(state).wait_until_ready is using the IP address from the state obviously enough, i had to include the IP address (first 3 octets was sufficient) to my no_proxy environment variable and that allowed it to complete.