如何只为一个方法而不是全局设置 TCPSocket 属性?

How do I set TCPSocket attributes for only a method and not globally?

我正在使用 Rails 4.2.7 和 Ruby 2.3.0。我有通过 SOCKS 代理获取网页的代码

require "resolv-replace.rb"
require 'open-uri'
require 'uri'
require "socksify"
require 'socksify/http'
...

  def get_content_via_socks(socks_server, socks_port, url, headers)
    TCPSocket::socks_server = socks_server
    TCPSocket::socks_port = socks_port 
    uri = URI(url)
    res1 = Net::HTTP.SOCKSProxy(nil, nil).start(uri.host, uri.port, :use_ssl => (uri.scheme == "https")) do |http|
      http.read_timeout = 500
      puts "launching #{uri} on #{socks_server}:#{socks_port}"
      resp = http.get(uri, initheader = headers)
    end
  end

唯一的问题是即使我已经设置

    TCPSocket::socks_server = socks_server
    TCPSocket::socks_port = socks_port 

在我的本地方法中,它似乎影响了整个应用程序。那是我打电话给

http         = Net::HTTP.new(uri.host, uri.port)

从另一个方法,它失败,除非上面的socks_server和socks_port是运行。如何仅为该方法设置 socks_server 和 socks_port 而不影响应用程序的其余部分?请不要在这里说设置参数

res1 = Net::HTTP.SOCKSProxy(nil, nil)

这些参数没有意义。您可以将它们设置为 "abc" 和 "def",它们的行为与将它们设置为有效值时的行为完全相同。

编辑:包括我的 Gemfile

source 'https://rubygems.org'

gem 'rails', '~> 5.0.1'
# Use SCSS for stylesheets
gem 'sass-rails'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
#gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'

gem 'addressable'
gem 'pg'
gem 'pundit'
gem 'omniauth-oauth2', '~> 1.3.1'
gem 'omniauth-google-oauth2'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-linkedin-oauth2'
gem 'jquery-ui-rails'
#gem 'jquery-cookie-rails'
gem 'will_paginate'
gem 'bootstrap-sass'
gem 'autoprefixer-rails'
gem 'compass-rails'
gem 'pdf-reader'
gem 'jquery-turbolinks'
gem 'activerecord-import'
gem 'w3c_validators'
gem 'whenever', :require => false
gem 'roo-xls'
gem 'socksify'

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platform: :mri
end

group :development do
  # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
  gem 'web-console'
  gem 'listen', '~> 3.0.5'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :production do
  gem 'unicorn'
  gem 'puma'
end

备注

Please don't say set the parameters here

res1 = Net::HTTP.SOCKSProxy(nil, nil)

抱歉,我不得不说您应该设置这些参数。 :)

在设置 TCPSocket::socks_server 时我无法让你的示例工作,但在使用 Net::HTTP.SOCKSProxy(socks_server, socks_port) 时它工作得很好。

我用过:

$ ruby -v && gem list socksify
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
*** LOCAL GEMS ***
socksify (1.7.0)

设置

在 linux 客户端上,我使用这些命令连接到两个 linux 服务器,同时在 2 个不同的终端中:

ssh -D 1085 linux_server1 -N
ssh -D 1084 linux_server2 -N

我的客户端现在有 2 个 Socks 代理,运行 在端口 1084 和 1085 上。

测试

这些方法连接到 [http://whatismyip.akamai.com][1] 以检查是否正在使用 SOCKS 代理。

require 'socket'
require 'socksify'
require 'socksify/http'
require 'uri'
require 'net/http'

def translate_ips(str)
  my_ips = {
    "XXX.XXX.XXX.XXX" => 'local_ip  :(',
    "YYY.YYY.YYY.YYY" => 'socks_ip1 :D',
    "ZZZ.ZZZ.ZZZ.ZZZ" => 'socks_ip2 :D'
  }
  str.gsub(/\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}/,my_ips)
end

def get_content_via_socks_v1(socks_server, socks_port, url, headers)
  TCPSocket::socks_server = socks_server
  TCPSocket::socks_port = socks_port 
  uri = URI(url)
  res1 = Net::HTTP.SOCKSProxy(nil, nil).start(uri.host, uri.port, :use_ssl => (uri.scheme == "https")) do |http|
    http.read_timeout = 500
    puts "launching #{uri} on #{socks_server}:#{socks_port}"
    resp = http.get(uri, initheader = headers)
  end
end

def get_content_via_socks_v2(socks_server, socks_port, url, headers)
  uri = URI(url)
  Net::HTTP.SOCKSProxy(socks_server, socks_port).start(uri.host, uri.port, use_ssl: (uri.scheme == 'https')) do |http|
    http.read_timeout = 500
    puts "launching #{uri} on #{socks_server}:#{socks_port}"
    http.get(uri, headers)
  end
end

puts translate_ips(get_content_via_socks_v1('localhost', 1085, 'http://whatismyip.akamai.com', nil).body)
puts translate_ips(get_content_via_socks_v1('localhost', 1084, 'http://whatismyip.akamai.com', nil).body)
puts
puts translate_ips(get_content_via_socks_v2('localhost', 1085, 'http://whatismyip.akamai.com', nil).body)
puts translate_ips(get_content_via_socks_v2('localhost', 1084, 'http://whatismyip.akamai.com', nil).body)

它输出:

launching http://whatismyip.akamai.com on localhost:1085
local_ip  :(
launching http://whatismyip.akamai.com on localhost:1084
local_ip  :(

launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D

Net::HTTP.SOCKSProxy(socks_server, socks_port) 版本工作得很好!

如果我尝试使用 Net::HTTP.SOCKSProxy("bogus", "bogus"),该方法会引发异常:

in `rescue in block in connect': Failed to open TCP connection to whatismyip.akamai.com:80 (getaddrinfo: Servname not supported for ai_socktype) (SocketError)

多线程

在方法的开头设置 TCPSocket::socks_server 不是线程安全的。

Net::HTTP.SOCKSProxy 与块一起使用应该可以防止竞争条件:

threads = []
10.times do
  sleep 0.1
  threads << Thread.new { puts translate_ips(get_content_via_socks_v2('localhost', 1085, 'http://whatismyip.akamai.com', nil).body)}
  threads << Thread.new { puts translate_ips(get_content_via_socks_v2('localhost', 1084, 'http://whatismyip.akamai.com', nil).body)}
end

threads.join

它输出:

launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D
launching http://whatismyip.akamai.com on localhost:1084
socks_ip2 :D
launching http://whatismyip.akamai.com on localhost:1085
socks_ip1 :D

用你的 Gemfile 测试

ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

你的 Gemfile 在 Linux Mint 17 上,上面的脚本在使用

启动时运行良好
rails runner get_content_via_socks.rb

我创建了一个空的 Gemset 并且只添加了您的宝石。结果 Gemfile.lock 是:

GEM
  remote: https://rubygems.org/
  specs:
    Ascii85 (1.0.2)
    actioncable (5.0.1)
      actionpack (= 5.0.1)
      nio4r (~> 1.2)
      websocket-driver (~> 0.6.1)
    actionmailer (5.0.1)
      actionpack (= 5.0.1)
      actionview (= 5.0.1)
      activejob (= 5.0.1)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 2.0)
    actionpack (5.0.1)
      actionview (= 5.0.1)
      activesupport (= 5.0.1)
      rack (~> 2.0)
      rack-test (~> 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    actionview (5.0.1)
      activesupport (= 5.0.1)
      builder (~> 3.1)
      erubis (~> 2.7.0)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    activejob (5.0.1)
      activesupport (= 5.0.1)
      globalid (>= 0.3.6)
    activemodel (5.0.1)
      activesupport (= 5.0.1)
    activerecord (5.0.1)
      activemodel (= 5.0.1)
      activesupport (= 5.0.1)
      arel (~> 7.0)
    activerecord-import (0.16.2)
      activerecord (>= 3.2)
    activesupport (5.0.1)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (~> 0.7)
      minitest (~> 5.1)
      tzinfo (~> 1.1)
    addressable (2.5.0)
      public_suffix (~> 2.0, >= 2.0.2)
    afm (0.2.2)
    arel (7.1.4)
    autoprefixer-rails (6.6.1)
      execjs
    bootstrap-sass (3.3.7)
      autoprefixer-rails (>= 5.2.1)
      sass (>= 3.3.4)
    builder (3.2.3)
    byebug (9.0.6)
    chronic (0.10.2)
    chunky_png (1.3.8)
    coffee-rails (4.2.1)
      coffee-script (>= 2.2.0)
      railties (>= 4.0.0, < 5.2.x)
    coffee-script (2.4.1)
      coffee-script-source
      execjs
    coffee-script-source (1.12.2)
    compass (1.0.3)
      chunky_png (~> 1.2)
      compass-core (~> 1.0.2)
      compass-import-once (~> 1.0.5)
      rb-fsevent (>= 0.9.3)
      rb-inotify (>= 0.9)
      sass (>= 3.3.13, < 3.5)
    compass-core (1.0.3)
      multi_json (~> 1.0)
      sass (>= 3.3.0, < 3.5)
    compass-import-once (1.0.5)
      sass (>= 3.2, < 3.5)
    compass-rails (3.0.2)
      compass (~> 1.0.0)
      sass-rails (< 5.1)
      sprockets (< 4.0)
    concurrent-ruby (1.0.4)
    debug_inspector (0.0.2)
    erubis (2.7.0)
    execjs (2.7.0)
    faraday (0.10.1)
      multipart-post (>= 1.2, < 3)
    ffi (1.9.17)
    globalid (0.3.7)
      activesupport (>= 4.1.0)
    hashery (2.1.2)
    hashie (3.4.6)
    i18n (0.7.0)
    jquery-rails (4.2.2)
      rails-dom-testing (>= 1, < 3)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    jquery-turbolinks (2.1.0)
      railties (>= 3.1.0)
      turbolinks
    jquery-ui-rails (6.0.1)
      railties (>= 3.2.16)
    json (2.0.3)
    jwt (1.5.6)
    kgio (2.11.0)
    libv8 (3.16.14.17)
    listen (3.0.8)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
    loofah (2.0.3)
      nokogiri (>= 1.5.9)
    mail (2.6.4)
      mime-types (>= 1.16, < 4)
    method_source (0.8.2)
    mime-types (3.1)
      mime-types-data (~> 3.2015)
    mime-types-data (3.2016.0521)
    mini_portile2 (2.1.0)
    minitest (5.10.1)
    multi_json (1.12.1)
    multi_xml (0.6.0)
    multipart-post (2.0.0)
    nio4r (1.2.1)
    nokogiri (1.7.0.1)
      mini_portile2 (~> 2.1.0)
    oauth (0.5.1)
    oauth2 (1.3.0)
      faraday (>= 0.8, < 0.11)
      jwt (~> 1.0)
      multi_json (~> 1.3)
      multi_xml (~> 0.5)
      rack (>= 1.2, < 3)
    omniauth (1.3.1)
      hashie (>= 1.2, < 4)
      rack (>= 1.0, < 3)
    omniauth-facebook (4.0.0)
      omniauth-oauth2 (~> 1.2)
    omniauth-google-oauth2 (0.4.1)
      jwt (~> 1.5.2)
      multi_json (~> 1.3)
      omniauth (>= 1.1.1)
      omniauth-oauth2 (>= 1.3.1)
    omniauth-linkedin-oauth2 (0.1.5)
      omniauth (~> 1.0)
      omniauth-oauth2
    omniauth-oauth (1.1.0)
      oauth
      omniauth (~> 1.0)
    omniauth-oauth2 (1.3.1)
      oauth2 (~> 1.0)
      omniauth (~> 1.2)
    omniauth-twitter (1.3.0)
      omniauth-oauth (~> 1.1)
      rack
    pdf-reader (1.4.1)
      Ascii85 (~> 1.0.0)
      afm (~> 0.2.1)
      hashery (~> 2.0)
      ruby-rc4
      ttfunk
    pg (0.19.0)
    public_suffix (2.0.5)
    puma (3.6.2)
    pundit (1.1.0)
      activesupport (>= 3.0.0)
    rack (2.0.1)
    rack-test (0.6.3)
      rack (>= 1.0)
    rails (5.0.1)
      actioncable (= 5.0.1)
      actionmailer (= 5.0.1)
      actionpack (= 5.0.1)
      actionview (= 5.0.1)
      activejob (= 5.0.1)
      activemodel (= 5.0.1)
      activerecord (= 5.0.1)
      activesupport (= 5.0.1)
      bundler (>= 1.3.0, < 2.0)
      railties (= 5.0.1)
      sprockets-rails (>= 2.0.0)
    rails-dom-testing (2.0.2)
      activesupport (>= 4.2.0, < 6.0)
      nokogiri (~> 1.6)
    rails-html-sanitizer (1.0.3)
      loofah (~> 2.0)
    railties (5.0.1)
      actionpack (= 5.0.1)
      activesupport (= 5.0.1)
      method_source
      rake (>= 0.8.7)
      thor (>= 0.18.1, < 2.0)
    raindrops (0.17.0)
    rake (12.0.0)
    rb-fsevent (0.9.8)
    rb-inotify (0.9.7)
      ffi (>= 0.5.0)
    ref (2.0.0)
    roo (2.7.1)
      nokogiri (~> 1)
      rubyzip (~> 1.1, < 2.0.0)
    roo-xls (1.0.0)
      nokogiri
      roo (>= 2.0.0beta1, < 3)
      spreadsheet (> 0.9.0)
    ruby-ole (1.2.12)
    ruby-rc4 (0.1.5)
    rubyzip (1.2.0)
    sass (3.4.23)
    sass-rails (5.0.6)
      railties (>= 4.0.0, < 6)
      sass (~> 3.1)
      sprockets (>= 2.8, < 4.0)
      sprockets-rails (>= 2.0, < 4.0)
      tilt (>= 1.1, < 3)
    socksify (1.7.0)
    spreadsheet (1.1.4)
      ruby-ole (>= 1.0)
    spring (2.0.0)
      activesupport (>= 4.2)
    spring-watcher-listen (2.0.1)
      listen (>= 2.7, < 4.0)
      spring (>= 1.2, < 3.0)
    sprockets (3.7.1)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-rails (3.2.0)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    therubyracer (0.12.3)
      libv8 (~> 3.16.14.15)
      ref
    thor (0.19.4)
    thread_safe (0.3.5)
    tilt (2.0.5)
    ttfunk (1.4.0)
    turbolinks (5.0.1)
      turbolinks-source (~> 5)
    turbolinks-source (5.0.0)
    tzinfo (1.2.2)
      thread_safe (~> 0.1)
    uglifier (3.0.4)
      execjs (>= 0.3.0, < 3)
    unicorn (5.2.0)
      kgio (~> 2.6)
      raindrops (~> 0.7)
    w3c_validators (1.3.1)
      json (~> 2.0)
      nokogiri (~> 1.6)
    web-console (3.4.0)
      actionview (>= 5.0)
      activemodel (>= 5.0)
      debug_inspector
      railties (>= 5.0)
    websocket-driver (0.6.4)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.2)
    whenever (0.9.7)
      chronic (>= 0.6.3)
    will_paginate (3.1.5)

PLATFORMS
  ruby

DEPENDENCIES
  activerecord-import
  addressable
  autoprefixer-rails
  bootstrap-sass
  byebug
  coffee-rails
  compass-rails
  jquery-rails
  jquery-turbolinks
  jquery-ui-rails
  listen (~> 3.0.5)
  omniauth-facebook
  omniauth-google-oauth2
  omniauth-linkedin-oauth2
  omniauth-oauth2 (~> 1.3.1)
  omniauth-twitter
  pdf-reader
  pg
  puma
  pundit
  rails (~> 5.0.1)
  roo-xls
  sass-rails
  socksify
  spring
  spring-watcher-listen (~> 2.0.0)
  therubyracer
  turbolinks
  uglifier
  unicorn
  w3c_validators
  web-console
  whenever
  will_paginate

BUNDLED WITH
   1.13.7





  [1]: http://whatismyip.akamai.com