httpi 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -132,4 +132,32 @@ describe HTTPI::Auth::Config do
132
132
  end
133
133
  end
134
134
 
135
+ describe "#ntlm" do
136
+ it "lets you specify the ntlm auth credentials" do
137
+ auth.ntlm "username", "password"
138
+ auth.ntlm.should == ["username", "password"]
139
+ end
140
+
141
+ it "also accepts an Array of credentials" do
142
+ auth.ntlm ["username", "password"]
143
+ auth.ntlm.should == ["username", "password"]
144
+ end
145
+
146
+ it "sets the authentication type to :ntlm" do
147
+ auth.ntlm "username", "password"
148
+ auth.type.should == :ntlm
149
+ end
150
+ end
151
+
152
+ describe "#ntlm?" do
153
+ it "defaults to return false" do
154
+ auth.should_not be_ntlm
155
+ end
156
+
157
+ it "returns true for HTTP ntlm auth" do
158
+ auth.ntlm "username", "password"
159
+ auth.should be_ntlm
160
+ end
161
+ end
162
+
135
163
  end
@@ -1,6 +1,10 @@
1
1
  require "spec_helper"
2
+ require "integration/support/server"
2
3
 
3
4
  # find out why httpi doesn't load these automatically. [dh, 2012-12-15]
5
+ require "excon"
6
+ require "net/http/persistent"
7
+
4
8
  unless RUBY_VERSION < "1.9"
5
9
  require "em-synchrony"
6
10
  require "em-http-request"
@@ -13,6 +17,15 @@ describe HTTPI do
13
17
  let(:client) { HTTPI }
14
18
  let(:httpclient) { HTTPI::Adapter.load(:httpclient) }
15
19
  let(:net_http) { HTTPI::Adapter.load(:net_http) }
20
+ let(:net_http_persistent) { HTTPI::Adapter.load(:net_http_persistent) }
21
+
22
+ before(:all) do
23
+ HTTPI::Adapter::Rack.mount('example.com', IntegrationServer::Application)
24
+ end
25
+
26
+ after(:all) do
27
+ HTTPI::Adapter::Rack.unmount('example.com')
28
+ end
16
29
 
17
30
  describe ".adapter=" do
18
31
  it "sets the default adapter to use" do
@@ -204,7 +217,10 @@ describe HTTPI do
204
217
  :httpclient => lambda { HTTPClient },
205
218
  :curb => lambda { Curl::Easy },
206
219
  :net_http => lambda { Net::HTTP },
207
- :em_http => lambda { EventMachine::HttpConnection }
220
+ :net_http_persistent => lambda { Net::HTTP::Persistent },
221
+ :em_http => lambda { EventMachine::HttpConnection },
222
+ :rack => lambda { Rack::MockRequest },
223
+ :excon => lambda { Excon::Connection }
208
224
  }
209
225
 
210
226
  context "using #{adapter}" do
@@ -78,6 +78,18 @@ describe HTTPI::Adapter::Curb do
78
78
  response = HTTPI.get(request, adapter)
79
79
  response.body.should eq("digest-auth")
80
80
  end
81
+
82
+ it "supports chunked response" do
83
+ request = HTTPI::Request.new(@server.url)
84
+ res = ""
85
+ request.on_body do |body|
86
+ res += body
87
+ end
88
+ response = HTTPI.post(request, adapter)
89
+ res.should eq("post")
90
+ response.body.should eq("")
91
+ end
92
+
81
93
  end
82
94
 
83
95
  context "https requests" do
@@ -81,6 +81,8 @@ describe HTTPI::Adapter::EmHttpRequest do
81
81
  end
82
82
 
83
83
  # it does not support digest authentication
84
+
85
+ # it does not support chunked response
84
86
  end
85
87
 
86
88
  # it does not support ssl authentication
@@ -75,27 +75,41 @@ describe HTTPI::Adapter::HTTPClient do
75
75
  response = HTTPI.get(request, adapter)
76
76
  response.body.should eq("digest-auth")
77
77
  end
78
- end
79
-
80
- context "https requests" do
81
- before :all do
82
- @server = IntegrationServer.run(:ssl => true)
83
- end
84
78
 
85
- after :all do
86
- @server.stop
87
- end
88
-
89
- it "raises when no certificate was set up" do
90
- expect { HTTPI.post(@server.url, "", adapter) }.to raise_error(HTTPI::SSLError)
91
- end
92
-
93
- it "works when set up properly" do
79
+ it "supports chunked response" do
94
80
  request = HTTPI::Request.new(@server.url)
95
- request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
81
+ res = ""
82
+ request.on_body do |body|
83
+ res += body
84
+ end
85
+ response = HTTPI.post(request, adapter)
86
+ res.should eq("post")
87
+ response.body.should eq("")
88
+ end
89
+ end
96
90
 
97
- response = HTTPI.get(request, adapter)
98
- expect(response.body).to eq("get")
91
+ if RUBY_PLATFORM =~ /java/
92
+ pending "Puma Server complains: SSL not supported on JRuby"
93
+ else
94
+ context "https requests" do
95
+ before :all do
96
+ @server = IntegrationServer.run(:ssl => true)
97
+ end
98
+ after :all do
99
+ @server.stop
100
+ end
101
+
102
+ it "raises when no certificate was set up" do
103
+ expect { HTTPI.post(@server.url, "", adapter) }.to raise_error(HTTPI::SSLError)
104
+ end
105
+
106
+ it "works when set up properly" do
107
+ request = HTTPI::Request.new(@server.url)
108
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
109
+
110
+ response = HTTPI.get(request, adapter)
111
+ expect(response.body).to eq("get")
112
+ end
99
113
  end
100
114
  end
101
115
 
@@ -0,0 +1,139 @@
1
+ require "spec_helper"
2
+ require "integration/support/server"
3
+
4
+ describe HTTPI::Adapter::NetHTTP do
5
+
6
+ subject(:adapter) { :net_http_persistent }
7
+
8
+ context "http requests" do
9
+ before :all do
10
+ @server = IntegrationServer.run
11
+ end
12
+
13
+ after :all do
14
+ @server.stop
15
+ end
16
+
17
+ it "sends and receives HTTP headers" do
18
+ request = HTTPI::Request.new(@server.url + "x-header")
19
+ request.headers["X-Header"] = "HTTPI"
20
+
21
+ response = HTTPI.get(request, adapter)
22
+ response.body.should include("HTTPI")
23
+ end
24
+
25
+ it "it supports headers with multiple values" do
26
+ request = HTTPI::Request.new(@server.url + "cookies")
27
+
28
+ response = HTTPI.get(request, adapter)
29
+ cookies = ["cookie1=chip1; path=/", "cookie2=chip2; path=/"]
30
+ response.headers["Set-Cookie"].should eq(cookies)
31
+ end
32
+
33
+ it "executes GET requests" do
34
+ response = HTTPI.get(@server.url, adapter)
35
+ response.body.should eq("get")
36
+ response.headers["Content-Type"].should eq("text/plain")
37
+ end
38
+
39
+ it "executes POST requests" do
40
+ response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
41
+ response.body.should eq("post")
42
+ response.headers["Content-Type"].should eq("text/plain")
43
+ end
44
+
45
+ it "executes HEAD requests" do
46
+ response = HTTPI.head(@server.url, adapter)
47
+ response.code.should == 200
48
+ response.headers["Content-Type"].should eq("text/plain")
49
+ end
50
+
51
+ it "executes PUT requests" do
52
+ response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
53
+ response.body.should eq("put")
54
+ response.headers["Content-Type"].should eq("text/plain")
55
+ end
56
+
57
+ it "executes DELETE requests" do
58
+ response = HTTPI.delete(@server.url, adapter)
59
+ response.body.should eq("delete")
60
+ response.headers["Content-Type"].should eq("text/plain")
61
+ end
62
+
63
+ it "supports basic authentication" do
64
+ request = HTTPI::Request.new(@server.url + "basic-auth")
65
+ request.auth.basic("admin", "secret")
66
+
67
+ response = HTTPI.get(request, adapter)
68
+ response.body.should eq("basic-auth")
69
+ end
70
+
71
+ # it does not support digest authentication
72
+
73
+ it "supports chunked response" do
74
+ request = HTTPI::Request.new(@server.url)
75
+ res = ""
76
+ request.on_body do |body|
77
+ res += body
78
+ end
79
+ response = HTTPI.post(request, adapter)
80
+ res.should eq("post")
81
+ response.body.to_s.should eq("")
82
+ end
83
+ end
84
+
85
+ if RUBY_PLATFORM =~ /java/
86
+ pending "Puma Server complains: SSL not supported on JRuby"
87
+ else
88
+ context "https requests" do
89
+ before :all do
90
+ @server = IntegrationServer.run(:ssl => true)
91
+ end
92
+ after :all do
93
+ @server.stop
94
+ end
95
+
96
+ # does not raise when no certificate was set up
97
+ it "works when set up properly" do
98
+ request = HTTPI::Request.new(@server.url)
99
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
100
+
101
+ response = HTTPI.get(request, adapter)
102
+ expect(response.body).to eq("get")
103
+ end
104
+ end
105
+ end
106
+
107
+ # The built-in Rack IntegrationServer and specs support a basic simulated NTLM exchange
108
+ # that does not require anything outside of the normal gem test infrastructure.
109
+ # (see spec/httpi/adapter/net_http_spec.rb: it "supports ntlm authentication"
110
+ # and spec/integration/support/application.rb: map "/ntlm-auth")
111
+ # But since that simulated exchange is based on recorded traffic, you may wish to
112
+ # run the following integration test against a real external NTLM server from time to time.
113
+ #
114
+ # This test must be specially enabled because it requires an external
115
+ # Windows 2012 Server configured according to the instructions found here:
116
+ # https://github.com/savonrb/httpi/wiki/NTLM-Integration-Test-Plan
117
+ #
118
+ # Once you have that server running as instructed, you can include this test by setting
119
+ # NTLM=external via the command line, e.g.:
120
+ # $ NTLM=external bundle exec rspec
121
+ #
122
+ if ENV["NTLM"]=="external"
123
+ context "http request via NTLM" do
124
+ it "works with NTLM connections" do
125
+ user = "tester"
126
+ pass = "vReqSoafRe5O"
127
+ request = HTTPI::Request.new("http://ntlmtest/")
128
+ request.auth.ntlm(user,pass)
129
+ response = HTTPI.get(request, adapter)
130
+ expect(response.code).to eq(200)
131
+ response.body.should match(/iis-8\.png/)
132
+
133
+ puts "EXTERNAL NTLM INTEGRATION TEST, response body:"
134
+ puts response.body
135
+ end
136
+ end
137
+ end
138
+
139
+ end
@@ -69,25 +69,70 @@ describe HTTPI::Adapter::NetHTTP do
69
69
  end
70
70
 
71
71
  # it does not support digest authentication
72
- end
73
72
 
74
- context "https requests" do
75
- before :all do
76
- @server = IntegrationServer.run(:ssl => true)
73
+ it "supports chunked response" do
74
+ request = HTTPI::Request.new(@server.url)
75
+ res = ""
76
+ request.on_body do |body|
77
+ res += body
78
+ end
79
+ response = HTTPI.post(request, adapter)
80
+ res.should eq("post")
81
+ response.body.to_s.should eq("")
77
82
  end
83
+ end
78
84
 
79
- after :all do
80
- @server.stop
85
+ if RUBY_PLATFORM =~ /java/
86
+ pending "Puma Server complains: SSL not supported on JRuby"
87
+ else
88
+ context "https requests" do
89
+ before :all do
90
+ @server = IntegrationServer.run(:ssl => true)
91
+ end
92
+ after :all do
93
+ @server.stop
94
+ end
95
+
96
+ # does not raise when no certificate was set up
97
+ it "works when set up properly" do
98
+ request = HTTPI::Request.new(@server.url)
99
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
100
+
101
+ response = HTTPI.get(request, adapter)
102
+ expect(response.body).to eq("get")
103
+ end
81
104
  end
105
+ end
82
106
 
83
- # does not raise when no certificate was set up
84
-
85
- it "works when set up properly" do
86
- request = HTTPI::Request.new(@server.url)
87
- request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
88
-
89
- response = HTTPI.get(request, adapter)
90
- expect(response.body).to eq("get")
107
+ # The built-in Rack IntegrationServer and specs support a basic simulated NTLM exchange
108
+ # that does not require anything outside of the normal gem test infrastructure.
109
+ # (see spec/httpi/adapter/net_http_spec.rb: it "supports ntlm authentication"
110
+ # and spec/integration/support/application.rb: map "/ntlm-auth")
111
+ # But since that simulated exchange is based on recorded traffic, you may wish to
112
+ # run the following integration test against a real external NTLM server from time to time.
113
+ #
114
+ # This test must be specially enabled because it requires an external
115
+ # Windows 2012 Server configured according to the instructions found here:
116
+ # https://github.com/savonrb/httpi/wiki/NTLM-Integration-Test-Plan
117
+ #
118
+ # Once you have that server running as instructed, you can include this test by setting
119
+ # NTLM=external via the command line, e.g.:
120
+ # $ NTLM=external bundle exec rspec
121
+ #
122
+ if ENV["NTLM"]=="external"
123
+ context "http request via NTLM" do
124
+ it "works with NTLM connections" do
125
+ user = "tester"
126
+ pass = "vReqSoafRe5O"
127
+ request = HTTPI::Request.new("http://ntlmtest/")
128
+ request.auth.ntlm(user,pass)
129
+ response = HTTPI.get(request, adapter)
130
+ expect(response.code).to eq(200)
131
+ response.body.should match(/iis-8\.png/)
132
+
133
+ puts "EXTERNAL NTLM INTEGRATION TEST, response body:"
134
+ puts response.body
135
+ end
91
136
  end
92
137
  end
93
138
 
@@ -47,6 +47,34 @@ class IntegrationServer
47
47
  }
48
48
  end
49
49
 
50
+ map "/ntlm-auth" do
51
+ run lambda { |env|
52
+ resp = [401, {"WWW-Authenticate" => "NTLM\r\nNegotiate"}, []]
53
+ # head request 1: challenge & response (from actual server)
54
+ if env["HTTP_AUTHORIZATION"] =~ /(NTLM|Negotiate) TlRMTVNTUAABAAAAB4IIAA/
55
+ resp = [401, {
56
+ "Content-Type" => "text/html; charset=us-ascii",
57
+ "Server" => "Microsoft-HTTPAPI/2.0",
58
+ "WWW-Authenticate" => "#{$1} TlRMTVNTUAACAAAAEAAQADgAAAAFgooCj/AvDazHhQsAAAAAAAAAAGAAYABIAAAABgLwIwAAAA9OAFQATABNAFQARQBTAFQAAgAQAE4AVABMAE0AVABFAFMAVAABABAATgBUAEwATQBUAEUAUwBUAAQAEABuAHQAbABtAHQAZQBzAHQAAwAQAG4AdABsAG0AdABlAHMAdAAHAAgAfzQp037nzQEAAAAA",
59
+ "Date" => "Mon, 31 Dec 2012 17:46:55 GMT",
60
+ "Content-Length" => "341"
61
+ }, []]
62
+ elsif env["HTTP_AUTHORIZATION"] =~ /(NTLM|Negotiate) (.+)/
63
+ # request 2: serve content
64
+ resp = IntegrationServer.respond_with "ntlm-auth"
65
+ else
66
+ resp = [401, {
67
+ "Content-Type" => "text/html; charset=us-ascii",
68
+ "WWW-Authenticate" => "NTLM\r\nNegotiate",
69
+ "Server" => "Microsoft-HTTPAPI/2.0",
70
+ "Date" => "Mon, 31 Dec 2012 17:46:55 GMT",
71
+ "Content-Length" => "341"
72
+ }, []]
73
+ end
74
+ resp
75
+ }
76
+ end
77
+
50
78
  map "/digest-auth" do
51
79
  unprotected_app = lambda { |env|
52
80
  IntegrationServer.respond_with "digest-auth"
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,25 @@
1
- require "bundler"
1
+ require 'bundler'
2
2
  Bundler.setup(:default, :development)
3
3
 
4
- require "httpi"
4
+ unless RUBY_PLATFORM =~ /java/
5
+ require 'simplecov'
6
+ require 'coveralls'
5
7
 
6
- require "rspec"
7
- require "mocha/api"
8
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
9
+ SimpleCov.start do
10
+ add_filter 'spec'
11
+ end
12
+ end
13
+
14
+ require 'httpi'
15
+ require 'rspec'
8
16
 
9
17
  RSpec.configure do |config|
10
18
  config.mock_with :mocha
19
+ config.order = 'random'
11
20
  end
12
21
 
13
22
  HTTPI.log = false
14
23
 
15
- require "support/fixture"
16
- require "support/matchers"
24
+ require 'support/fixture'
25
+ require 'support/matchers'