cs-httpi 0.9.5.1

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.
Files changed (48) hide show
  1. data/.autotest +5 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +8 -0
  5. data/CHANGELOG.md +66 -0
  6. data/Gemfile +9 -0
  7. data/LICENSE +20 -0
  8. data/README.md +229 -0
  9. data/Rakefile +18 -0
  10. data/autotest/discover.rb +1 -0
  11. data/cs-httpi.gemspec +26 -0
  12. data/lib/cs-httpi.rb +198 -0
  13. data/lib/cs-httpi/adapter.rb +67 -0
  14. data/lib/cs-httpi/adapter/curb.rb +119 -0
  15. data/lib/cs-httpi/adapter/httpclient.rb +98 -0
  16. data/lib/cs-httpi/adapter/net_http.rb +115 -0
  17. data/lib/cs-httpi/auth/config.rb +78 -0
  18. data/lib/cs-httpi/auth/ssl.rb +91 -0
  19. data/lib/cs-httpi/dime.rb +56 -0
  20. data/lib/cs-httpi/request.rb +99 -0
  21. data/lib/cs-httpi/response.rb +85 -0
  22. data/lib/cs-httpi/version.rb +5 -0
  23. data/nbproject/private/private.properties +2 -0
  24. data/nbproject/private/rake-d.txt +0 -0
  25. data/nbproject/project.properties +7 -0
  26. data/nbproject/project.xml +15 -0
  27. data/spec/cs-httpi/adapter/curb_spec.rb +232 -0
  28. data/spec/cs-httpi/adapter/httpclient_spec.rb +164 -0
  29. data/spec/cs-httpi/adapter/net_http_spec.rb +142 -0
  30. data/spec/cs-httpi/adapter_spec.rb +55 -0
  31. data/spec/cs-httpi/auth/config_spec.rb +117 -0
  32. data/spec/cs-httpi/auth/ssl_spec.rb +128 -0
  33. data/spec/cs-httpi/httpi_spec.rb +284 -0
  34. data/spec/cs-httpi/request_spec.rb +140 -0
  35. data/spec/cs-httpi/response_spec.rb +125 -0
  36. data/spec/fixtures/attachment.gif +0 -0
  37. data/spec/fixtures/client_cert.pem +16 -0
  38. data/spec/fixtures/client_key.pem +15 -0
  39. data/spec/fixtures/xml.gz +0 -0
  40. data/spec/fixtures/xml.xml +10 -0
  41. data/spec/fixtures/xml_dime.dime +0 -0
  42. data/spec/fixtures/xml_dime.xml +1 -0
  43. data/spec/integration/request_spec.rb +95 -0
  44. data/spec/integration/server.rb +39 -0
  45. data/spec/spec_helper.rb +12 -0
  46. data/spec/support/fixture.rb +27 -0
  47. data/spec/support/matchers.rb +19 -0
  48. metadata +158 -0
@@ -0,0 +1,128 @@
1
+ require "spec_helper"
2
+ require "cs-httpi/auth/ssl"
3
+
4
+ describe HTTPI::Auth::SSL do
5
+
6
+ describe "VERIFY_MODES" do
7
+ it "contains 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 "defaults to return false" do
14
+ ssl = HTTPI::Auth::SSL.new
15
+ ssl.should_not be_present
16
+ end
17
+
18
+ it "returns 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 "returns 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 "returns true if both client key and cert are present" do
33
+ ssl.should be_present
34
+ end
35
+
36
+ it "returns true of the verify_mode is :none" do
37
+ ssl = HTTPI::Auth::SSL.new
38
+ ssl.verify_mode = :none
39
+ ssl.should be_present
40
+ end
41
+ end
42
+
43
+ describe "#verify_mode" do
44
+ it "defaults to return :peer" do
45
+ ssl.verify_mode.should == :peer
46
+ end
47
+
48
+ it "sets the verify mode to use" do
49
+ ssl = HTTPI::Auth::SSL.new
50
+
51
+ ssl.verify_mode = :none
52
+ ssl.verify_mode.should == :none
53
+ end
54
+
55
+ it "raises an ArgumentError if the given mode is not supported" do
56
+ expect { ssl.verify_mode = :invalid }.to raise_error(ArgumentError)
57
+ end
58
+ end
59
+
60
+ describe "#cert" do
61
+ it "returns an OpenSSL::X509::Certificate for the given cert_file" do
62
+ ssl.cert.should be_a(OpenSSL::X509::Certificate)
63
+ end
64
+
65
+ it "returns nil if no cert_file was given" do
66
+ ssl = HTTPI::Auth::SSL.new
67
+ ssl.cert.should be_nil
68
+ end
69
+ end
70
+
71
+ describe "#cert_key" do
72
+ it "returns a OpenSSL::PKey::RSA for the given cert_key" do
73
+ ssl.cert_key.should be_a(OpenSSL::PKey::RSA)
74
+ end
75
+
76
+ it "returns nil if no cert_key_file was given" do
77
+ ssl = HTTPI::Auth::SSL.new
78
+ ssl.cert_key.should be_nil
79
+ end
80
+ end
81
+
82
+ describe "#ca_cert" do
83
+ it "returns an OpenSSL::X509::Certificate for the given ca_cert_file" do
84
+ ssl = HTTPI::Auth::SSL.new
85
+
86
+ ssl.ca_cert_file = "spec/fixtures/client_cert.pem"
87
+ ssl.ca_cert.should be_a(OpenSSL::X509::Certificate)
88
+ end
89
+ end
90
+
91
+ describe "#openssl_verify_mode" do
92
+ it "returns the OpenSSL verify mode for :none" do
93
+ ssl = HTTPI::Auth::SSL.new
94
+
95
+ ssl.verify_mode = :none
96
+ ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_NONE
97
+ end
98
+
99
+ it "returns the OpenSSL verify mode for :peer" do
100
+ ssl = HTTPI::Auth::SSL.new
101
+
102
+ ssl.verify_mode = :peer
103
+ ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_PEER
104
+ end
105
+
106
+ it "returns the OpenSSL verify mode for :fail_if_no_peer_cert" do
107
+ ssl = HTTPI::Auth::SSL.new
108
+
109
+ ssl.verify_mode = :fail_if_no_peer_cert
110
+ ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
111
+ end
112
+
113
+ it "returns the OpenSSL verify mode for :client_once" do
114
+ ssl = HTTPI::Auth::SSL.new
115
+
116
+ ssl.verify_mode = :client_once
117
+ ssl.openssl_verify_mode.should == OpenSSL::SSL::VERIFY_CLIENT_ONCE
118
+ end
119
+ end
120
+
121
+ def ssl
122
+ ssl = HTTPI::Auth::SSL.new
123
+ ssl.cert_key_file = "spec/fixtures/client_key.pem"
124
+ ssl.cert_file = "spec/fixtures/client_cert.pem"
125
+ ssl
126
+ end
127
+
128
+ end
@@ -0,0 +1,284 @@
1
+ require "spec_helper"
2
+ require "cs-httpi"
3
+
4
+ describe HTTPI do
5
+ let(:client) { HTTPI }
6
+ let(:httpclient) { HTTPI::Adapter.load(:httpclient)[1] }
7
+ let(:curb) { HTTPI::Adapter.load(:curb)[1] }
8
+
9
+ describe ".get(request)" do
10
+ it "executes a GET request using the default adapter" do
11
+ request = HTTPI::Request.new
12
+ httpclient.any_instance.expects(:get).with(request)
13
+
14
+ client.get request
15
+ end
16
+ end
17
+
18
+ describe ".get(request, adapter)" do
19
+ it "executes a GET request using the given adapter" do
20
+ request = HTTPI::Request.new
21
+ curb.any_instance.expects(:get).with(request)
22
+
23
+ client.get request, :curb
24
+ end
25
+ end
26
+
27
+ describe ".get(url)" do
28
+ it "executes a GET request using the default adapter" do
29
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
30
+ httpclient.any_instance.expects(:get).with(instance_of(HTTPI::Request))
31
+
32
+ client.get "http://example.com"
33
+ end
34
+ end
35
+
36
+ describe ".get(url, adapter)" do
37
+ it "executes a GET request using the given adapter" do
38
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
39
+ curb.any_instance.expects(:get).with(instance_of(HTTPI::Request))
40
+
41
+ client.get "http://example.com", :curb
42
+ end
43
+ end
44
+
45
+ describe ".post(request)" do
46
+ it "executes a POST request using the default adapter" do
47
+ request = HTTPI::Request.new
48
+ httpclient.any_instance.expects(:post).with(request)
49
+
50
+ client.post request
51
+ end
52
+ end
53
+
54
+ describe ".post(request, adapter)" do
55
+ it "executes a POST request using the given adapter" do
56
+ request = HTTPI::Request.new
57
+ curb.any_instance.expects(:post).with(request)
58
+
59
+ client.post request, :curb
60
+ end
61
+ end
62
+
63
+ describe ".post(url, body)" do
64
+ it "executes a POST request using the default adapter" do
65
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
66
+ HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
67
+ httpclient.any_instance.expects(:post).with(instance_of(HTTPI::Request))
68
+
69
+ client.post "http://example.com", "<some>xml</some>"
70
+ end
71
+ end
72
+
73
+ describe ".post(url, body, adapter)" do
74
+ it "executes a POST request using the given adapter" do
75
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
76
+ HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
77
+ curb.any_instance.expects(:post).with(instance_of(HTTPI::Request))
78
+
79
+ client.post "http://example.com", "<some>xml</some>", :curb
80
+ end
81
+ end
82
+
83
+ describe ".head(request)" do
84
+ it "executes a HEAD request using the default adapter" do
85
+ request = HTTPI::Request.new
86
+ httpclient.any_instance.expects(:head).with(request)
87
+
88
+ client.head request
89
+ end
90
+ end
91
+
92
+ describe ".head(request, adapter)" do
93
+ it "executes a HEAD request using the given adapter" do
94
+ request = HTTPI::Request.new
95
+ curb.any_instance.expects(:head).with(request)
96
+
97
+ client.head request, :curb
98
+ end
99
+ end
100
+
101
+ describe ".head(url)" do
102
+ it "executes a HEAD request using the default adapter" do
103
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
104
+ httpclient.any_instance.expects(:head).with(instance_of(HTTPI::Request))
105
+
106
+ client.head "http://example.com"
107
+ end
108
+ end
109
+
110
+ describe ".head(url, adapter)" do
111
+ it "executes a HEAD request using the given adapter" do
112
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
113
+ curb.any_instance.expects(:head).with(instance_of(HTTPI::Request))
114
+
115
+ client.head "http://example.com", :curb
116
+ end
117
+ end
118
+
119
+ describe ".put(request)" do
120
+ it "executes a PUT request using the default adapter" do
121
+ request = HTTPI::Request.new
122
+ httpclient.any_instance.expects(:put).with(request)
123
+
124
+ client.put request
125
+ end
126
+ end
127
+
128
+ describe ".put(request, adapter)" do
129
+ it "executes a PUT request using the given adapter" do
130
+ request = HTTPI::Request.new
131
+ curb.any_instance.expects(:put).with(request)
132
+
133
+ client.put request, :curb
134
+ end
135
+ end
136
+
137
+ describe ".put(url, body)" do
138
+ it "executes a PUT request using the default adapter" do
139
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
140
+ HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
141
+ httpclient.any_instance.expects(:put).with(instance_of(HTTPI::Request))
142
+
143
+ client.put "http://example.com", "<some>xml</some>"
144
+ end
145
+ end
146
+
147
+ describe ".put(url, body, adapter)" do
148
+ it "executes a PUT request using the given adapter" do
149
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
150
+ HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
151
+ curb.any_instance.expects(:put).with(instance_of(HTTPI::Request))
152
+
153
+ client.put "http://example.com", "<some>xml</some>", :curb
154
+ end
155
+ end
156
+
157
+ describe ".delete(request)" do
158
+ it "executes a DELETE request using the default adapter" do
159
+ request = HTTPI::Request.new
160
+ httpclient.any_instance.expects(:delete).with(request)
161
+
162
+ client.delete request
163
+ end
164
+ end
165
+
166
+ describe ".delete(request, adapter)" do
167
+ it "executes a DELETE request using the given adapter" do
168
+ request = HTTPI::Request.new
169
+ curb.any_instance.expects(:delete).with(request)
170
+
171
+ client.delete request, :curb
172
+ end
173
+ end
174
+
175
+ describe ".delete(url)" do
176
+ it "executes a DELETE request using the default adapter" do
177
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
178
+ httpclient.any_instance.expects(:delete).with(instance_of(HTTPI::Request))
179
+
180
+ client.delete "http://example.com"
181
+ end
182
+ end
183
+
184
+ describe ".delete(url, adapter)" do
185
+ it "executes a DELETE request using the given adapter" do
186
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
187
+ curb.any_instance.expects(:delete).with(instance_of(HTTPI::Request))
188
+
189
+ client.delete "http://example.com", :curb
190
+ end
191
+ end
192
+
193
+ describe ".request" do
194
+ it "raises an ArgumentError in case of an invalid request method" do
195
+ expect { client.request :invalid, HTTPI::Request.new }.to raise_error(ArgumentError)
196
+ end
197
+ end
198
+
199
+ describe ".adapter=" do
200
+ it "sets the default adapter to use" do
201
+ HTTPI::Adapter.expects(:use=).with(:net_http)
202
+ HTTPI.adapter = :net_http
203
+ end
204
+ end
205
+
206
+ HTTPI::REQUEST_METHODS.each do |method|
207
+ describe ".request(#{method}, request, adapter)" do
208
+ it "delegates to the .#{method} method" do
209
+ HTTPI.expects(method)
210
+ client.request method, HTTPI::Request.new
211
+ end
212
+ end
213
+
214
+ describe ".#{method}" do
215
+ let(:request) { HTTPI::Request.new :url => "http://example.com" }
216
+
217
+ it "raises an ArgumentError in case of an invalid adapter" do
218
+ expect { client.request method, request, :invalid }.to raise_error(ArgumentError)
219
+ end
220
+
221
+ it "raises an ArgumentError in case of an invalid request" do
222
+ expect { client.request method, "invalid" }.to raise_error(ArgumentError)
223
+ end
224
+
225
+ HTTPI::Adapter::ADAPTERS.each do |adapter, opts|
226
+ client_class = {
227
+ :httpclient => lambda { HTTPClient },
228
+ :curb => lambda { Curl::Easy },
229
+ :net_http => lambda { Net::HTTP }
230
+ }
231
+
232
+ context "using #{adapter}" do
233
+ before { opts[:class].any_instance.expects(method) }
234
+
235
+ it "logs that we're executing a request" do
236
+ HTTPI.expects(:log).with(:debug, "HTTPI executes HTTP #{method.to_s.upcase} using the #{adapter} adapter")
237
+ client.request method, request, adapter
238
+ end
239
+
240
+ it "yields the HTTP client instance used for the request" do
241
+ block = lambda { |http| http.be_a(client_class[adapter].call) }
242
+ client.request(method, request, adapter, &block)
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end
248
+
249
+ context "(with reset)" do
250
+ before { HTTPI.reset_config! }
251
+
252
+ after do
253
+ HTTPI.reset_config!
254
+ HTTPI.log = false # disable for specs
255
+ end
256
+
257
+ describe ".log" do
258
+ it "defaults to true" do
259
+ HTTPI.log?.should be_true
260
+ end
261
+ end
262
+
263
+ describe ".logger" do
264
+ it "defaults to Logger writing to STDOUT" do
265
+ HTTPI.logger.should be_a(Logger)
266
+ end
267
+ end
268
+
269
+ describe ".log_level" do
270
+ it "defaults to :warn" do
271
+ HTTPI.log_level.should == :warn
272
+ end
273
+ end
274
+
275
+ describe ".log" do
276
+ it "logs the given messages" do
277
+ HTTPI.log_level = :debug
278
+ HTTPI.logger.expects(:debug).with("Log this")
279
+ HTTPI.log "Log", "this"
280
+ end
281
+ end
282
+ end
283
+
284
+ end
@@ -0,0 +1,140 @@
1
+ require "spec_helper"
2
+ require "cs-httpi/request"
3
+
4
+ describe HTTPI::Request do
5
+ let(:request) { HTTPI::Request.new }
6
+
7
+ describe ".new" do
8
+ it "accepts a url" do
9
+ request = HTTPI::Request.new "http://example.com"
10
+ request.url.should == URI("http://example.com")
11
+ end
12
+
13
+ it "accepts a Hash of accessors to set" do
14
+ request = HTTPI::Request.new :url => "http://example.com", :open_timeout => 30
15
+ request.url.should == URI("http://example.com")
16
+ request.open_timeout.should == 30
17
+ end
18
+ end
19
+
20
+ describe "#url" do
21
+ it "lets you specify the URL to access as a String" do
22
+ request.url = "http://example.com"
23
+ request.url.should == URI("http://example.com")
24
+ end
25
+
26
+ it "also accepts a URI object" do
27
+ request.url = URI("http://example.com")
28
+ request.url.should == URI("http://example.com")
29
+ end
30
+
31
+ it "raises an ArgumentError in case of an invalid url" do
32
+ expect { request.url = "invalid" }.to raise_error(ArgumentError)
33
+ end
34
+ end
35
+
36
+ describe "#proxy" do
37
+ it "lets you specify the proxy URL to use as a String" do
38
+ request.proxy = "http://proxy.example.com"
39
+ request.proxy.should == URI("http://proxy.example.com")
40
+ end
41
+
42
+ it "also accepts a URI object" do
43
+ request.proxy = URI("http://proxy.example.com")
44
+ request.proxy.should == URI("http://proxy.example.com")
45
+ end
46
+
47
+ it "raises an ArgumentError in case of an invalid url" do
48
+ expect { request.proxy = "invalid" }.to raise_error(ArgumentError)
49
+ end
50
+ end
51
+
52
+ describe "#ssl" do
53
+ it "returns false if no request url was specified" do
54
+ request.should_not be_ssl
55
+ end
56
+
57
+ it "returns false if the request url does not start with https" do
58
+ request.url = "http://example.com"
59
+ request.should_not be_ssl
60
+ end
61
+
62
+ it "returns true if the request url starts with https" do
63
+ request.url = "https://example.com"
64
+ request.should be_ssl
65
+ end
66
+
67
+ context "with an explicit value" do
68
+ it "returns the value" do
69
+ request.ssl = true
70
+ request.should be_ssl
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "#headers" do
76
+ it "lets you specify a Hash of HTTP request headers" do
77
+ request.headers = { "Accept-Encoding" => "gzip" }
78
+ request.headers.should == { "Accept-Encoding" => "gzip" }
79
+ end
80
+
81
+ it "defaults to return an empty Hash" do
82
+ request.headers.should == {}
83
+ end
84
+ end
85
+
86
+ describe "#gzip" do
87
+ it "adds the proper 'Accept-Encoding' header" do
88
+ request.gzip
89
+ request.headers["Accept-Encoding"].should == "gzip,deflate"
90
+ end
91
+ end
92
+
93
+ describe "#body" do
94
+ it "lets you specify the HTTP request body" do
95
+ request.body = "<some>xml</some>"
96
+ request.body.should == "<some>xml</some>"
97
+ end
98
+
99
+ it "lets you specify the HTTP request body as hash" do
100
+ request.body = {:some => "content", :another => "content"}
101
+ request.body.should == "some=content&another=content"
102
+ end
103
+ end
104
+
105
+ describe "#open_timeout" do
106
+ it "lets you specify the open timeout" do
107
+ request.open_timeout = 30
108
+ request.open_timeout.should == 30
109
+ end
110
+ end
111
+
112
+ describe "#read_timeout" do
113
+ it "lets you specify the read timeout" do
114
+ request.read_timeout = 45
115
+ request.read_timeout.should == 45
116
+ end
117
+ end
118
+
119
+ describe "#auth" do
120
+ it "returns the authentication object" do
121
+ request.auth.should be_an(HTTPI::Auth::Config)
122
+ end
123
+
124
+ it "memoizes the authentication object" do
125
+ request.auth.should equal(request.auth)
126
+ end
127
+ end
128
+
129
+ describe "#auth?" do
130
+ it "returns true when auth credentials are specified" do
131
+ request.auth.basic "username", "password"
132
+ request.auth?.should be_true
133
+ end
134
+
135
+ it "returns false otherwise" do
136
+ request.auth?.should be_false
137
+ end
138
+ end
139
+
140
+ end