如何让Rubysspi 1.3.1与Ruby 1.9.3和Selenium-Webdriver一起使用

时间:2014-08-15 15:23:35

标签: ruby proxy ntlm

我最近从ruby 1.8.7迁移到ruby 1.9.3并且无法退出我的代理。从命令行安装gems工作正常,但是在运行'apply_sspi_patch'后,readme提到了应该修补http.rb文件,并运行'test_patched_net_http.rb'测试文件,我看到了:

  1) Error:
test_net_http(PatchedRubyTest):
ArgumentError: Error occurred during proxy negotiation. req: nil; res: #<Net::HTTPProxyAuthenticationRequired 407 Proxy Authentication Required readbody=true>; Original message: wrong number of arguments (1 for 0)
    C:/ruby/lib/ruby/gems/1.9.1/gems/rubysspi-1.3.1/lib/win32/sspi/http_proxy_patch.rb:76:in `request'
    test_patched_net_http.rb:33:in `block in test_net_http'
    test_patched_net_http.rb:32:in `test_net_http'

这对应于行req["Proxy-Authorization"] = "#{tok} #{n.get_initial_token(tok)}" n是n = Win32::SSPI::NegotiateAuth.new。 NegotiateAuth类确实需要1个参数。

我将http_proxy_patch.rb文件需要从require 'win32/sspi'更新为require 'C:\ruby\lib\ruby\gems\1.9.1\gems\rubysspi-1.3.1\lib\win32\sspi.rb'后,'test_patched_net_http.rb'测试文件通过。

现在,当我运行测试时,我偶尔会遇到类似以下错误:

RuntimeError: Error occurred during proxy negotiation. req: "NTLM BUNCH_OF_NUMBERS_AND_LETTERS=="; res: #<Net::HTTPProxyAuthenticationRequired 407 Proxy Authentication Required readbody=true>; Original message: Error: SEC_E_INTERNAL_ERROR
    C:/ruby/lib/ruby/gems/1.9.1/gems/rubysspi-1.3.1/lib/win32/sspi.rb:304:in `complete_authentication'
    C:/ruby/lib/ruby/gems/1.9.1/gems/rubysspi-1.3.1/lib/win32/sspi/http_proxy_patch.rb:91:in `request'
    C:/ruby/lib/ruby/gems/1.9.1/gems/rubysspi-1.3.1/lib/win32/sspi/http_proxy_patch.rb:57:in `block in request'
  • Ruby - ruby​​ 1.9.3p448(2013-06-27)[i386-mingw32]
  • Rubysspi - 1.3.1
  • Selenium-Webdriver - 2.42.0

1 个答案:

答案 0 :(得分:0)

我通过修改gems \ ruby​​sspi-1.3.1 \ lib \ win32 \ sspi \ http_proxy_patch.rb文件来缓解/删除了我的问题:

我在请求方法中添加了重试(jretry),现在我不再看到错误。

def request(req, body = nil, &block) # :yield: +response+
  unless started?
    start {
      req['connection'] ||= 'close'
      return request(req, body, &block)
    }
  end
  if proxy_user()
    unless use_ssl?
      req.proxy_basic_auth proxy_user(), proxy_pass()
    end
  end

  req.set_body_internal body
  begin_transport req
    req.exec @socket, @curr_http_version, edit_path(req.path)
    begin
      res = HTTPResponse.read_new(@socket)
    end while res.kind_of?(HTTPContinue)
    if tok = sspi_auth_required?(res)
      jretry = 2
      begin
        n = Win32::SSPI::NegotiateAuth.new
        res.reading_body(@socket, req.response_body_permitted?) { }
        end_transport req, res
        begin_transport req
        if proxy?
          req["Proxy-Authorization"] = "#{tok} #{n.get_initial_token(tok)}"
          req["Proxy-Connection"] = "Keep-Alive"
        else
          req["Authorization"] = "#{tok} #{n.get_initial_token(tok)}"
        end
        # Some versions of ISA will close the connection if this isn't present.
        req["Connection"] = "Keep-Alive"
        req.exec @socket, @curr_http_version, edit_path(req.path)
        begin
          res = HTTPResponse.read_new(@socket)
        end while res.kind_of?(HTTPContinue)
        if (proxy? && res["Proxy-Authenticate"]) || (! proxy? && res["WWW-Authenticate"])
          res.reading_body(@socket, req.response_body_permitted?) { }
          if proxy?
            req["Proxy-Authorization"] = "#{tok} #{n.complete_authentication res["Proxy-Authenticate"]}"
            req["Proxy-Connection"] = "Keep-Alive"
          else
            token = res["WWW-Authenticate"].split(" ").last
            req["Authorization"] = "#{tok} #{n.complete_authentication token}"
          end
          req["Connection"] = "Keep-Alive"
          req.exec @socket, @curr_http_version, edit_path(req.path)
          begin
            res = HTTPResponse.read_new(@socket)
          end while res.kind_of?(HTTPContinue)
        end
      rescue
        if jretry != 0
          jretry -= 1
          retry
        else
          exc = $!.exception("Error occurred during proxy negotiation. req: #{req["Proxy-Authorization"].inspect}; res: #{res.inspect}; Original message: #{$!.message}")
          exc.set_backtrace $!.backtrace
          raise exc
        end
      end
    end

    res.reading_body(@socket, req.response_body_permitted?) {
      yield res if block_given?
    }
  end_transport req, res

  res
end