Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to send proxy params. #27

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

ryanfox1985
Copy link
Contributor

Hello,

according with this documentation:
https://www.rubydoc.info/stdlib/net/Net%2FHTTP.start

The opts parameters are not send in a correct order, also is not allowed to request though a proxy.

Regards.

@gaffneyc
Copy link
Member

@ryanfox1985 Thank you for the pull request.

Is there a reason you're unable to use the http_proxy environment variable and need it implemented at the client level? Want to make sure I understand before moving forward.

@ryanfox1985
Copy link
Contributor Author

@gaffneyc is not possible to use the http_proxy because right now is not calling with the good parameters to the method start.

Here you have the link to the documentation https://www.rubydoc.info/stdlib/net/Net%2FHTTP.start to review.

The propose of this PR is resolve this issue with the parameters.

@ryanfox1985
Copy link
Contributor Author

ryanfox1985 commented Apr 29, 2020

the current code is overriding the p_addr => HTTP.start(address, port=nil, p_addr=:ENV, p_port=nil, p_user=nil, p_pass=nil, opt, &block)

And removes the default value :ENV

@ryanfox1985
Copy link
Contributor Author

My proposal fixes the parameters order and allows more flexibility to configure the proxy passing options.

@gaffneyc
Copy link
Member

Trying to find documentation for it but I believe Ruby will automatically use the http_proxy environment variable when set even if you don't pass a param to HTTP.start

@gaffneyc
Copy link
Member

@ryanfox1985 Here is the documentation https://ruby-doc.org/stdlib-2.7.1/libdoc/net/http/rdoc/Net/HTTP.html#class-Net::HTTP-label-Proxies

It seems like you should be able to do this to use a proxy:

export http_proxy=http://your.proxy:port
ruby script.rb

@ryanfox1985
Copy link
Contributor Author

ryanfox1985 commented Apr 29, 2020

@gaffneyc not working your proposal with the current code:

Net::HTTP.start(uri.host, uri.port, opts) do |http|

...

opts = hash { with timeouts... }

The current code overrides the parameter p_addr (with a default value :ENV) for opts that is a hash and its the 7th parameter, look the api doc for #start method.

HTTP.start(address, port=nil, p_addr=:ENV, p_port=nil, p_user=nil, p_pass=nil, opt, &block)

https://www.rubydoc.info/stdlib/net/Net%2FHTTP.start

@ryanfox1985
Copy link
Contributor Author

The current code sends p_addr = opts, it's wrong

@gaffneyc
Copy link
Member

@ryanfox1985 The signature for HTTP.start changes based on the number of arguments passed in. It will always treat the last item in the list, if it's a Hash, as the opt param. I've included the source below. On the first line it checks if the last argument is a hash and extracts it from the argument list.

At least in this case, the call to HTTP.start is correct and does work as is.

The question I have: for your use case do you need to pass in the proxy params?

def HTTP.start(address, *arg, &block)
  arg.pop if opt = Hash.try_convert(arg[-1])
  port, p_addr, p_port, p_user, p_pass = *arg
  p_addr = :ENV if arg.size < 2
  port = https_default_port if !port && opt && opt[:use_ssl]
  http = new(address, port, p_addr, p_port, p_user, p_pass)
  http.ipaddr = opt[:ipaddr] if opt && opt[:ipaddr]

  if opt
    if opt[:use_ssl]
      opt = {verify_mode: OpenSSL::SSL::VERIFY_PEER}.update(opt)
    end
    http.methods.grep(/\A(\w+)=\z/) do |meth|
      key = $1.to_sym
      opt.key?(key) or next
      http.__send__(meth, opt[key])
    end
  end

  http.start(&block)
end

@gaffneyc
Copy link
Member

@ryanfox1985 I mentioned the http_proxy environment variable and wanted to test it to make sure it works.

Using tinyproxy I was able to set up a local HTTP proxy that logged requests. (Using tinyproxy -d).

I then ran the below code to test that http_proxy worked and was able to see requests going through the proxy.

http_proxy=http://127.0.0.1:8888 DMS_API_KEY=[key here] ruby examples/api.rb

I was then able to see in the tinyproxy logs that it was connecting through the proxy

CONNECT   Apr 29 14:24:43 [15325]: Connect (file descriptor 10): localhost [127.0.0.1]
CONNECT   Apr 29 14:24:43 [15325]: Request (file descriptor 10): CONNECT api.deadmanssnitch.com:443 HTTP/1.1
INFO      Apr 29 14:24:43 [15325]: No upstream proxy for api.deadmanssnitch.com
INFO      Apr 29 14:24:43 [15325]: opensock: opening connection to api.deadmanssnitch.com:443
INFO      Apr 29 14:24:43 [15325]: opensock: getaddrinfo returned for api.deadmanssnitch.com:443
CONNECT   Apr 29 14:24:43 [15325]: Established connection to host "api.deadmanssnitch.com" using file descriptor 11.
INFO      Apr 29 14:24:43 [15325]: Not sending client headers to remote machine
INFO      Apr 29 14:24:44 [15325]: Closed connection between local client (fd:10) and remote client (fd:11)

@ryanfox1985
Copy link
Contributor Author

ryanfox1985 commented Apr 29, 2020

@gaffneyc I reviewed the source and you are right.

The first line removes the last argument if it's a hash: arg.pop if opt = Hash.try_convert(arg[-1])
and this line forces the p_addr => p_addr = :ENV if arg.size < 2 because the only argument is the port.

Finally I discovered my problem, we have ruby 2.1.3 and the net library not sets p_addr, leaves as a nil and not as a :ENV:

image

Here you can check the source => https://apidock.com/ruby/v2_1_10/Net/HTTP/start/class

@gaffneyc
Copy link
Member

@ryanfox1985 Hm... okay. Ruby 2.1 is really old at this point. Are you using Snitcher inside an application or from the command line with the system default ruby?

@gaffneyc
Copy link
Member

Found the feature request for http_proxy support and it looks like it should work for Ruby 2.0 and newer. I will see if I can test it against Ruby 2.1.

@gaffneyc
Copy link
Member

After some more testing it looks like the http_proxy environment variable wasn't supported until Ruby 2.5

lib/snitcher.rb Outdated
use_ssl: use_ssl?(uri),
}
[
options.fetch(:p_addr, :ENV),
Copy link
Contributor Author

@ryanfox1985 ryanfox1985 Apr 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My PR starts to have sense for ruby < 2.5

Maybe I can detect the ruby version here and sets:

  • nil for Ruby < 2.5
  • :ENV for Ruby >= 2.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants