glebtv-httpclient 3.2.4 → 3.2.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67da2be91a12b0b8e107d865eea78fca6118bf5c
4
- data.tar.gz: 9ffc63296d22b328aab17af7832060cd3894c1f1
3
+ metadata.gz: d57dc51e3125fe47a5913b35f918f7de23a198b3
4
+ data.tar.gz: b246d47f730cb1da959fab0574674fd1e2046ddd
5
5
  SHA512:
6
- metadata.gz: 78f6a87dfda29f7ee7cf46d812b6b3af37419ebf9088898c6b994c129a2e4b4692cfd19f276dfba61c71a590a0a0795f0c50f1d702d6b8251c032014d7b805d2
7
- data.tar.gz: 97e997886c7c72cb855783e94bd95b2cd8425af4f72e5d178c4dc1846dd6451d680cef33cfaa4d7fd632b90e22aca106dec5ec237546a03fa30a03a5a2cf6c8f
6
+ metadata.gz: 494ab4ac5e4357fec105b6d48b74f6b494d05e7343344f8f37c09e22d176f052716239c1953d3a293091e81e7b7876fa0c2560cc441f0d149bbb773d7238396e
7
+ data.tar.gz: 7ff5805d66e3d6cf6602152c246799c7656a109708dbf6d215cc633a23b7823b44998ec8895a60c3f1073c6272d2af0023493084c56b23e6365605dedb7f3adb
data/Gemfile.lock CHANGED
@@ -1,12 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- glebtv-httpclient (3.2.3)
4
+ glebtv-httpclient (3.2.5)
5
5
  lru_redux
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
+ activesupport (3.2.17)
11
+ i18n (~> 0.6, >= 0.6.4)
12
+ multi_json (~> 1.0)
13
+ climate_control (0.0.3)
14
+ activesupport (>= 3.0)
10
15
  coveralls (0.7.0)
11
16
  multi_json (~> 1.3)
12
17
  rest-client
@@ -16,11 +21,12 @@ GEM
16
21
  diff-lcs (1.2.5)
17
22
  docile (1.1.3)
18
23
  ffi2-generators (0.1.1)
24
+ i18n (0.6.9)
19
25
  json (1.8.1)
20
26
  lru_redux (0.8.1)
21
27
  mime-types (2.2)
22
28
  multi_json (1.9.2)
23
- rake (10.2.2)
29
+ rake (10.3.0)
24
30
  rdoc (4.1.1)
25
31
  json (~> 1.4)
26
32
  rest-client (1.6.7)
@@ -33,6 +39,13 @@ GEM
33
39
  rspec-expectations (2.14.5)
34
40
  diff-lcs (>= 1.1.3, < 2.0)
35
41
  rspec-mocks (2.14.6)
42
+ rspecify (0.1.7)
43
+ activesupport (>= 3.0)
44
+ i18n (~> 0.6.0)
45
+ ruby_parser (~> 2.3.1)
46
+ ruby_scribe (~> 0.1.4)
47
+ ruby_transform (~> 0.1.4)
48
+ thor (~> 0.13)
36
49
  rubinius-coverage (2.0.3)
37
50
  rubinius-debugger (2.0.3)
38
51
  rubinius-developer_tools (2.0.0)
@@ -40,6 +53,19 @@ GEM
40
53
  rubinius-debugger (~> 2.0)
41
54
  rubinius-profiler (~> 2.0)
42
55
  rubinius-profiler (2.0.1)
56
+ ruby_parser (2.3.1)
57
+ sexp_processor (~> 3.0)
58
+ ruby_scribe (0.1.5)
59
+ activesupport (~> 3.0)
60
+ i18n (~> 0.6.0)
61
+ ruby_parser (~> 2.3.1)
62
+ thor (~> 0.13)
63
+ ruby_transform (0.1.5)
64
+ activesupport (>= 3.0)
65
+ i18n (~> 0.6.0)
66
+ ruby_parser (~> 2.3.1)
67
+ ruby_scribe (~> 0.1.4)
68
+ thor (~> 0.13)
43
69
  rubysl (2.0.15)
44
70
  rubysl-abbrev (~> 2.0)
45
71
  rubysl-base64 (~> 2.0)
@@ -242,6 +268,7 @@ GEM
242
268
  rubysl-xmlrpc (2.0.0)
243
269
  rubysl-yaml (2.0.4)
244
270
  rubysl-zlib (2.0.1)
271
+ sexp_processor (3.2.0)
245
272
  simplecov (0.8.2)
246
273
  docile (~> 1.1.0)
247
274
  multi_json
@@ -258,12 +285,14 @@ PLATFORMS
258
285
 
259
286
  DEPENDENCIES
260
287
  bundler
288
+ climate_control
261
289
  coveralls
262
290
  glebtv-httpclient!
263
291
  jruby-openssl
264
292
  rake
265
293
  rdoc
266
294
  rspec
295
+ rspecify
267
296
  rubinius-developer_tools
268
297
  rubysl (~> 2.0)
269
298
  test-unit
data/httpclient.gemspec CHANGED
@@ -28,4 +28,6 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'rspec'
29
29
  spec.add_development_dependency 'rdoc'
30
30
  spec.add_development_dependency 'coveralls'
31
+ spec.add_development_dependency 'climate_control'
32
+ spec.add_development_dependency 'rspecify'
31
33
  end
@@ -816,30 +816,33 @@ class HTTPClient
816
816
  socket = nil
817
817
  begin
818
818
  @debug_dev << "! CONNECT TO #{site.host}:#{site.port}\n" if @debug_dev
819
+ raise HTTPClient::BadURIError.new('Unable to get hostname from URI') if site.host.nil?
819
820
  clean_host = site.host.delete("[]")
820
- clean_local = @socket_local.host.delete("[]")
821
821
  if str = @test_loopback_http_response.shift
822
822
  socket = LoopBackSocket.new(clean_host, site.port, str)
823
823
  else
824
824
  begin
825
- ip = IPAddr.new(clean_host).to_s
826
- # puts "! #{site.host} IS AN IP!\n"
827
- # @debug_dev << "! #{site.host} IS AN IP!\n" if @debug_dev
825
+ ips = [ IPAddr.new(clean_host) ]
828
826
  rescue
829
- ip = HTTPClient.dns_cache.fetch clean_host do
827
+ ips = HTTPClient.dns_cache.fetch clean_host do
830
828
  Timeout.timeout(10) do
831
- # @debug_dev << "! RESOLVING #{clean_host}" if @debug_dev
832
- ip = Resolv.getaddress(clean_host)
833
- # puts "! RESOLVED #{clean_host} TO #{ip}\n"
834
- # @debug_dev << "! RESOLVED #{clean_host} TO #{ip}\n" if @debug_dev
835
- ip
829
+ Resolv.getaddresses(clean_host)
836
830
  end
837
831
  end
838
832
  end
839
833
 
840
834
  if @socket_local == Site::EMPTY
841
- socket = TCPSocket.new(ip, site.port)
835
+ socket = TCPSocket.new(ips.first.to_s, site.port)
842
836
  else
837
+ clean_local = @socket_local.host.delete("[]").to_s
838
+ if IPAddr.new(clean_local).ipv6?
839
+ ip = ips.select { |i| IPAddr.new(i).ipv6? }.first
840
+ else
841
+ ip = ips.select { |i| IPAddr.new(i).ipv4? }.first
842
+ end
843
+ if ip.nil?
844
+ raise HTTPClient::BadIPProtoError.new("Unable to select matching source and destination ip addresses (v4/v6) for connecting to #{ips.join(',')} from #{clean_local}")
845
+ end
843
846
  socket = TCPSocket.new(ip, site.port, clean_local, @socket_local.port)
844
847
  end
845
848
  end
@@ -1,3 +1,3 @@
1
1
  class HTTPClient
2
- VERSION = '3.2.4' unless defined?(VERSION)
2
+ VERSION = '3.2.6' unless defined?(VERSION)
3
3
  end
data/lib/httpclient.rb CHANGED
@@ -260,6 +260,14 @@ class HTTPClient
260
260
  @res = res
261
261
  end
262
262
  end
263
+
264
+ # Raised for indicating bad URIs
265
+ class BadURIError < RuntimeError
266
+ end
267
+
268
+ # Raised when trying to request with bad proto
269
+ class BadIPProtoError < RuntimeError
270
+ end
263
271
 
264
272
  # Raised for indicating a timeout error.
265
273
  class TimeoutError < RuntimeError
@@ -0,0 +1,326 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe HTTPClient do
5
+ before :each do
6
+ @client = HTTPClient.new
7
+ end
8
+
9
+ describe 'GET' do
10
+ it 'performs normal GET' do
11
+ HTTPClient.new.get(@srv.u('servlet')) do |s|
12
+ s.should eq 'get'
13
+ end
14
+ end
15
+
16
+ it 'raises if bad URI' do
17
+ expect { HTTPClient.get_content '/z/' }.to raise_error(HTTPClient::BadURIError)
18
+ end
19
+
20
+ describe '#download_file' do
21
+ it 'writes to file' do
22
+ file = Tempfile.new('httpcl')
23
+ HTTPClient.new.download_file(@srv.u('largebody'), file.path)
24
+ file.read.length.should eq 1_000_000
25
+ end
26
+
27
+ it 'compressed' do
28
+ file = Tempfile.new('httpcl')
29
+ @client.download_file(@srv.u('compressed?enc=gzip'), file.path)
30
+ file.read.length.should eq 25
31
+ end
32
+
33
+ it 'compressed transparent' do
34
+ @client.transparent_gzip_decompression = true
35
+
36
+ file = Tempfile.new('httpcl')
37
+ @client.download_file(@srv.u('compressed?enc=gzip'), file.path)
38
+ cnt = file.read
39
+ cnt.length.should eq 5
40
+ cnt.should eq 'hello'
41
+
42
+ @client.download_file(@srv.u('compressed?enc=deflate'), file.path)
43
+ cnt = file.read
44
+ cnt.length.should eq 5
45
+ cnt.should eq 'hello'
46
+ end
47
+
48
+ it 'compressed large' do
49
+ file = Tempfile.new('httpcl')
50
+ @client.transparent_gzip_decompression = true
51
+
52
+ content = @client.download_file(@srv.u('compressed_large?enc=gzip'), file.path)
53
+ file.read.should eq LARGE_STR
54
+
55
+ content = @client.download_file(@srv.u('compressed_large?enc=deflate'), file.path)
56
+ file.read.should eq LARGE_STR
57
+ end
58
+ end
59
+
60
+ describe '#get_content' do
61
+ it 'normal' do
62
+ @client.get_content(@srv.u('hello')).should eq 'hello'
63
+ @client.get_content(@srv.u('redirect1')).should eq 'hello'
64
+ @client.get_content(@srv.u('redirect2')).should eq 'hello'
65
+ end
66
+
67
+ it '127.0.0.1' do
68
+ url = @srv.u.sub(/localhost/, '127.0.0.1')
69
+ @client.get_content(url + 'hello').should eq 'hello'
70
+ @client.get_content(url + 'redirect1').should eq 'hello'
71
+ @client.get_content(url + 'redirect2').should eq 'hello'
72
+ end
73
+
74
+ it 'redirect callback' do
75
+ called = false
76
+ @client.redirect_uri_callback = lambda { |uri, res|
77
+ newuri = res.header['location'][0]
78
+ called = true
79
+ newuri
80
+ }
81
+
82
+ @client.get_content(@srv.u('relative_redirect')).should eq 'hello'
83
+ called.should be_true
84
+ end
85
+
86
+ it 'errors' do
87
+ expect {
88
+ @client.get_content(@srv.u 'notfound')
89
+ }.to raise_error(HTTPClient::BadResponseError)
90
+
91
+ expect {
92
+ @client.get_content(@srv.u 'redirect_self')
93
+ }.to raise_error(HTTPClient::BadResponseError)
94
+ end
95
+
96
+ it 'with block' do
97
+ @client.get_content(@srv.u 'hello') do |str|
98
+ str.should eq 'hello'
99
+ end
100
+ @client.get_content(@srv.u + 'redirect1') do |str|
101
+ str.should eq 'hello'
102
+ end
103
+ @client.get_content(@srv.u + 'redirect2') do |str|
104
+ str.should eq 'hello'
105
+ end
106
+ end
107
+
108
+ it 'compressed' do
109
+ @client.transparent_gzip_decompression = false
110
+
111
+ content = @client.get_content(@srv.u 'compressed?enc=gzip')
112
+ content.should_not eq 'hello'
113
+ content.should eq GZIP_CONTENT
114
+ @client.transparent_gzip_decompression = true
115
+
116
+ content = @client.get_content(@srv.u 'compressed?enc=gzip')
117
+ content.should eq 'hello'
118
+
119
+ content = @client.get_content(@srv.u 'compressed?enc=deflate')
120
+ content.should eq 'hello'
121
+ end
122
+
123
+ it 'compressed large' do
124
+ @client.transparent_gzip_decompression = true
125
+
126
+ content = @client.get_content(@srv.u 'compressed_large?enc=gzip')
127
+ content.should eq LARGE_STR
128
+
129
+ content = @client.get_content(@srv.u 'compressed_large?enc=deflate')
130
+ content.should eq LARGE_STR
131
+ end
132
+ end
133
+ end
134
+ describe 'request' do
135
+ describe 'get with block' do
136
+ it 'works with filter_block: true' do
137
+ @client.request(:get, @srv.u('hello')) do |str|
138
+ str.should eq 'hello'
139
+ end
140
+ end
141
+ it 'works with filter_block: false' do
142
+ @client.request(:get, @srv.u('hello'), filter_block: false) do |req, str|
143
+ req.class.name.should eq 'HTTP::Message'
144
+ str.should eq 'hello'
145
+ end
146
+ end
147
+ end
148
+ end
149
+ describe 'agent name' do
150
+ it 'default' do
151
+ str = ""
152
+ @client.debug_dev = str
153
+ @client.get(@srv.u)
154
+ lines = str.split(/(?:\r?\n)+/)
155
+ lines[0].should eq '= Request'
156
+ lines[4].should eq "User-Agent: HTTPClient #{HTTPClient::VERSION}"
157
+ end
158
+
159
+ it 'custom' do
160
+ client = HTTPClient.new(nil, "agent_name_foo")
161
+ str = ""
162
+ client.debug_dev = str
163
+ client.get(@srv.u)
164
+ lines = str.split(/(?:\r?\n)+/)
165
+ lines[0].should eq '= Request'
166
+ lines[4].should eq 'User-Agent: agent_name_foo'
167
+ end
168
+ end
169
+
170
+ describe 'protocol versions' do
171
+ it '0.9' do
172
+ @client.protocol_version = 'HTTP/0.9'
173
+ @client.debug_dev = str = ''
174
+ @client.test_loopback_http_response << "hello\nworld\n"
175
+ res = @client.get(@srv.u 'hello')
176
+ res.http_version.should eq '0.9'
177
+ res.status.should be_nil
178
+ res.reason.should be_nil
179
+ res.content.should eq "hello\nworld\n"
180
+ lines = str.split(/(?:\r?\n)+/)
181
+ lines[0].should eq "= Request"
182
+ lines[2].should eq "! CONNECTION ESTABLISHED"
183
+ lines[3].should eq "GET /hello HTTP/0.9"
184
+ lines[7].should eq "Connection: close"
185
+ lines[8].should eq "= Response"
186
+ lines[9].should match /^hello$/
187
+ lines[10].should match /^world$/
188
+ end
189
+
190
+ it '1.0' do
191
+ @client.protocol_version.should be_nil
192
+ @client.protocol_version = 'HTTP/1.0'
193
+ @client.protocol_version.should eq 'HTTP/1.0'
194
+ str = ""
195
+ @client.debug_dev = str
196
+ @client.get(@srv.u 'hello')
197
+ lines = str.split(/(?:\r?\n)+/)
198
+ lines[0].should eq "= Request"
199
+ lines[2].should eq "! CONNECTION ESTABLISHED"
200
+ lines[3].should eq "GET /hello HTTP/1.0"
201
+ lines[7].should eq "Connection: close"
202
+ lines[8].should eq "= Response"
203
+ end
204
+
205
+ it '1.1' do
206
+ @client.protocol_version.should be_nil
207
+ str = ""
208
+ @client.debug_dev = str
209
+ @client.get(@srv.u)
210
+ lines = str.split(/(?:\r?\n)+/)
211
+ lines[0].should eq "= Request"
212
+ lines[2].should eq "! CONNECTION ESTABLISHED"
213
+ lines[3].should eq "GET / HTTP/1.1"
214
+ lines[7].should eq "Host: localhost:#{@srv.port}"
215
+ @client.protocol_version = 'HTTP/1.1'
216
+ @client.protocol_version.should eq 'HTTP/1.1'
217
+ str = ""
218
+ @client.debug_dev = str
219
+ @client.get(@srv.u)
220
+ lines = str.split(/(?:\r?\n)+/)
221
+ lines[0].should eq "= Request"
222
+ lines[2].should eq "! CONNECTION ESTABLISHED"
223
+ lines[3].should eq "GET / HTTP/1.1"
224
+ @client.protocol_version = 'HTTP/1.0'
225
+ str = ""
226
+ @client.debug_dev = str
227
+ @client.get(@srv.u)
228
+ lines = str.split(/(?:\r?\n)+/)
229
+ lines[0].should eq "= Request"
230
+ lines[2].should eq "! CONNECTION ESTABLISHED"
231
+ lines[3].should eq "GET / HTTP/1.0"
232
+ end
233
+ end
234
+
235
+ describe 'accept' do
236
+ it '*/* by default' do
237
+ str = ""
238
+ @client.debug_dev = str
239
+ @client.get(@srv.u)
240
+ lines = str.split(/(?:\r?\n)+/)
241
+ lines[5].should eq "Accept: */*"
242
+ end
243
+
244
+ it 'sets properly' do
245
+ str = ""
246
+ @client.debug_dev = str
247
+ @client.get(@srv.u, :header => {:Accept => 'text/html'})
248
+ lines = str.split(/(?:\r?\n)+/)
249
+ lines[4].should eq "Accept: text/html"
250
+ lines.each do |line|
251
+ line.should_not eq "Accept: */*"
252
+ end
253
+ end
254
+ end
255
+
256
+ describe 'POST' do
257
+ describe '#post_content' do
258
+ it 'works' do
259
+ @client.post_content(@srv.u('hello')).should eq 'hello'
260
+ @client.post_content(@srv.u("redirect1")).should eq 'hello'
261
+ @client.post_content(@srv.u("redirect2")).should eq 'hello'
262
+ end
263
+ end
264
+
265
+ it 'redirect callback' do
266
+ called = false
267
+ @client.redirect_uri_callback = lambda { |uri, res|
268
+ newuri = res.header['location'][0]
269
+ called = true
270
+ newuri
271
+ }
272
+ @client.post_content(@srv.u("relative_redirect")).should eq 'hello'
273
+ called.should be_true
274
+ end
275
+
276
+ it 'errors' do
277
+ expect {
278
+ @client.post_content(@srv.u 'notfound')
279
+ }.to raise_error(HTTPClient::BadResponseError)
280
+
281
+ expect {
282
+ @client.post_content(@srv.u 'redirect_self')
283
+ }.to raise_error(HTTPClient::BadResponseError)
284
+ end
285
+
286
+
287
+ describe 'string io' do
288
+ it do
289
+ post_body = StringIO.new("1234567890")
290
+ @client.post_content(@srv.u("servlet"), post_body).should eq 'post,1234567890'
291
+
292
+ # all browsers use GET for 302
293
+ post_body = StringIO.new("1234567890")
294
+ @client.post_content(@srv.u("servlet_413"), post_body).should eq '1234567890'
295
+
296
+ @client.get_content(@srv.u("servlet_redirect_413")).should eq ''
297
+
298
+ post_body = StringIO.new("1234567890")
299
+ @client.post_content(@srv.u("servlet_redirect_413"), post_body).should eq ''
300
+
301
+ post_body = StringIO.new("1234567890")
302
+ @client.post_content(@srv.u("servlet_temporary_redirect"), post_body).should eq 'post,1234567890'
303
+
304
+ post_body = StringIO.new("1234567890")
305
+ @client.post_content(@srv.u("servlet_see_other"), post_body).should eq 'get'
306
+ end
307
+
308
+ it 'doesnt rewind' do
309
+ post_body = StringIO.new("1234567890")
310
+ post_body.read(5)
311
+ @client.post_content(@srv.u("servlet_temporary_redirect"), post_body).should eq 'post,67890'
312
+ end
313
+ end
314
+ end
315
+
316
+ describe 'util' do
317
+ it '#urify' do
318
+ urify(nil).should be_nil
319
+ uri = 'http://foo'
320
+ # urify(uri).class.name.should eq 'HTTPClient::Util::AddressableURI'
321
+ urify(uri).should eq urify(uri)
322
+ urify(uri).to_s.should eq uri
323
+ urify(urify(uri)).should eq urify(uri)
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+ require 'hexdump'
4
+
5
+ describe 'HexDump' do
6
+ it 'encode' do
7
+ str = "\032l\277\370\2429\216\236\351[{\{\262\350\274\376"
8
+ str.force_encoding('BINARY') if str.respond_to?(:force_encoding)
9
+ HexDump.encode(str).should eq ["00000000 1a6cbff8 a2398e9e e95b7b7b b2e8bcfe .l...9...[{{...."]
10
+ end
11
+ end