glebtv-httpclient 3.2.7 → 3.2.8

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.
@@ -4,58 +4,61 @@
4
4
  # (MIT Licensed). Thanks!
5
5
 
6
6
  require "lru_redux"
7
+ require 'thread'
7
8
 
8
- # Not thread-safe!
9
9
  class HTTPClient
10
10
  class LRUCache
11
11
 
12
12
  attr_reader :max_size, :ttl, :soft_ttl, :retry_delay
13
13
 
14
14
  def initialize(opts={})
15
+ @mutex = Mutex.new
16
+
15
17
  @max_size = Integer(opts[:max_size] || 100)
16
18
  @ttl = Float(opts[:ttl] || 0)
17
19
  @soft_ttl = Float(opts[:soft_ttl] || 0)
18
20
  @retry_delay = Float(opts[:retry_delay] || 0)
21
+
19
22
  raise "max_size must not be negative" if @max_size < 0
20
23
  raise "ttl must not be negative" if @ttl < 0
21
24
  raise "soft_ttl must not be negative" if @soft_ttl < 0
22
25
  raise "retry_delay must not be negative" if @retry_delay < 0
23
26
 
27
+ # we don't use thread safe variant, as we're doing thread safety ourselves
24
28
  @data = LruRedux::Cache.new(@max_size)
25
29
  end
26
30
 
27
- def store(key, value)
28
- expiration = Time.now + @ttl
29
- soft_expiration = Time.now + @soft_ttl
30
- @data[key] = Datum.new(value, expiration, soft_expiration)
31
- value
32
- end
33
-
34
- alias :[]= :store
35
-
36
31
  def fetch(key)
37
- datum = @data[key]
38
- if datum.nil?
39
- store(key, value = yield)
40
- elsif datum.expired?
41
- @data.delete(key)
42
- store(key, value = yield)
43
- elsif datum.soft_expired?
44
- begin
32
+ # for now, this means that DNS resolving is single-threaded
33
+ @mutex.synchronize do
34
+ datum = @data[key]
35
+ if datum.nil?
45
36
  store(key, value = yield)
46
- rescue RuntimeError => e
47
- datum.soft_expiration = (Time.now + retry_delay) if retry_delay > 0
37
+ elsif datum.expired?
38
+ @data.delete(key)
39
+ store(key, value = yield)
40
+ elsif datum.soft_expired?
41
+ begin
42
+ store(key, value = yield)
43
+ rescue RuntimeError => e
44
+ datum.soft_expiration = (Time.now + retry_delay) if retry_delay > 0
45
+ datum.value
46
+ end
47
+ else
48
48
  datum.value
49
49
  end
50
- else
51
- datum.value
52
50
  end
53
51
  end
54
52
 
55
- alias :[] :fetch
56
-
57
53
  private
58
54
 
55
+ def store(key, value)
56
+ expiration = Time.now + @ttl
57
+ soft_expiration = Time.now + @soft_ttl
58
+ @data[key] = Datum.new(value, expiration, soft_expiration)
59
+ value
60
+ end
61
+
59
62
  class Datum
60
63
  attr_reader :value, :expiration, :soft_expiration
61
64
  attr_writer :soft_expiration
@@ -123,9 +123,9 @@ class HTTPClient
123
123
  # use client_key=.
124
124
  #
125
125
  # Calling this method resets all existing sessions.
126
- def set_client_cert_file(cert_file, key_file)
126
+ def set_client_cert_file(cert_file, key_file, pass = nil)
127
127
  @client_cert = X509::Certificate.new(File.open(cert_file) { |f| f.read })
128
- @client_key = PKey::RSA.new(File.open(key_file) { |f| f.read })
128
+ @client_key = PKey::RSA.new(File.open(key_file) { |f| f.read }, pass)
129
129
  change_notify
130
130
  end
131
131
 
@@ -392,6 +392,7 @@ class HTTPClient
392
392
 
393
393
  def change_notify
394
394
  @client.reset_all
395
+ nil
395
396
  end
396
397
 
397
398
  def load_cacerts(cert_store)
@@ -1,3 +1,4 @@
1
1
  class HTTPClient
2
- VERSION = '3.2.7' unless defined?(VERSION)
2
+ VERSION = '3.2.8' unless defined?(VERSION)
3
3
  end
4
+
data/spec/basic_spec.rb CHANGED
@@ -9,7 +9,7 @@ describe HTTPClient do
9
9
  describe 'GET' do
10
10
  it 'performs normal GET' do
11
11
  HTTPClient.new.get(@srv.u('servlet')) do |s|
12
- s.should eq 'get'
12
+ expect(s).to eq 'get'
13
13
  end
14
14
  end
15
15
 
@@ -21,13 +21,13 @@ describe HTTPClient do
21
21
  it 'writes to file' do
22
22
  file = Tempfile.new('httpcl')
23
23
  HTTPClient.new.download_file(@srv.u('largebody'), file.path)
24
- file.read.length.should eq 1_000_000
24
+ expect(file.read.length).to eq 1_000_000
25
25
  end
26
26
 
27
27
  it 'compressed' do
28
28
  file = Tempfile.new('httpcl')
29
29
  @client.download_file(@srv.u('compressed?enc=gzip'), file.path)
30
- file.read.length.should eq 25
30
+ expect(file.read.length).to eq 25
31
31
  end
32
32
 
33
33
  it 'compressed transparent' do
@@ -36,13 +36,13 @@ describe HTTPClient do
36
36
  file = Tempfile.new('httpcl')
37
37
  @client.download_file(@srv.u('compressed?enc=gzip'), file.path)
38
38
  cnt = file.read
39
- cnt.length.should eq 5
40
- cnt.should eq 'hello'
39
+ expect(cnt.length).to eq 5
40
+ expect(cnt).to eq 'hello'
41
41
 
42
42
  @client.download_file(@srv.u('compressed?enc=deflate'), file.path)
43
43
  cnt = file.read
44
- cnt.length.should eq 5
45
- cnt.should eq 'hello'
44
+ expect(cnt.length).to eq 5
45
+ expect(cnt).to eq 'hello'
46
46
  end
47
47
 
48
48
  it 'compressed large' do
@@ -50,25 +50,25 @@ describe HTTPClient do
50
50
  @client.transparent_gzip_decompression = true
51
51
 
52
52
  content = @client.download_file(@srv.u('compressed_large?enc=gzip'), file.path)
53
- file.read.should eq LARGE_STR
53
+ expect(file.read).to eq LARGE_STR
54
54
 
55
55
  content = @client.download_file(@srv.u('compressed_large?enc=deflate'), file.path)
56
- file.read.should eq LARGE_STR
56
+ expect(file.read).to eq LARGE_STR
57
57
  end
58
58
  end
59
59
 
60
60
  describe '#get_content' do
61
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'
62
+ expect(@client.get_content(@srv.u('hello'))).to eq 'hello'
63
+ expect(@client.get_content(@srv.u('redirect1'))).to eq 'hello'
64
+ expect(@client.get_content(@srv.u('redirect2'))).to eq 'hello'
65
65
  end
66
66
 
67
67
  it '127.0.0.1' do
68
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'
69
+ expect(@client.get_content(url + 'hello')).to eq 'hello'
70
+ expect(@client.get_content(url + 'redirect1')).to eq 'hello'
71
+ expect(@client.get_content(url + 'redirect2')).to eq 'hello'
72
72
  end
73
73
 
74
74
  it 'redirect callback' do
@@ -79,8 +79,8 @@ describe HTTPClient do
79
79
  newuri
80
80
  }
81
81
 
82
- @client.get_content(@srv.u('relative_redirect')).should eq 'hello'
83
- called.should be_true
82
+ expect(@client.get_content(@srv.u('relative_redirect'))).to eq 'hello'
83
+ expect(called).to be_truthy
84
84
  end
85
85
 
86
86
  it 'errors' do
@@ -95,13 +95,13 @@ describe HTTPClient do
95
95
 
96
96
  it 'with block' do
97
97
  @client.get_content(@srv.u 'hello') do |str|
98
- str.should eq 'hello'
98
+ expect(str).to eq 'hello'
99
99
  end
100
100
  @client.get_content(@srv.u + 'redirect1') do |str|
101
- str.should eq 'hello'
101
+ expect(str).to eq 'hello'
102
102
  end
103
103
  @client.get_content(@srv.u + 'redirect2') do |str|
104
- str.should eq 'hello'
104
+ expect(str).to eq 'hello'
105
105
  end
106
106
  end
107
107
 
@@ -109,25 +109,25 @@ describe HTTPClient do
109
109
  @client.transparent_gzip_decompression = false
110
110
 
111
111
  content = @client.get_content(@srv.u 'compressed?enc=gzip')
112
- content.should_not eq 'hello'
113
- content.should eq GZIP_CONTENT
112
+ expect(content).not_to eq 'hello'
113
+ expect(content).to eq GZIP_CONTENT
114
114
  @client.transparent_gzip_decompression = true
115
115
 
116
116
  content = @client.get_content(@srv.u 'compressed?enc=gzip')
117
- content.should eq 'hello'
117
+ expect(content).to eq 'hello'
118
118
 
119
119
  content = @client.get_content(@srv.u 'compressed?enc=deflate')
120
- content.should eq 'hello'
120
+ expect(content).to eq 'hello'
121
121
  end
122
122
 
123
123
  it 'compressed large' do
124
124
  @client.transparent_gzip_decompression = true
125
125
 
126
126
  content = @client.get_content(@srv.u 'compressed_large?enc=gzip')
127
- content.should eq LARGE_STR
127
+ expect(content).to eq LARGE_STR
128
128
 
129
129
  content = @client.get_content(@srv.u 'compressed_large?enc=deflate')
130
- content.should eq LARGE_STR
130
+ expect(content).to eq LARGE_STR
131
131
  end
132
132
  end
133
133
  end
@@ -135,13 +135,13 @@ describe HTTPClient do
135
135
  describe 'get with block' do
136
136
  it 'works with filter_block: true' do
137
137
  @client.request(:get, @srv.u('hello')) do |str|
138
- str.should eq 'hello'
138
+ expect(str).to eq 'hello'
139
139
  end
140
140
  end
141
141
  it 'works with filter_block: false' do
142
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'
143
+ expect(req.class.name).to eq 'HTTP::Message'
144
+ expect(str).to eq 'hello'
145
145
  end
146
146
  end
147
147
  end
@@ -152,8 +152,8 @@ describe HTTPClient do
152
152
  @client.debug_dev = str
153
153
  @client.get(@srv.u)
154
154
  lines = str.split(/(?:\r?\n)+/)
155
- lines[0].should eq '= Request'
156
- lines[4].should eq "User-Agent: HTTPClient #{HTTPClient::VERSION}"
155
+ expect(lines[0]).to eq '= Request'
156
+ expect(lines[4]).to eq "User-Agent: HTTPClient #{HTTPClient::VERSION}"
157
157
  end
158
158
 
159
159
  it 'custom' do
@@ -162,8 +162,8 @@ describe HTTPClient do
162
162
  client.debug_dev = str
163
163
  client.get(@srv.u)
164
164
  lines = str.split(/(?:\r?\n)+/)
165
- lines[0].should eq '= Request'
166
- lines[4].should eq 'User-Agent: agent_name_foo'
165
+ expect(lines[0]).to eq '= Request'
166
+ expect(lines[4]).to eq 'User-Agent: agent_name_foo'
167
167
  end
168
168
  end
169
169
 
@@ -173,62 +173,62 @@ describe HTTPClient do
173
173
  @client.debug_dev = str = ''
174
174
  @client.test_loopback_http_response << "hello\nworld\n"
175
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"
176
+ expect(res.http_version).to eq '0.9'
177
+ expect(res.status).to be_nil
178
+ expect(res.reason).to be_nil
179
+ expect(res.content).to eq "hello\nworld\n"
180
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$/
181
+ expect(lines[0]).to eq "= Request"
182
+ expect(lines[2]).to eq "! CONNECTION ESTABLISHED"
183
+ expect(lines[3]).to eq "GET /hello HTTP/0.9"
184
+ expect(lines[7]).to eq "Connection: close"
185
+ expect(lines[8]).to eq "= Response"
186
+ expect(lines[9]).to match /^hello$/
187
+ expect(lines[10]).to match /^world$/
188
188
  end
189
189
 
190
190
  it '1.0' do
191
- @client.protocol_version.should be_nil
191
+ expect(@client.protocol_version).to be_nil
192
192
  @client.protocol_version = 'HTTP/1.0'
193
- @client.protocol_version.should eq 'HTTP/1.0'
193
+ expect(@client.protocol_version).to eq 'HTTP/1.0'
194
194
  str = ""
195
195
  @client.debug_dev = str
196
196
  @client.get(@srv.u 'hello')
197
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"
198
+ expect(lines[0]).to eq "= Request"
199
+ expect(lines[2]).to eq "! CONNECTION ESTABLISHED"
200
+ expect(lines[3]).to eq "GET /hello HTTP/1.0"
201
+ expect(lines[7]).to eq "Connection: close"
202
+ expect(lines[8]).to eq "= Response"
203
203
  end
204
204
 
205
205
  it '1.1' do
206
- @client.protocol_version.should be_nil
206
+ expect(@client.protocol_version).to be_nil
207
207
  str = ""
208
208
  @client.debug_dev = str
209
209
  @client.get(@srv.u)
210
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}"
211
+ expect(lines[0]).to eq "= Request"
212
+ expect(lines[2]).to eq "! CONNECTION ESTABLISHED"
213
+ expect(lines[3]).to eq "GET / HTTP/1.1"
214
+ expect(lines[7]).to eq "Host: localhost:#{@srv.port}"
215
215
  @client.protocol_version = 'HTTP/1.1'
216
- @client.protocol_version.should eq 'HTTP/1.1'
216
+ expect(@client.protocol_version).to eq 'HTTP/1.1'
217
217
  str = ""
218
218
  @client.debug_dev = str
219
219
  @client.get(@srv.u)
220
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"
221
+ expect(lines[0]).to eq "= Request"
222
+ expect(lines[2]).to eq "! CONNECTION ESTABLISHED"
223
+ expect(lines[3]).to eq "GET / HTTP/1.1"
224
224
  @client.protocol_version = 'HTTP/1.0'
225
225
  str = ""
226
226
  @client.debug_dev = str
227
227
  @client.get(@srv.u)
228
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"
229
+ expect(lines[0]).to eq "= Request"
230
+ expect(lines[2]).to eq "! CONNECTION ESTABLISHED"
231
+ expect(lines[3]).to eq "GET / HTTP/1.0"
232
232
  end
233
233
  end
234
234
 
@@ -238,7 +238,7 @@ describe HTTPClient do
238
238
  @client.debug_dev = str
239
239
  @client.get(@srv.u)
240
240
  lines = str.split(/(?:\r?\n)+/)
241
- lines[5].should eq "Accept: */*"
241
+ expect(lines[5]).to eq "Accept: */*"
242
242
  end
243
243
 
244
244
  it 'sets properly' do
@@ -246,9 +246,9 @@ describe HTTPClient do
246
246
  @client.debug_dev = str
247
247
  @client.get(@srv.u, :header => {:Accept => 'text/html'})
248
248
  lines = str.split(/(?:\r?\n)+/)
249
- lines[4].should eq "Accept: text/html"
249
+ expect(lines[4]).to eq "Accept: text/html"
250
250
  lines.each do |line|
251
- line.should_not eq "Accept: */*"
251
+ expect(line).not_to eq "Accept: */*"
252
252
  end
253
253
  end
254
254
  end
@@ -256,9 +256,9 @@ describe HTTPClient do
256
256
  describe 'POST' do
257
257
  describe '#post_content' do
258
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'
259
+ expect(@client.post_content(@srv.u('hello'))).to eq 'hello'
260
+ expect(@client.post_content(@srv.u("redirect1"))).to eq 'hello'
261
+ expect(@client.post_content(@srv.u("redirect2"))).to eq 'hello'
262
262
  end
263
263
  end
264
264
 
@@ -269,8 +269,8 @@ describe HTTPClient do
269
269
  called = true
270
270
  newuri
271
271
  }
272
- @client.post_content(@srv.u("relative_redirect")).should eq 'hello'
273
- called.should be_true
272
+ expect(@client.post_content(@srv.u("relative_redirect"))).to eq 'hello'
273
+ expect(called).to be_truthy
274
274
  end
275
275
 
276
276
  it 'errors' do
@@ -287,40 +287,40 @@ describe HTTPClient do
287
287
  describe 'string io' do
288
288
  it do
289
289
  post_body = StringIO.new("1234567890")
290
- @client.post_content(@srv.u("servlet"), post_body).should eq 'post,1234567890'
290
+ expect(@client.post_content(@srv.u("servlet"), post_body)).to eq 'post,1234567890'
291
291
 
292
292
  # all browsers use GET for 302
293
293
  post_body = StringIO.new("1234567890")
294
- @client.post_content(@srv.u("servlet_413"), post_body).should eq '1234567890'
294
+ expect(@client.post_content(@srv.u("servlet_413"), post_body)).to eq '1234567890'
295
295
 
296
- @client.get_content(@srv.u("servlet_redirect_413")).should eq ''
296
+ expect(@client.get_content(@srv.u("servlet_redirect_413"))).to eq ''
297
297
 
298
298
  post_body = StringIO.new("1234567890")
299
- @client.post_content(@srv.u("servlet_redirect_413"), post_body).should eq ''
299
+ expect(@client.post_content(@srv.u("servlet_redirect_413"), post_body)).to eq ''
300
300
 
301
301
  post_body = StringIO.new("1234567890")
302
- @client.post_content(@srv.u("servlet_temporary_redirect"), post_body).should eq 'post,1234567890'
302
+ expect(@client.post_content(@srv.u("servlet_temporary_redirect"), post_body)).to eq 'post,1234567890'
303
303
 
304
304
  post_body = StringIO.new("1234567890")
305
- @client.post_content(@srv.u("servlet_see_other"), post_body).should eq 'get'
305
+ expect(@client.post_content(@srv.u("servlet_see_other"), post_body)).to eq 'get'
306
306
  end
307
307
 
308
308
  it 'doesnt rewind' do
309
309
  post_body = StringIO.new("1234567890")
310
310
  post_body.read(5)
311
- @client.post_content(@srv.u("servlet_temporary_redirect"), post_body).should eq 'post,67890'
311
+ expect(@client.post_content(@srv.u("servlet_temporary_redirect"), post_body)).to eq 'post,67890'
312
312
  end
313
313
  end
314
314
  end
315
315
 
316
316
  describe 'util' do
317
317
  it '#urify' do
318
- urify(nil).should be_nil
318
+ expect(urify(nil)).to be_nil
319
319
  uri = 'http://foo'
320
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)
321
+ expect(urify(uri)).to eq urify(uri)
322
+ expect(urify(uri).to_s).to eq uri
323
+ expect(urify(urify(uri))).to eq urify(uri)
324
324
  end
325
325
  end
326
326
  end