typhoeus 0.6.9 → 0.7.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +9 -0
- data/README.md +60 -13
- data/lib/rack/typhoeus/middleware/params_decoder/helper.rb +1 -1
- data/lib/typhoeus/easy_factory.rb +26 -2
- data/lib/typhoeus/request.rb +2 -1
- data/lib/typhoeus/version.rb +1 -1
- data/spec/rack/typhoeus/middleware/params_decoder/helper_spec.rb +24 -0
- data/spec/typhoeus/easy_factory_spec.rb +41 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NzFhNDA4NzIxZjBjODEyOGU0NGM3MGU4Y2E3NzRjMmRlNDg2YTY0Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MWQwYWI4Yjk0ZDM0MWY0ZGE0Y2JmMTQ1NjJhNzRiY2M3MmJhNDM2OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MDZlYmY3MmVlN2U3YTFkOGYxODU4MGYyMzE1NTZjMzViNWY2NTc2YWEzMTQy
|
10
|
+
NDhlYzE3N2I4MDM5NTYzY2JkMWNmYmI4MmNhNjg3ZjZmMmVlNGZmYWJkNGU2
|
11
|
+
NzExODBlMmUyMzgyODZjMjg1N2I1ZTU4ODQwZGEwNzQwNGU2MGE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjVmOTFlMzExYTI4YzlhOWViYTMzZDE1M2FlY2U0Y2JlMWE5OWQ5Nzk4ZmUy
|
14
|
+
ZTI1YTE3NzAyNTM5YWFlNzk3NWQ5MDQ2ZTlhNDdmMGJkZjFhYmQyZDc4OTlm
|
15
|
+
YzQ4OGYzODM5NTNlYjFjZGFlZjA0YmEzOGFkMGUwOTViMzY3NDI=
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.7.0.pre1
|
4
|
+
|
5
|
+
[Full Changelog](http://github.com/typhoeus/typhoeus/compare/v0.6.9...v0.7.0.pre1)
|
6
|
+
|
7
|
+
Enhancements:
|
8
|
+
|
9
|
+
* Improving timeout behavior and documentation. `no_signal` is now set per default!
|
10
|
+
([Jonas Wagner](https://github.com/jwagner), [\#398](https://github.com/typhoeus/typhoeus/pull/398)
|
11
|
+
|
3
12
|
## 0.6.8
|
4
13
|
|
5
14
|
[Full Changelog](http://github.com/typhoeus/typhoeus/compare/v0.6.7...v0.6.8)
|
data/README.md
CHANGED
@@ -74,7 +74,7 @@ The response object will be set after the request is run.
|
|
74
74
|
response = request.response
|
75
75
|
response.code
|
76
76
|
response.total_time
|
77
|
-
response.
|
77
|
+
response.headers
|
78
78
|
response.body
|
79
79
|
```
|
80
80
|
|
@@ -165,25 +165,54 @@ request.run
|
|
165
165
|
|
166
166
|
### Making Parallel Requests
|
167
167
|
|
168
|
-
Generally, you should be running requests through hydra. Here is how that looks
|
168
|
+
Generally, you should be running requests through hydra. Here is how that looks:
|
169
169
|
|
170
170
|
```ruby
|
171
171
|
hydra = Typhoeus::Hydra.hydra
|
172
172
|
|
173
|
-
first_request = Typhoeus::Request.new("
|
173
|
+
first_request = Typhoeus::Request.new("http://example.com/posts/1")
|
174
174
|
first_request.on_complete do |response|
|
175
|
-
|
175
|
+
third_url = response.body
|
176
|
+
third_request = Typhoeus::Request.new(third_url)
|
176
177
|
hydra.queue third_request
|
177
178
|
end
|
178
|
-
second_request = Typhoeus::Request.new("
|
179
|
+
second_request = Typhoeus::Request.new("http://example.com/posts/2")
|
179
180
|
|
180
181
|
hydra.queue first_request
|
181
182
|
hydra.queue second_request
|
182
|
-
# this is a blocking call that returns once all requests are complete
|
183
|
+
hydra.run # this is a blocking call that returns once all requests are complete
|
184
|
+
```
|
185
|
+
|
186
|
+
The execution of that code goes something like this. The first and second requests are built and queued. When hydra is run the first and second requests run in parallel. When the first request completes, the third request is then built and queued, in this example based on the result of the first request. The moment it is queued Hydra starts executing it. Meanwhile the second request would continue to run (or it could have completed before the first). Once the third request is done, `hydra.run` returns.
|
187
|
+
|
188
|
+
How to get an array of response bodies back after executing a queue:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
hydra = Typhoeus::Hydra.new
|
192
|
+
requests = 10.times.map {
|
193
|
+
request = Typhoeus::Request.new("www.example.com", followlocation: true)
|
194
|
+
hydra.queue(request)
|
195
|
+
request
|
196
|
+
}
|
183
197
|
hydra.run
|
198
|
+
|
199
|
+
responses = requests.map { |request|
|
200
|
+
request.response.body
|
201
|
+
}
|
184
202
|
```
|
203
|
+
`hydra.run` is a blocking request. You can also use the `on_complete` callback to handle each request as it completes:
|
185
204
|
|
186
|
-
|
205
|
+
```ruby
|
206
|
+
hydra = Typhoeus::Hydra.new
|
207
|
+
10.times do
|
208
|
+
request = Typhoeus::Request.new("www.example.com", followlocation: true)
|
209
|
+
request.on_complete do |response|
|
210
|
+
#do_something_with response
|
211
|
+
end
|
212
|
+
hydra.queue(request)
|
213
|
+
end
|
214
|
+
hydra.run
|
215
|
+
```
|
187
216
|
|
188
217
|
### Specifying Max Concurrency
|
189
218
|
|
@@ -318,17 +347,27 @@ end
|
|
318
347
|
|
319
348
|
### Timeouts
|
320
349
|
|
321
|
-
No exceptions are raised on HTTP timeouts. You can check whether a request timed out with the following
|
350
|
+
No exceptions are raised on HTTP timeouts. You can check whether a request timed out with the following method:
|
322
351
|
|
323
352
|
```ruby
|
324
|
-
Typhoeus.get("www.example.com").timed_out?
|
353
|
+
Typhoeus.get("www.example.com", timeout: 1).timed_out?
|
325
354
|
```
|
326
355
|
|
356
|
+
Timed out responses also have their success? method return false.
|
357
|
+
|
327
358
|
There are two different timeouts available: [`timeout`](http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTTIMEOUT)
|
328
|
-
and [`connecttimeout`](http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTCONNECTTIMEOUT).
|
329
|
-
|
330
|
-
|
331
|
-
|
359
|
+
and [`connecttimeout`](http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTCONNECTTIMEOUT).
|
360
|
+
`timeout` is the time limit for the entire request in seconds.
|
361
|
+
`connecttimeout` is the time limit for just the connection phase, again in seconds.
|
362
|
+
|
363
|
+
There are two additional more fine grained opptions `timeout_ms` and
|
364
|
+
`connecttimeout_ms`. These options offer millisecond precision but are not always available (for instance on linux if `nosignal` is not set to true).
|
365
|
+
|
366
|
+
When you pass a floating point `timeout` (or `connecttimeout`) Typhoeus will set `timeout_ms` for you if it has not been defined. The actual timeout values passed to curl will always be rounded up.
|
367
|
+
|
368
|
+
DNS timeouts of less than one second are not supported unless curl is compiled with an asynchronous resolver.
|
369
|
+
|
370
|
+
The default `timeout` is 0 (zero) which means curl never times out during transfer. The default `connecttimeout` is 300 seconds. A `connecttimeout` of 0 will also result in the default `connecttimeout` of 300 seconds.
|
332
371
|
|
333
372
|
### Following Redirections
|
334
373
|
|
@@ -350,6 +389,14 @@ Typhoeus::Request.get("www.example.com", userpwd: "user:password")
|
|
350
389
|
Typhoeus.get("www.example.com", accept_encoding: "gzip")
|
351
390
|
```
|
352
391
|
|
392
|
+
The above has a different behavior than setting the header directly in the header hash, eg:
|
393
|
+
```ruby
|
394
|
+
Typhoeus.get("www.example.com", headers: {"Accept-Encoding" => "gzip"})
|
395
|
+
```
|
396
|
+
|
397
|
+
Setting the header hash directly will not include the `--compressed` flag in the libcurl command and therefore libcurl will not decompress the response. If you want the `--compressed` flag to be added automatically, set `:accept_encoding` Typhoeus option.
|
398
|
+
|
399
|
+
|
353
400
|
### Cookies
|
354
401
|
|
355
402
|
```ruby
|
@@ -64,19 +64,43 @@ module Typhoeus
|
|
64
64
|
private
|
65
65
|
|
66
66
|
def sanitize(options)
|
67
|
-
|
67
|
+
# set nosignal to true by default
|
68
|
+
# this improves thread safety and timeout behavior
|
69
|
+
sanitized = {:nosignal => true}
|
68
70
|
request.options.each do |k,v|
|
69
|
-
|
71
|
+
s = k.to_sym
|
72
|
+
next if [:method, :cache_ttl].include?(s)
|
70
73
|
if new_option = renamed_options[k.to_sym]
|
71
74
|
warn("Deprecated option #{k}. Please use #{new_option} instead.")
|
72
75
|
sanitized[new_option] = v
|
76
|
+
# sanitize timeouts
|
77
|
+
elsif [:timeout_ms, :connecttimeout_ms].include?(s)
|
78
|
+
if !v.integer?
|
79
|
+
warn("Value '#{v}' for option '#{k}' must be integer.")
|
80
|
+
end
|
81
|
+
sanitized[k] = v.ceil
|
73
82
|
else
|
74
83
|
sanitized[k] = v
|
75
84
|
end
|
76
85
|
end
|
86
|
+
|
87
|
+
sanitize_timeout!(sanitized, :timeout)
|
88
|
+
sanitize_timeout!(sanitized, :connecttimeout)
|
89
|
+
|
77
90
|
sanitized
|
78
91
|
end
|
79
92
|
|
93
|
+
def sanitize_timeout!(options, timeout)
|
94
|
+
timeout_ms = (timeout.to_s + '_ms').to_sym
|
95
|
+
if options[timeout] && options[timeout].round != options[timeout]
|
96
|
+
if !options[timeout_ms]
|
97
|
+
options[timeout_ms] = (options[timeout]*1000).ceil
|
98
|
+
end
|
99
|
+
options[timeout] = options[timeout].ceil
|
100
|
+
end
|
101
|
+
options
|
102
|
+
end
|
103
|
+
|
80
104
|
# Sets on_complete callback on easy in order to be able to
|
81
105
|
# track progress.
|
82
106
|
#
|
data/lib/typhoeus/request.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'zlib'
|
2
|
+
require 'digest/sha1'
|
2
3
|
require 'typhoeus/request/actions'
|
3
4
|
require 'typhoeus/request/before'
|
4
5
|
require 'typhoeus/request/block_connection'
|
@@ -162,7 +163,7 @@ module Typhoeus
|
|
162
163
|
#
|
163
164
|
# @return [ String ] The cache key.
|
164
165
|
def cache_key
|
165
|
-
"#{self.class.name}#{base_url}#{hashable_string_for(options)}"
|
166
|
+
Digest::SHA1.hexdigest "#{self.class.name}#{base_url}#{hashable_string_for(options)}"
|
166
167
|
end
|
167
168
|
|
168
169
|
# Mimics libcurls POST body generation. This is not accurate, but good
|
data/lib/typhoeus/version.rb
CHANGED
@@ -39,6 +39,30 @@ describe "Rack::Typhoeus::Middleware::ParamsDecoder::Helper" do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
context "when longer and more complex" do
|
43
|
+
let(:params) do
|
44
|
+
{
|
45
|
+
:ids => {
|
46
|
+
"0" => "407304",
|
47
|
+
"1" => "407305",
|
48
|
+
"2" => "407306",
|
49
|
+
"3" => "407307",
|
50
|
+
"4" => "407308",
|
51
|
+
"5" => "407309",
|
52
|
+
"6" => "407310",
|
53
|
+
"7" => "407311",
|
54
|
+
"8" => "407312",
|
55
|
+
"9" => "407313",
|
56
|
+
"10" => "327012"
|
57
|
+
}
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
it "decodes ensuring arrays maintain their original order" do
|
62
|
+
expect(decoded[:ids]).to eq(["407304", "407305", "407306", "407307", "407308", "407309", "407310", "407311", "407312", "407313", "327012"])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
42
66
|
context "when nested" do
|
43
67
|
let(:params) do
|
44
68
|
{ :array => { '0' => 0, '1' => { '0' => 'sub0', '1' => 'sub1' } } }
|
@@ -15,6 +15,47 @@ describe Typhoeus::EasyFactory do
|
|
15
15
|
expect(easy_factory.get).to be_a(Ethon::Easy)
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
context "timeouts" do
|
20
|
+
it "sets nosignal to true by default" do
|
21
|
+
expect(easy_factory.easy).to receive(:http_request).with(anything(), anything(), hash_including(:nosignal => true))
|
22
|
+
easy_factory.get
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when timeout is not a whole number and timeout_ms is not set" do
|
26
|
+
let(:options) { {:timeout => 0.1} }
|
27
|
+
it "ceils timeout and sets timeout_ms" do
|
28
|
+
expect(easy_factory.easy).to receive(:http_request).with(anything(), anything(), hash_including(:timeout_ms => 100, :timeout => 1))
|
29
|
+
easy_factory.get
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when timeout is not a whole number and timeout_ms is set" do
|
34
|
+
let(:options) { {:timeout => 0.1, :timeout_ms => 123} }
|
35
|
+
it "ceils timeout and does not change timeout_ms" do
|
36
|
+
expect(easy_factory.easy).to receive(:http_request).with(anything(), anything(), hash_including(:timeout_ms => 123, :timeout => 1))
|
37
|
+
easy_factory.get
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when connecttimeout is not a whole number and connecttimeout_ms is not set" do
|
42
|
+
let(:options) { {:connecttimeout => 0.1} }
|
43
|
+
it "ceils connecttimeout and sets connecttimeout_ms" do
|
44
|
+
expect(easy_factory.easy).to receive(:http_request).with(anything(), anything(), hash_including(:connecttimeout_ms => 100, :connecttimeout => 1))
|
45
|
+
easy_factory.get
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when connecttimeout is not a whole number and connecttimeout_ms is set" do
|
50
|
+
let(:options) { {:connecttimeout => 0.1, :connecttimeout_ms => 123} }
|
51
|
+
it "ceils connecttimeout and does not change connecttimeout_ms" do
|
52
|
+
expect(easy_factory.easy).to receive(:http_request).with(anything(), anything(), hash_including(:connecttimeout_ms => 123, :connecttimeout => 1))
|
53
|
+
easy_factory.get
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
end
|
18
59
|
|
19
60
|
context "when invalid option" do
|
20
61
|
let(:options) { {:invalid => 1} }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typhoeus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Balatero
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-11-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: ethon
|