httpi 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +10 -10
- data/README.md +40 -9
- data/lib/httpi.rb +9 -0
- data/lib/httpi/adapter/curb.rb +15 -6
- data/lib/httpi/adapter/httpclient.rb +20 -11
- data/lib/httpi/adapter/net_http.rb +14 -10
- data/lib/httpi/auth/config.rb +68 -0
- data/lib/httpi/auth/ssl.rb +76 -0
- data/lib/httpi/request.rb +32 -48
- data/lib/httpi/version.rb +1 -1
- data/spec/fixtures/client_cert.pem +16 -0
- data/spec/fixtures/client_key.pem +15 -0
- data/spec/httpi/adapter/curb_spec.rb +136 -10
- data/spec/httpi/adapter/httpclient_spec.rb +99 -33
- data/spec/httpi/adapter/net_http_spec.rb +99 -28
- data/spec/httpi/auth/config_spec.rb +117 -0
- data/spec/httpi/auth/ssl_spec.rb +112 -0
- data/spec/httpi/httpi_spec.rb +45 -37
- data/spec/httpi/request_spec.rb +38 -73
- data/spec/integration/request_spec.rb +3 -3
- metadata +14 -10
@@ -3,6 +3,7 @@ require "httpi/adapter/net_http"
|
|
3
3
|
require "httpi/request"
|
4
4
|
|
5
5
|
describe HTTPI::Adapter::NetHTTP do
|
6
|
+
let(:net_http) { Net::HTTP.any_instance }
|
6
7
|
|
7
8
|
def adapter(request)
|
8
9
|
@adapter ||= HTTPI::Adapter::NetHTTP.new request
|
@@ -16,58 +17,128 @@ describe HTTPI::Adapter::NetHTTP do
|
|
16
17
|
end
|
17
18
|
|
18
19
|
describe "#get" do
|
19
|
-
before do
|
20
|
-
@request = HTTPI::Request.new :url => "http://example.com"
|
21
|
-
stub_request(:get, @request.url.to_s).to_return(:body => Fixture.xml)
|
22
|
-
end
|
23
|
-
|
24
20
|
it "should return a valid HTTPI::Response" do
|
25
|
-
|
21
|
+
stub_request(:get, basic_request.url.to_s).to_return(:body => Fixture.xml)
|
22
|
+
adapter(basic_request).get(basic_request).should match_response(:body => Fixture.xml)
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
29
26
|
describe "#post" do
|
30
|
-
before do
|
31
|
-
@request = HTTPI::Request.new :url => "http://example.com", :body => Fixture.xml
|
32
|
-
stub_request(:post, @request.url.to_s).with(:body => @request.body).to_return(:body => Fixture.xml)
|
33
|
-
end
|
34
|
-
|
35
27
|
it "should return a valid HTTPI::Response" do
|
36
|
-
|
28
|
+
request = HTTPI::Request.new :url => "http://example.com", :body => Fixture.xml
|
29
|
+
stub_request(:post, request.url.to_s).with(:body => request.body).to_return(:body => Fixture.xml)
|
30
|
+
|
31
|
+
adapter(request).post(request).should match_response(:body => Fixture.xml)
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
40
35
|
describe "#head" do
|
41
|
-
before do
|
42
|
-
@request = HTTPI::Request.new :url => "http://example.com"
|
43
|
-
stub_request(:head, @request.url.to_s).to_return(:body => Fixture.xml)
|
44
|
-
end
|
45
|
-
|
46
36
|
it "should return a valid HTTPI::Response" do
|
47
|
-
|
37
|
+
stub_request(:head, basic_request.url.to_s).to_return(:body => Fixture.xml)
|
38
|
+
adapter(basic_request).head(basic_request).should match_response(:body => Fixture.xml)
|
48
39
|
end
|
49
40
|
end
|
50
41
|
|
51
42
|
describe "#put" do
|
52
|
-
|
53
|
-
|
54
|
-
stub_request(:put,
|
43
|
+
it "should return a valid HTTPI::Response" do
|
44
|
+
request = HTTPI::Request.new :url => "http://example.com", :body => Fixture.xml
|
45
|
+
stub_request(:put, request.url.to_s).with(:body => request.body).to_return(:body => Fixture.xml)
|
46
|
+
|
47
|
+
adapter(request).put(request).should match_response(:body => Fixture.xml)
|
55
48
|
end
|
49
|
+
end
|
56
50
|
|
51
|
+
describe "#delete" do
|
57
52
|
it "should return a valid HTTPI::Response" do
|
58
|
-
|
53
|
+
stub_request(:delete, basic_request.url.to_s)
|
54
|
+
adapter(basic_request).delete(basic_request).should match_response(:body => "")
|
59
55
|
end
|
60
56
|
end
|
61
57
|
|
62
|
-
describe "
|
63
|
-
before
|
64
|
-
|
65
|
-
|
58
|
+
describe "settings:" do
|
59
|
+
before { stub_request(:get, basic_request.url.to_s) }
|
60
|
+
|
61
|
+
describe "use_ssl" do
|
62
|
+
it "should be set to false for non-SSL requests" do
|
63
|
+
net_http.expects(:use_ssl=).with(false)
|
64
|
+
adapter(basic_request).get(basic_request)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be set to true for SSL requests" do
|
68
|
+
request = basic_request { |request| request.ssl = true }
|
69
|
+
|
70
|
+
net_http.expects(:use_ssl=).with(true)
|
71
|
+
adapter(request).get(request)
|
72
|
+
end
|
66
73
|
end
|
67
74
|
|
68
|
-
|
69
|
-
|
75
|
+
describe "open_timeout" do
|
76
|
+
it "should not be set if not specified" do
|
77
|
+
net_http.expects(:open_timeout=).never
|
78
|
+
adapter(basic_request).get(basic_request)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be set if specified" do
|
82
|
+
request = basic_request { |request| request.open_timeout = 30 }
|
83
|
+
|
84
|
+
net_http.expects(:open_timeout=).with(30)
|
85
|
+
adapter(request).get(request)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "read_timeout" do
|
90
|
+
it "should not be set if not specified" do
|
91
|
+
net_http.expects(:read_timeout=).never
|
92
|
+
adapter(basic_request).get(basic_request)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be set if specified" do
|
96
|
+
request = basic_request { |request| request.read_timeout = 30 }
|
97
|
+
|
98
|
+
net_http.expects(:read_timeout=).with(30)
|
99
|
+
adapter(request).get(request)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "basic_auth" do
|
104
|
+
it "should be set for HTTP basic auth" do
|
105
|
+
request = basic_request { |request| request.auth.basic "username", "password" }
|
106
|
+
|
107
|
+
stub_request(:get, "http://username:password@example.com")
|
108
|
+
Net::HTTP::Get.any_instance.expects(:basic_auth).with(*request.auth.credentials)
|
109
|
+
adapter(request).get(request)
|
110
|
+
end
|
70
111
|
end
|
112
|
+
|
113
|
+
context "(for SSL client auth)" do
|
114
|
+
let(:ssl_auth_request) do
|
115
|
+
basic_request do |request|
|
116
|
+
request.auth.ssl.cert_key_file = "spec/fixtures/client_key.pem"
|
117
|
+
request.auth.ssl.cert_file = "spec/fixtures/client_cert.pem"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it "key, cert and verify_mode should be set" do
|
122
|
+
net_http.expects(:cert=).with(ssl_auth_request.auth.ssl.cert)
|
123
|
+
net_http.expects(:key=).with(ssl_auth_request.auth.ssl.cert_key)
|
124
|
+
net_http.expects(:verify_mode=).with(ssl_auth_request.auth.ssl.openssl_verify_mode)
|
125
|
+
|
126
|
+
adapter(ssl_auth_request).get(ssl_auth_request)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should set the client_ca if specified" do
|
130
|
+
ssl_auth_request.auth.ssl.ca_cert_file = "spec/fixtures/client_cert.pem"
|
131
|
+
net_http.expects(:ca_file=).with(ssl_auth_request.auth.ssl.ca_cert_file)
|
132
|
+
|
133
|
+
adapter(ssl_auth_request).get(ssl_auth_request)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def basic_request
|
139
|
+
request = HTTPI::Request.new "http://example.com"
|
140
|
+
yield request if block_given?
|
141
|
+
request
|
71
142
|
end
|
72
143
|
|
73
144
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi/auth/config"
|
3
|
+
|
4
|
+
describe HTTPI::Auth::Config do
|
5
|
+
let(:auth) { HTTPI::Auth::Config.new }
|
6
|
+
|
7
|
+
describe "#basic" do
|
8
|
+
it "lets you specify the basic auth credentials" do
|
9
|
+
auth.basic "username", "password"
|
10
|
+
auth.basic.should == ["username", "password"]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "also accepts an Array of credentials" do
|
14
|
+
auth.basic ["username", "password"]
|
15
|
+
auth.basic.should == ["username", "password"]
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sets the authentication type to :basic" do
|
19
|
+
auth.basic "username", "password"
|
20
|
+
auth.type.should == :basic
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#basic?" do
|
25
|
+
it "should default to return false" do
|
26
|
+
auth.should_not be_basic
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return true for HTTP basic auth" do
|
30
|
+
auth.basic "username", "password"
|
31
|
+
auth.should be_basic
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#digest" do
|
36
|
+
it "lets you specify the digest auth credentials" do
|
37
|
+
auth.digest "username", "password"
|
38
|
+
auth.digest.should == ["username", "password"]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "also accepts an Array of credentials" do
|
42
|
+
auth.digest ["username", "password"]
|
43
|
+
auth.digest.should == ["username", "password"]
|
44
|
+
end
|
45
|
+
|
46
|
+
it "sets the authentication type to :digest" do
|
47
|
+
auth.digest "username", "password"
|
48
|
+
auth.type.should == :digest
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#digest?" do
|
53
|
+
it "should default to return false" do
|
54
|
+
auth.should_not be_digest
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return true for HTTP digest auth" do
|
58
|
+
auth.digest "username", "password"
|
59
|
+
auth.should be_digest
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#http?" do
|
64
|
+
it "should default to return false" do
|
65
|
+
auth.should_not be_http
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return true for HTTP basic auth" do
|
69
|
+
auth.basic "username", "password"
|
70
|
+
auth.should be_http
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should return true for HTTP digest auth" do
|
74
|
+
auth.digest "username", "password"
|
75
|
+
auth.should be_http
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#ssl" do
|
80
|
+
it "should return the HTTPI::Auth::SSL object" do
|
81
|
+
auth.ssl.should be_a(HTTPI::Auth::SSL)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#ssl?" do
|
86
|
+
it "should default to return false" do
|
87
|
+
auth.should_not be_ssl
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should return true for SSL client auth" do
|
91
|
+
auth.ssl.cert_key_file = "spec/fixtures/client_key.pem"
|
92
|
+
auth.ssl.cert_file = "spec/fixtures/client_cert.pem"
|
93
|
+
|
94
|
+
auth.should be_ssl
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#type" do
|
99
|
+
it "should return the authentication type" do
|
100
|
+
auth.basic "username", "password"
|
101
|
+
auth.type.should == :basic
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#credentials" do
|
106
|
+
it "return the credentials for HTTP basic auth" do
|
107
|
+
auth.basic "username", "basic"
|
108
|
+
auth.credentials.should == ["username", "basic"]
|
109
|
+
end
|
110
|
+
|
111
|
+
it "return the credentials for HTTP digest auth" do
|
112
|
+
auth.digest "username", "digest"
|
113
|
+
auth.credentials.should == ["username", "digest"]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi/auth/ssl"
|
3
|
+
|
4
|
+
describe HTTPI::Auth::SSL do
|
5
|
+
|
6
|
+
describe "VERIFY_MODES" do
|
7
|
+
it "should contain the supported SSL verify modes" do
|
8
|
+
HTTPI::Auth::SSL::VERIFY_MODES.should == [:none, :peer, :fail_if_no_peer_cert, :client_once]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#present?" do
|
13
|
+
it "should default to return false" do
|
14
|
+
ssl = HTTPI::Auth::SSL.new
|
15
|
+
ssl.should_not be_present
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return false if only a client key was specified" do
|
19
|
+
ssl = HTTPI::Auth::SSL.new
|
20
|
+
ssl.cert_key_file = "spec/fixtures/client_key.pem"
|
21
|
+
|
22
|
+
ssl.should_not be_present
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return false if only a client key was specified" do
|
26
|
+
ssl = HTTPI::Auth::SSL.new
|
27
|
+
ssl.cert_file = "spec/fixtures/client_cert.pem"
|
28
|
+
|
29
|
+
ssl.should_not be_present
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return true if both client key and cert are present" do
|
33
|
+
ssl.should be_present
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#verify_mode" do
|
38
|
+
it "should default to return :peer" do
|
39
|
+
ssl.verify_mode.should == :peer
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should set the verify mode to use" do
|
43
|
+
ssl = HTTPI::Auth::SSL.new
|
44
|
+
|
45
|
+
ssl.verify_mode = :none
|
46
|
+
ssl.verify_mode.should == :none
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise an ArgumentError if the given mode is not supported" do
|
50
|
+
lambda { ssl.verify_mode = :invalid }.should raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#cert" do
|
55
|
+
it "should return an OpenSSL::X509::Certificate for the given cert_file" do
|
56
|
+
ssl.cert.should be_a(OpenSSL::X509::Certificate)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#cert_key" do
|
61
|
+
it "should return a OpenSSL::PKey::RSA for the given cert_key" do
|
62
|
+
ssl.cert_key.should be_a(OpenSSL::PKey::RSA)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#ca_cert" do
|
67
|
+
it "should return an OpenSSL::X509::Certificate for the given ca_cert_file" do
|
68
|
+
ssl = HTTPI::Auth::SSL.new
|
69
|
+
|
70
|
+
ssl.ca_cert_file = "spec/fixtures/client_cert.pem"
|
71
|
+
ssl.ca_cert.should be_a(OpenSSL::X509::Certificate)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#openssl_verify_mode" do
|
76
|
+
it "should return the OpenSSL verify mode for :none" do
|
77
|
+
ssl = HTTPI::Auth::SSL.new
|
78
|
+
|
79
|
+
ssl.verify_mode = :none
|
80
|
+
ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_NONE
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should return the OpenSSL verify mode for :peer" do
|
84
|
+
ssl = HTTPI::Auth::SSL.new
|
85
|
+
|
86
|
+
ssl.verify_mode = :peer
|
87
|
+
ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_PEER
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should return the OpenSSL verify mode for :fail_if_no_peer_cert" do
|
91
|
+
ssl = HTTPI::Auth::SSL.new
|
92
|
+
|
93
|
+
ssl.verify_mode = :fail_if_no_peer_cert
|
94
|
+
ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return the OpenSSL verify mode for :client_once" do
|
98
|
+
ssl = HTTPI::Auth::SSL.new
|
99
|
+
|
100
|
+
ssl.verify_mode = :client_once
|
101
|
+
ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_CLIENT_ONCE
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def ssl
|
106
|
+
ssl = HTTPI::Auth::SSL.new
|
107
|
+
ssl.cert_key_file = "spec/fixtures/client_key.pem"
|
108
|
+
ssl.cert_file = "spec/fixtures/client_cert.pem"
|
109
|
+
ssl
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/spec/httpi/httpi_spec.rb
CHANGED
@@ -42,28 +42,6 @@ describe HTTPI do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
shared_examples_for "a request method" do
|
46
|
-
context "(with a block)" do
|
47
|
-
it "should yield the HTTP client instance used for the request" do
|
48
|
-
client.delete "http://example.com" do |http|
|
49
|
-
http.should be_an(HTTPClient)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
it "and raise an ArgumentError in case of an invalid adapter" do
|
55
|
-
lambda { client.delete HTTPI::Request.new, :invalid }.should raise_error(ArgumentError)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "and raise an ArgumentError in case of an invalid URL" do
|
59
|
-
lambda { client.delete "invalid" }.should raise_error(ArgumentError)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe ".get" do
|
64
|
-
it_should_behave_like "a request method"
|
65
|
-
end
|
66
|
-
|
67
45
|
describe ".post(request)" do
|
68
46
|
it "should execute an HTTP POST request using the default adapter" do
|
69
47
|
request = HTTPI::Request.new
|
@@ -102,10 +80,6 @@ describe HTTPI do
|
|
102
80
|
end
|
103
81
|
end
|
104
82
|
|
105
|
-
describe ".post" do
|
106
|
-
it_should_behave_like "a request method"
|
107
|
-
end
|
108
|
-
|
109
83
|
describe ".head(request)" do
|
110
84
|
it "should execute an HTTP HEAD request using the default adapter" do
|
111
85
|
request = HTTPI::Request.new
|
@@ -142,10 +116,6 @@ describe HTTPI do
|
|
142
116
|
end
|
143
117
|
end
|
144
118
|
|
145
|
-
describe ".head" do
|
146
|
-
it_should_behave_like "a request method"
|
147
|
-
end
|
148
|
-
|
149
119
|
describe ".put(request)" do
|
150
120
|
it "should execute an HTTP PUT request using the default adapter" do
|
151
121
|
request = HTTPI::Request.new
|
@@ -184,10 +154,6 @@ describe HTTPI do
|
|
184
154
|
end
|
185
155
|
end
|
186
156
|
|
187
|
-
describe ".put" do
|
188
|
-
it_should_behave_like "a request method"
|
189
|
-
end
|
190
|
-
|
191
157
|
describe ".delete(request)" do
|
192
158
|
it "should execute an HTTP DELETE request using the default adapter" do
|
193
159
|
request = HTTPI::Request.new
|
@@ -223,9 +189,51 @@ describe HTTPI do
|
|
223
189
|
client.delete "http://example.com", :curb
|
224
190
|
end
|
225
191
|
end
|
226
|
-
|
227
|
-
describe ".
|
228
|
-
|
192
|
+
|
193
|
+
describe ".request" do
|
194
|
+
it "should raise an ArgumentError in case of an invalid request method" do
|
195
|
+
lambda { client.request :invalid, HTTPI::Request.new }.should raise_error(ArgumentError)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
HTTPI::REQUEST_METHODS.each do |method|
|
200
|
+
|
201
|
+
describe ".request(#{method}, request, adapter)" do
|
202
|
+
it "should delegate to the .#{method} method" do
|
203
|
+
HTTPI.expects(method)
|
204
|
+
client.request method, HTTPI::Request.new
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe ".#{method}" do
|
209
|
+
it "should raise an ArgumentError in case of an invalid adapter" do
|
210
|
+
lambda { client.request method, request, :invalid }.should raise_error(ArgumentError)
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should raise an ArgumentError in case of an invalid request" do
|
214
|
+
lambda { client.request method, "invalid" }.should raise_error(ArgumentError)
|
215
|
+
end
|
216
|
+
|
217
|
+
HTTPI::Adapter.adapters.each do |adapter, adapter_class|
|
218
|
+
client_class = {
|
219
|
+
:httpclient => lambda { HTTPClient },
|
220
|
+
:curb => lambda { Curl::Easy },
|
221
|
+
:net_http => lambda { Net::HTTP }
|
222
|
+
}
|
223
|
+
|
224
|
+
context "using :#{adapter} with a block" do
|
225
|
+
let(:request) { HTTPI::Request.new :url => "http://example.com" }
|
226
|
+
|
227
|
+
before { adapter_class.any_instance.stubs(method) }
|
228
|
+
|
229
|
+
it "should yield the HTTP client instance used for the request" do
|
230
|
+
block = lambda { |http| http.should be_a(client_class[adapter].call) }
|
231
|
+
client.request(method, request, adapter, &block)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
229
237
|
end
|
230
238
|
|
231
239
|
end
|