httpi 0.9.3 → 0.9.4
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/.travis.yml +7 -0
- data/CHANGELOG.md +14 -1
- data/Gemfile +5 -3
- data/README.md +130 -100
- data/Rakefile +10 -40
- data/httpi.gemspec +11 -13
- data/lib/httpi.rb +5 -0
- data/lib/httpi/adapter.rb +17 -13
- data/lib/httpi/auth/ssl.rb +4 -4
- data/lib/httpi/request.rb +1 -1
- data/lib/httpi/version.rb +1 -1
- data/spec/httpi/adapter/curb_spec.rb +167 -164
- data/spec/httpi/adapter/httpclient_spec.rb +16 -16
- data/spec/httpi/adapter_spec.rb +29 -15
- data/spec/httpi/auth/config_spec.rb +16 -16
- data/spec/httpi/auth/ssl_spec.rb +19 -19
- data/spec/httpi/httpi_spec.rb +44 -53
- data/spec/httpi/request_spec.rb +15 -15
- data/spec/httpi/response_spec.rb +17 -17
- metadata +34 -50
data/lib/httpi.rb
CHANGED
data/lib/httpi/adapter.rb
CHANGED
@@ -14,30 +14,30 @@ module HTTPI
|
|
14
14
|
module Adapter
|
15
15
|
|
16
16
|
ADAPTERS = {
|
17
|
-
:httpclient => HTTPClient,
|
18
|
-
:curb => Curb,
|
19
|
-
:net_http => NetHTTP
|
17
|
+
:httpclient => { :class => HTTPClient, :dependencies => ["httpclient"] },
|
18
|
+
:curb => { :class => Curb, :dependencies => ["curb"] },
|
19
|
+
:net_http => { :class => NetHTTP, :dependencies => ["net/https", "net/ntlm_http"] }
|
20
20
|
}
|
21
21
|
|
22
|
-
|
23
|
-
[:httpclient, ["httpclient"]],
|
24
|
-
[:curb, ["curb"]],
|
25
|
-
[:net_http, ["net/https", "net/ntlm_http"]]
|
26
|
-
]
|
22
|
+
LOAD_ORDER = [:httpclient, :curb, :net_http]
|
27
23
|
|
28
24
|
class << self
|
29
25
|
|
30
26
|
def use=(adapter)
|
31
|
-
@adapter = adapter.nil?
|
27
|
+
return @adapter = nil if adapter.nil?
|
28
|
+
|
29
|
+
validate_adapter! adapter
|
30
|
+
load_dependencies adapter
|
31
|
+
@adapter = adapter
|
32
32
|
end
|
33
33
|
|
34
34
|
def use
|
35
35
|
@adapter ||= default_adapter
|
36
36
|
end
|
37
37
|
|
38
|
-
def load(adapter
|
38
|
+
def load(adapter)
|
39
39
|
adapter = adapter ? validate_adapter!(adapter) : use
|
40
|
-
[adapter, ADAPTERS[adapter]]
|
40
|
+
[adapter, ADAPTERS[adapter][:class]]
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
@@ -48,9 +48,9 @@ module HTTPI
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def default_adapter
|
51
|
-
|
51
|
+
LOAD_ORDER.each do |adapter|
|
52
52
|
begin
|
53
|
-
|
53
|
+
load_dependencies adapter
|
54
54
|
return adapter
|
55
55
|
rescue LoadError
|
56
56
|
next
|
@@ -58,6 +58,10 @@ module HTTPI
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
def load_dependencies(adapter)
|
62
|
+
ADAPTERS[adapter][:dependencies].each { |dependency| require dependency }
|
63
|
+
end
|
64
|
+
|
61
65
|
end
|
62
66
|
end
|
63
67
|
end
|
data/lib/httpi/auth/ssl.rb
CHANGED
@@ -17,7 +17,7 @@ module HTTPI
|
|
17
17
|
rescue TypeError, Errno::ENOENT
|
18
18
|
false
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Accessor for the cert key file to validate SSL certificates.
|
22
22
|
attr_accessor :cert_key_file
|
23
23
|
|
@@ -29,18 +29,18 @@ module HTTPI
|
|
29
29
|
|
30
30
|
# Accessor for the cacert file to validate SSL certificates.
|
31
31
|
attr_accessor :ca_cert_file
|
32
|
-
|
32
|
+
|
33
33
|
# Returns the cert type to validate SSL certificates PEM|DER.
|
34
34
|
def cert_type
|
35
35
|
@cert_type ||= :pem
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
# Sets the cert type to validate SSL certificates PEM|DER.
|
39
39
|
def cert_type=(type)
|
40
40
|
raise ArgumentError, "Invalid SSL cert type: #{type}" unless CERT_TYPES.include? type
|
41
41
|
@cert_type = type
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
# Returns the SSL verify mode. Defaults to <tt>:peer</tt>.
|
45
45
|
def verify_mode
|
46
46
|
@verify_mode ||= :peer
|
data/lib/httpi/request.rb
CHANGED
data/lib/httpi/version.rb
CHANGED
@@ -2,228 +2,231 @@ require "spec_helper"
|
|
2
2
|
require "httpi/adapter/curb"
|
3
3
|
require "httpi/request"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
let(:adapter) { HTTPI::Adapter::Curb.new }
|
9
|
-
let(:curb) { Curl::Easy.any_instance }
|
10
|
-
|
11
|
-
describe "#get" do
|
12
|
-
before do
|
13
|
-
curb.expects(:http_get)
|
14
|
-
curb.expects(:response_code).returns(200)
|
15
|
-
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
16
|
-
curb.expects(:body_str).returns(Fixture.xml)
|
17
|
-
end
|
5
|
+
# curb does not run on jruby
|
6
|
+
unless RUBY_PLATFORM =~ /java/
|
7
|
+
require "curb"
|
18
8
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
9
|
+
describe HTTPI::Adapter::Curb do
|
10
|
+
let(:adapter) { HTTPI::Adapter::Curb.new }
|
11
|
+
let(:curb) { Curl::Easy.any_instance }
|
23
12
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
13
|
+
describe "#get" do
|
14
|
+
before do
|
15
|
+
curb.expects(:http_get)
|
16
|
+
curb.expects(:response_code).returns(200)
|
17
|
+
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
18
|
+
curb.expects(:body_str).returns(Fixture.xml)
|
19
|
+
end
|
31
20
|
|
32
|
-
|
33
|
-
|
21
|
+
it "returns a valid HTTPI::Response" do
|
22
|
+
adapter.get(basic_request).should match_response(:body => Fixture.xml)
|
23
|
+
end
|
34
24
|
end
|
35
|
-
end
|
36
25
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
26
|
+
describe "#post" do
|
27
|
+
before do
|
28
|
+
curb.expects(:http_post)
|
29
|
+
curb.expects(:response_code).returns(200)
|
30
|
+
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
31
|
+
curb.expects(:body_str).returns(Fixture.xml)
|
32
|
+
end
|
43
33
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
curb.expects(:response_code).returns(200)
|
48
|
-
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
49
|
-
curb.expects(:body_str).returns(Fixture.xml)
|
34
|
+
it "returns a valid HTTPI::Response" do
|
35
|
+
adapter.post(basic_request).should match_response(:body => Fixture.xml)
|
36
|
+
end
|
50
37
|
end
|
51
38
|
|
52
|
-
|
53
|
-
|
39
|
+
describe "#post" do
|
40
|
+
it "sends the body in the request" do
|
41
|
+
curb.expects(:http_post).with('xml=hi&name=123')
|
42
|
+
adapter.post(basic_request { |request| request.body = 'xml=hi&name=123' } )
|
43
|
+
end
|
54
44
|
end
|
55
|
-
end
|
56
45
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
46
|
+
describe "#head" do
|
47
|
+
before do
|
48
|
+
curb.expects(:http_head)
|
49
|
+
curb.expects(:response_code).returns(200)
|
50
|
+
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
51
|
+
curb.expects(:body_str).returns(Fixture.xml)
|
52
|
+
end
|
64
53
|
|
65
|
-
|
66
|
-
|
54
|
+
it "returns a valid HTTPI::Response" do
|
55
|
+
adapter.head(basic_request).should match_response(:body => Fixture.xml)
|
56
|
+
end
|
67
57
|
end
|
68
|
-
end
|
69
58
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
59
|
+
describe "#put" do
|
60
|
+
before do
|
61
|
+
curb.expects(:http_put)
|
62
|
+
curb.expects(:response_code).returns(200)
|
63
|
+
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
64
|
+
curb.expects(:body_str).returns(Fixture.xml)
|
65
|
+
end
|
76
66
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
curb.expects(:response_code).returns(200)
|
81
|
-
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
82
|
-
curb.expects(:body_str).returns("")
|
67
|
+
it "returns a valid HTTPI::Response" do
|
68
|
+
adapter.put(basic_request).should match_response(:body => Fixture.xml)
|
69
|
+
end
|
83
70
|
end
|
84
71
|
|
85
|
-
|
86
|
-
|
72
|
+
describe "#put" do
|
73
|
+
it "sends the body in the request" do
|
74
|
+
curb.expects(:http_put).with('xml=hi&name=123')
|
75
|
+
adapter.put(basic_request { |request| request.body = 'xml=hi&name=123' } )
|
76
|
+
end
|
87
77
|
end
|
88
|
-
end
|
89
78
|
|
90
|
-
|
91
|
-
|
79
|
+
describe "#delete" do
|
80
|
+
before do
|
81
|
+
curb.expects(:http_delete)
|
82
|
+
curb.expects(:response_code).returns(200)
|
83
|
+
curb.expects(:header_str).returns("Accept-encoding: utf-8")
|
84
|
+
curb.expects(:body_str).returns("")
|
85
|
+
end
|
92
86
|
|
93
|
-
|
94
|
-
|
95
|
-
curb.expects(:url=).with(basic_request.url.to_s)
|
96
|
-
adapter.get(basic_request)
|
87
|
+
it "returns a valid HTTPI::Response" do
|
88
|
+
adapter.delete(basic_request).should match_response(:body => "")
|
97
89
|
end
|
98
90
|
end
|
99
91
|
|
100
|
-
describe "
|
101
|
-
|
102
|
-
|
103
|
-
|
92
|
+
describe "settings:" do
|
93
|
+
before { curb.stubs(:http_get) }
|
94
|
+
|
95
|
+
describe "url" do
|
96
|
+
it "always sets the request url" do
|
97
|
+
curb.expects(:url=).with(basic_request.url.to_s)
|
98
|
+
adapter.get(basic_request)
|
99
|
+
end
|
104
100
|
end
|
105
101
|
|
106
|
-
|
107
|
-
|
102
|
+
describe "proxy_url" do
|
103
|
+
it "is not set unless it's specified" do
|
104
|
+
curb.expects(:proxy_url=).never
|
105
|
+
adapter.get(basic_request)
|
106
|
+
end
|
108
107
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
end
|
108
|
+
it "is set if specified" do
|
109
|
+
request = basic_request { |request| request.proxy = "http://proxy.example.com" }
|
113
110
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
adapter.get(basic_request)
|
111
|
+
curb.expects(:proxy_url=).with(request.proxy.to_s)
|
112
|
+
adapter.get(request)
|
113
|
+
end
|
118
114
|
end
|
119
115
|
|
120
|
-
|
121
|
-
|
116
|
+
describe "timeout" do
|
117
|
+
it "is not set unless it's specified" do
|
118
|
+
curb.expects(:timeout=).never
|
119
|
+
adapter.get(basic_request)
|
120
|
+
end
|
122
121
|
|
123
|
-
|
124
|
-
|
125
|
-
end
|
126
|
-
end
|
122
|
+
it "is set if specified" do
|
123
|
+
request = basic_request { |request| request.read_timeout = 30 }
|
127
124
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
adapter.get(basic_request)
|
125
|
+
curb.expects(:timeout=).with(30)
|
126
|
+
adapter.get(request)
|
127
|
+
end
|
132
128
|
end
|
133
129
|
|
134
|
-
|
135
|
-
|
130
|
+
describe "connect_timeout" do
|
131
|
+
it "is not set unless it's specified" do
|
132
|
+
curb.expects(:connect_timeout=).never
|
133
|
+
adapter.get(basic_request)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "is set if specified" do
|
137
|
+
request = basic_request { |request| request.open_timeout = 30 }
|
136
138
|
|
137
|
-
|
138
|
-
|
139
|
+
curb.expects(:connect_timeout=).with(30)
|
140
|
+
adapter.get(request)
|
141
|
+
end
|
139
142
|
end
|
140
|
-
end
|
141
143
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
144
|
+
describe "headers" do
|
145
|
+
it "is always set" do
|
146
|
+
curb.expects(:headers=).with({})
|
147
|
+
adapter.get(basic_request)
|
148
|
+
end
|
146
149
|
end
|
147
|
-
end
|
148
150
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
151
|
+
describe "verbose" do
|
152
|
+
it "is always set to false" do
|
153
|
+
curb.expects(:verbose=).with(false)
|
154
|
+
adapter.get(basic_request)
|
155
|
+
end
|
153
156
|
end
|
154
|
-
end
|
155
157
|
|
156
|
-
|
157
|
-
|
158
|
-
|
158
|
+
describe "http_auth_types" do
|
159
|
+
it "is set to :basic for HTTP basic auth" do
|
160
|
+
request = basic_request { |request| request.auth.basic "username", "password" }
|
159
161
|
|
160
|
-
|
161
|
-
|
162
|
-
|
162
|
+
curb.expects(:http_auth_types=).with(:basic)
|
163
|
+
adapter.get(request)
|
164
|
+
end
|
163
165
|
|
164
|
-
|
165
|
-
|
166
|
+
it "is set to :digest for HTTP digest auth" do
|
167
|
+
request = basic_request { |request| request.auth.digest "username", "password" }
|
166
168
|
|
167
|
-
|
168
|
-
|
169
|
+
curb.expects(:http_auth_types=).with(:digest)
|
170
|
+
adapter.get(request)
|
171
|
+
end
|
169
172
|
end
|
170
|
-
end
|
171
173
|
|
172
|
-
|
173
|
-
|
174
|
-
|
174
|
+
describe "username and password" do
|
175
|
+
it "is set for HTTP basic auth" do
|
176
|
+
request = basic_request { |request| request.auth.basic "username", "password" }
|
175
177
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
178
|
+
curb.expects(:username=).with("username")
|
179
|
+
curb.expects(:password=).with("password")
|
180
|
+
adapter.get(request)
|
181
|
+
end
|
180
182
|
|
181
|
-
|
182
|
-
|
183
|
+
it "is set for HTTP digest auth" do
|
184
|
+
request = basic_request { |request| request.auth.digest "username", "password" }
|
183
185
|
|
184
|
-
|
185
|
-
|
186
|
-
|
186
|
+
curb.expects(:username=).with("username")
|
187
|
+
curb.expects(:password=).with("password")
|
188
|
+
adapter.get(request)
|
189
|
+
end
|
187
190
|
end
|
188
|
-
end
|
189
191
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
192
|
+
context "(for SSL client auth)" do
|
193
|
+
let(:ssl_auth_request) do
|
194
|
+
basic_request do |request|
|
195
|
+
request.auth.ssl.cert_key_file = "spec/fixtures/client_key.pem"
|
196
|
+
request.auth.ssl.cert_file = "spec/fixtures/client_cert.pem"
|
197
|
+
end
|
195
198
|
end
|
196
|
-
end
|
197
199
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
200
|
+
it "cert_key, cert and ssl_verify_peer should be set" do
|
201
|
+
curb.expects(:cert_key=).with(ssl_auth_request.auth.ssl.cert_key_file)
|
202
|
+
curb.expects(:cert=).with(ssl_auth_request.auth.ssl.cert_file)
|
203
|
+
curb.expects(:ssl_verify_peer=).with(true)
|
204
|
+
curb.expects(:certtype=).with(ssl_auth_request.auth.ssl.cert_type.to_s.upcase)
|
203
205
|
|
204
|
-
|
205
|
-
|
206
|
+
adapter.get(ssl_auth_request)
|
207
|
+
end
|
206
208
|
|
207
|
-
|
208
|
-
|
209
|
-
|
209
|
+
it "sets the cert_type to DER if specified" do
|
210
|
+
ssl_auth_request.auth.ssl.cert_type = :der
|
211
|
+
curb.expects(:certtype=).with(:der.to_s.upcase)
|
210
212
|
|
211
|
-
|
212
|
-
|
213
|
+
adapter.get(ssl_auth_request)
|
214
|
+
end
|
213
215
|
|
214
|
-
|
215
|
-
|
216
|
-
|
216
|
+
it "sets the cacert if specified" do
|
217
|
+
ssl_auth_request.auth.ssl.ca_cert_file = "spec/fixtures/client_cert.pem"
|
218
|
+
curb.expects(:cacert=).with(ssl_auth_request.auth.ssl.ca_cert_file)
|
217
219
|
|
218
|
-
|
220
|
+
adapter.get(ssl_auth_request)
|
221
|
+
end
|
219
222
|
end
|
220
223
|
end
|
221
|
-
end
|
222
224
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
225
|
+
def basic_request
|
226
|
+
request = HTTPI::Request.new :url => "http://example.com"
|
227
|
+
yield request if block_given?
|
228
|
+
request
|
229
|
+
end
|
228
230
|
|
231
|
+
end
|
229
232
|
end
|