class HTTPClient::SSPINegotiateAuth

def get(req)

See win32/sspi for negotiation state transition.
Response handler: returns credential.
def get(req)
  target_uri = req.header.request_uri
  synchronize {
    domain_uri, param = @challenge.find { |uri, v|
      Util.uri_part_of(target_uri, uri)
    }
    return nil unless param
    Util.try_require('win32/sspi') || Util.try_require('gssapi') || return
    state = param[:state]
    authenticator = param[:authenticator]
    authphrase = param[:authphrase]
    case state
    when :init
      if defined?(Win32::SSPI)
        authenticator = param[:authenticator] = Win32::SSPI::NegotiateAuth.new
        authenticator.get_initial_token(@scheme)
      else # use GSSAPI
        authenticator = param[:authenticator] = GSSAPI::Simple.new(domain_uri.host, 'HTTP')
        # Base64 encode the context token
        [authenticator.init_context].pack('m').gsub(/\n/,'')
      end
    when :response
      @challenge[target_uri][:state] = :done
      if defined?(Win32::SSPI)
        authenticator.complete_authentication(authphrase)
      else # use GSSAPI
        authenticator.init_context(authphrase.unpack('m').pop)
      end
    when :done
      :skip
    else
      nil
    end
  }
end