diff --git a/CHANGELOG.md b/CHANGELOG.md index 872df8c..1139408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### 2.2.0 (edge) + +* Feature: [#108](https://github.com/savonrb/httpi/pull/108) Make `rubyntlm` gem, an optional dependency. + ### 2.1.0 (2013-07-22) * Feature: [#75](https://github.com/savonrb/httpi/pull/75) Rack adapter. diff --git a/httpi.gemspec b/httpi.gemspec index 2f1bc6e..b2a2e5e 100644 --- a/httpi.gemspec +++ b/httpi.gemspec @@ -16,12 +16,12 @@ Gem::Specification.new do |s| s.license = 'MIT' s.add_dependency 'rack' - s.add_dependency 'rubyntlm', '~> 0.3.2' - s.add_development_dependency 'rake', '~> 10.0' - s.add_development_dependency 'rspec', '~> 2.12' - s.add_development_dependency 'mocha', '~> 0.13' - s.add_development_dependency 'puma', '~> 2.3.2' + s.add_development_dependency 'rubyntlm', '~> 0.3.2' + s.add_development_dependency 'rake', '~> 10.0' + s.add_development_dependency 'rspec', '~> 2.12' + s.add_development_dependency 'mocha', '~> 0.13' + s.add_development_dependency 'puma', '~> 2.3.2' s.files = `git ls-files`.split("\n") s.require_path = 'lib' diff --git a/lib/httpi/adapter/net_http.rb b/lib/httpi/adapter/net_http.rb index 9ad8ea0..59d8f96 100644 --- a/lib/httpi/adapter/net_http.rb +++ b/lib/httpi/adapter/net_http.rb @@ -2,10 +2,18 @@ require "httpi/adapter/base" require "httpi/response" -require 'net/ntlm' require 'kconv' require 'socket' +begin + require 'net/ntlm' + unless Net::NTLM::VERSION::STRING >= '0.3.2' + raise ArgumentError('Invalid version of rubyntlm. Please use v0.3.2+.') + end +rescue LoadError => e + HTTPI.logger.debug('Net::NTLM is not available. Install via gem install rubyntlm.') +end + module HTTPI module Adapter @@ -76,6 +84,10 @@ def setup end def negotiate_ntlm_auth(http, &requester) + unless Net.const_defined?(:NTLM) + HTTPI.logger.fatal('Cannot negotiate ntlm auth if net/ntlm is not present. Perhaps the net/ntlm gem is not installed?') + end + # first figure out if we should use NTLM or Negotiate nego_auth_response = respond_with(requester.call(http, request_client(:head))) if nego_auth_response.headers['www-authenticate'].include? 'Negotiate' @@ -102,7 +114,7 @@ def negotiate_ntlm_auth(http, &requester) if auth_response.headers["WWW-Authenticate"] =~ /(NTLM|Negotiate) (.+)/ auth_token = $2 ntlm_message = Net::NTLM::Message.decode64(auth_token) - + message_builder = {} # copy the username and password from the authorization parameters message_builder[:user] = @request.auth.ntlm[0] @@ -114,7 +126,7 @@ def negotiate_ntlm_auth(http, &requester) else message_builder[:domain] = '' end - + ntlm_response = ntlm_message.response(message_builder , {:ntlmv2 => true}) # Finally add header of Authorization diff --git a/lib/httpi/version.rb b/lib/httpi/version.rb index 7343db1..3faa245 100644 --- a/lib/httpi/version.rb +++ b/lib/httpi/version.rb @@ -1,5 +1,5 @@ module HTTPI - VERSION = "2.1.0" + VERSION = "2.2.0" end diff --git a/spec/httpi/adapter/net_http_spec.rb b/spec/httpi/adapter/net_http_spec.rb index f2bc65d..caa50b3 100644 --- a/spec/httpi/adapter/net_http_spec.rb +++ b/spec/httpi/adapter/net_http_spec.rb @@ -75,6 +75,17 @@ response = HTTPI.get(request, adapter) response.body.should eq("ntlm-auth") end + + it 'fatal logs when net/ntlm is not available, but ntlm authentication was requested' do + Net.expects(:const_defined?).with(:NTLM).returns false + + request = HTTPI::Request.new(@server.url + 'ntlm-auth') + request.auth.ntlm("testing", "failures") + HTTPI.logger.expects(:fatal) + + response = HTTPI.get(request, adapter) + response.body.should eq("ntlm-auth") + end end # it does not support digest auth