只有当每次尝试都针对该端点创建一个配置好的客户端时,代理列表才会真正有用。要经由未认证的 HTTP 代理发送 GET,可以这样使用 Net::HTTP:

require 'net/http'

uri = URI('https://www.example.com/status')
proxies = ['http://proxy-a.example:8080',
           'http://proxy-b.example:8080']

proxies.each do |value|
  proxy = URI(value)
  http = Net::HTTP.new(uri.host, uri.port, proxy.host, proxy.port)
  http.use_ssl = uri.scheme == 'https'
  http.open_timeout = 5
  http.read_timeout = 10
  begin
    response = http.get(uri.request_uri)
    puts "#{proxy.host}:#{proxy.port} #{response.code}"
    break if response.is_a?(Net::HTTPSuccess)
  rescue Net::OpenTimeout, Net::ReadTimeout, SocketError, SystemCallError, IOError => error
    warn "#{proxy.host}:#{proxy.port} #{error.class}"
  end
end

第四个参数选择代理端口;uri.host 和 uri.port 仍指向目标。通过未认证的 HTTP 端点检查允许的公开 URL 时,请从HTTP 代理列表中填入示例里的两个条目。request_uri 会保留路径和查询。示例会处理常见的连接与读取失败,并在收到 HTTP 状态时记录下来。

这里的任何 2xx 响应都会结束这次查找。如果你的操作期待另一种结果,就请明确定义该判据。重定向并不能自动证明已经取到了想要的页面。

自动重试要与方法相匹配。POST 在正文发出后超时,远端应用可能已经被改动;换一个代理再试可能重复这一效果。GET 示例并不承诺对任意事务都能安全重放。

相关文章