* lib/net/http.rb: merge Ruby-SSPI patch contributed by Justin Bailey.

* ext/Win32API/lib/win32/sspi.rb: new file.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12081 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
aamine 2007-03-16 13:17:10 +00:00
parent 30aa46db0b
commit ae2c8b45d2
3 changed files with 387 additions and 16 deletions

View file

@ -1,8 +1,8 @@
#
# = net/http.rb
#
# Copyright (c) 1999-2006 Yukihiro Matsumoto
# Copyright (c) 1999-2006 Minero Aoki
# Copyright (c) 1999-2007 Yukihiro Matsumoto
# Copyright (c) 1999-2007 Minero Aoki
# Copyright (c) 2001 GOTOU Yuuzou
#
# Written and maintained by Minero Aoki <aamine@loveruby.net>.
@ -1035,27 +1035,32 @@ module Net #:nodoc:
}
end
if proxy_user()
unless use_ssl?
req.proxy_basic_auth proxy_user(), proxy_pass()
end
req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
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)
res.reading_body(@socket, req.response_body_permitted?) {
yield res if block_given?
}
end_transport req, res
res = transport_request(req, &block)
if sspi_auth?(res)
sspi_auth(req)
res = transport_request(req, &block)
end
res
end
private
def transport_request(req)
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)
res.reading_body(@socket, req.response_body_permitted?) {
yield res if block_given?
}
end_transport req, res
res
end
def begin_transport(req)
if @socket.closed?
connect
@ -1096,6 +1101,34 @@ module Net #:nodoc:
(@curr_http_version == '1.1')
end
def sspi_auth?(res)
return false unless @sspi_enabled
if res.kind_of?(HTTPProxyAuthenticationRequired) and
proxy? and res["Proxy-Authenticate"].include?("Negotiate")
begin
require 'win32/sspi'
true
rescue LoadError
false
end
else
false
end
end
def sspi_auth(req)
n = Win32::SSPI::NegotiateAuth.new
req["Proxy-Authorization"] = "Negotiate #{n.get_initial_token}"
# Some versions of ISA will close the connection if this isn't present.
req["Connection"] = "Keep-Alive"
req["Proxy-Connection"] = "Keep-Alive"
res = transport_request(req)
authphrase = res["Proxy-Authenticate"] or return res
req["Proxy-Authorization"] = "Negotiate #{n.complete_authentication(authphrase)}"
rescue => err
raise HTTPAuthenticationError.new('HTTP authentication failed', err)
end
#
# utils
#