glebtv-httpclient 3.2.4 → 3.2.6

Sign up to get free protection for your applications and to get access to all the features.
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