typhoeus 0.6.3 → 0.6.4
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 +15 -0
- data/.gitignore +8 -0
- data/.rspec +4 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +7 -1
- data/CONTRIBUTING.md +16 -0
- data/Guardfile +9 -0
- data/README.md +303 -1
- data/UPGRADE.md +55 -0
- data/lib/rack/typhoeus/middleware/params_decoder.rb +1 -1
- data/lib/rack/typhoeus/middleware/params_decoder/helper.rb +6 -2
- data/lib/typhoeus/adapters/faraday.rb +4 -1
- data/lib/typhoeus/easy_factory.rb +36 -15
- data/lib/typhoeus/hydra/before.rb +2 -1
- data/lib/typhoeus/hydra/cacheable.rb +1 -0
- data/lib/typhoeus/hydra/memoizable.rb +1 -0
- data/lib/typhoeus/hydra/queueable.rb +15 -3
- data/lib/typhoeus/request.rb +6 -2
- data/lib/typhoeus/request/marshal.rb +3 -2
- data/lib/typhoeus/response/informations.rb +4 -0
- data/lib/typhoeus/version.rb +1 -1
- data/perf/profile.rb +14 -0
- data/perf/vs_nethttp.rb +64 -0
- data/spec/rack/typhoeus/middleware/params_decoder/helper_spec.rb +132 -0
- data/spec/rack/typhoeus/middleware/params_decoder_spec.rb +31 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/localhost_server.rb +94 -0
- data/spec/support/server.rb +108 -0
- data/spec/typhoeus/adapters/faraday_spec.rb +245 -0
- data/spec/typhoeus/config_spec.rb +15 -0
- data/spec/typhoeus/easy_factory_spec.rb +96 -0
- data/spec/typhoeus/errors/no_stub_spec.rb +13 -0
- data/spec/typhoeus/expectation_spec.rb +273 -0
- data/spec/typhoeus/hydra/addable_spec.rb +22 -0
- data/spec/typhoeus/hydra/before_spec.rb +97 -0
- data/spec/typhoeus/hydra/block_connection_spec.rb +18 -0
- data/spec/typhoeus/hydra/cacheable_spec.rb +68 -0
- data/spec/typhoeus/hydra/memoizable_spec.rb +53 -0
- data/spec/typhoeus/hydra/queueable_spec.rb +34 -0
- data/spec/typhoeus/hydra/runnable_spec.rb +155 -0
- data/spec/typhoeus/hydra/stubbable_spec.rb +28 -0
- data/spec/typhoeus/hydra_spec.rb +26 -0
- data/spec/typhoeus/pool_spec.rb +79 -0
- data/spec/typhoeus/request/actions_spec.rb +19 -0
- data/spec/typhoeus/request/before_spec.rb +92 -0
- data/spec/typhoeus/request/block_connection_spec.rb +75 -0
- data/spec/typhoeus/request/cacheable_spec.rb +80 -0
- data/spec/typhoeus/request/callbacks_spec.rb +91 -0
- data/spec/typhoeus/request/marshal_spec.rb +62 -0
- data/spec/typhoeus/request/memoizable_spec.rb +34 -0
- data/spec/typhoeus/request/operations_spec.rb +70 -0
- data/spec/typhoeus/request/responseable_spec.rb +13 -0
- data/spec/typhoeus/request/stubbable_spec.rb +27 -0
- data/spec/typhoeus/request_spec.rb +131 -0
- data/spec/typhoeus/response/header_spec.rb +97 -0
- data/spec/typhoeus/response/informations_spec.rb +218 -0
- data/spec/typhoeus/response/status_spec.rb +218 -0
- data/spec/typhoeus/response_spec.rb +81 -0
- data/spec/typhoeus_spec.rb +105 -0
- data/typhoeus.gemspec +25 -0
- metadata +101 -27
@@ -36,7 +36,7 @@ module Rack
|
|
36
36
|
private
|
37
37
|
|
38
38
|
# Persist params change in environment. Extracted from:
|
39
|
-
# https://github.com/rack/rack/blob/master/lib/rack/request.rb#
|
39
|
+
# https://github.com/rack/rack/blob/master/lib/rack/request.rb#L243
|
40
40
|
def update_params(req, k, v)
|
41
41
|
found = false
|
42
42
|
if req.GET.has_key?(k)
|
@@ -48,8 +48,12 @@ module Rack
|
|
48
48
|
# @return [Boolean] True if its a encoded Array, else false.
|
49
49
|
def encoded?(hash)
|
50
50
|
return false if hash.empty?
|
51
|
-
|
52
|
-
|
51
|
+
if hash.keys.size > 1
|
52
|
+
keys = hash.keys.map{|i| i.to_i if i.respond_to?(:to_i)}.sort
|
53
|
+
keys == hash.keys.size.times.to_a
|
54
|
+
else
|
55
|
+
hash.keys.first =~ /0/
|
56
|
+
end
|
53
57
|
end
|
54
58
|
|
55
59
|
# If the Hash is an array encoded by typhoeus an array is returned
|
@@ -110,8 +110,11 @@ module Faraday # :nodoc:
|
|
110
110
|
def configure_ssl(req, env)
|
111
111
|
ssl = env[:ssl]
|
112
112
|
|
113
|
-
|
113
|
+
verify_p = (ssl && ssl.fetch(:verify, true))
|
114
|
+
|
115
|
+
ssl_verifyhost = verify_p ? 2 : 0
|
114
116
|
req.options[:ssl_verifyhost] = ssl_verifyhost
|
117
|
+
req.options[:ssl_verifypeer] = verify_p
|
115
118
|
req.options[:sslversion] = ssl[:version] if ssl[:version]
|
116
119
|
req.options[:sslcert] = ssl[:client_cert] if ssl[:client_cert]
|
117
120
|
req.options[:sslkey] = ssl[:client_key] if ssl[:client_key]
|
@@ -51,7 +51,7 @@ module Typhoeus
|
|
51
51
|
easy.http_request(
|
52
52
|
request.base_url,
|
53
53
|
request.options.fetch(:method, :get),
|
54
|
-
request.options
|
54
|
+
sanitize(request.options)
|
55
55
|
)
|
56
56
|
rescue Ethon::Errors::InvalidOption => e
|
57
57
|
help = provide_help(e.message.match(/:\s(\w+)/)[1])
|
@@ -63,6 +63,20 @@ module Typhoeus
|
|
63
63
|
|
64
64
|
private
|
65
65
|
|
66
|
+
def sanitize(options)
|
67
|
+
sanitized = {}
|
68
|
+
request.options.each do |k,v|
|
69
|
+
next if [:method, :cache_ttl].include?(k.to_sym)
|
70
|
+
if new_option = renamed_options[k.to_sym]
|
71
|
+
warn("Deprecated option #{k}. Please use #{new_option} instead.")
|
72
|
+
sanitized[new_option] = v
|
73
|
+
else
|
74
|
+
sanitized[k] = v
|
75
|
+
end
|
76
|
+
end
|
77
|
+
sanitized
|
78
|
+
end
|
79
|
+
|
66
80
|
# Sets on_complete callback on easy in order to be able to
|
67
81
|
# track progress.
|
68
82
|
#
|
@@ -72,28 +86,22 @@ module Typhoeus
|
|
72
86
|
# @return [ Ethon::Easy ] The easy.
|
73
87
|
def set_callback
|
74
88
|
easy.on_complete do |easy|
|
75
|
-
request.finish(Response.new(easy.
|
89
|
+
request.finish(Response.new(easy.mirror.options))
|
76
90
|
Typhoeus::Pool.release(easy)
|
77
91
|
if hydra && !hydra.queued_requests.empty?
|
78
|
-
hydra.
|
92
|
+
hydra.dequeue
|
79
93
|
end
|
80
94
|
end
|
81
95
|
end
|
82
96
|
|
83
|
-
def
|
84
|
-
|
97
|
+
def renamed_options
|
98
|
+
{
|
85
99
|
:auth_method => :httpauth,
|
86
100
|
:connect_timeout => :connecttimeout,
|
87
|
-
:disable_ssl_host_verification => :ssl_verifyhost,
|
88
|
-
:disable_ssl_peer_verification => :ssl_verifypeer,
|
89
101
|
:encoding => :accept_encoding,
|
90
102
|
:follow_location => :followlocation,
|
91
103
|
:max_redirects => :maxredirs,
|
92
|
-
:password => :userpwd,
|
93
|
-
:proxy_auth_method => :proxyauth,
|
94
|
-
:proxy_password => :proxyuserpwd,
|
95
104
|
:proxy_type => :proxytype,
|
96
|
-
:proxy_username => :proxyuserpwd,
|
97
105
|
:ssl_cacert => :cainfo,
|
98
106
|
:ssl_capath => :capath,
|
99
107
|
:ssl_cert => :sslcert,
|
@@ -102,12 +110,25 @@ module Typhoeus
|
|
102
110
|
:ssl_key_password => :keypasswd,
|
103
111
|
:ssl_key_type => :sslkeytype,
|
104
112
|
:ssl_version => :sslversion,
|
105
|
-
:username => :userpwd
|
106
113
|
}
|
107
|
-
|
108
|
-
|
114
|
+
end
|
115
|
+
|
116
|
+
def changed_options
|
117
|
+
{
|
118
|
+
:disable_ssl_host_verification => :ssl_verifyhost,
|
119
|
+
:disable_ssl_peer_verification => :ssl_verifypeer,
|
120
|
+
:proxy_auth_method => :proxyauth,
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
def removed_options
|
125
|
+
[:cache_key_basis, :cache_timeout, :user_agent]
|
126
|
+
end
|
127
|
+
|
128
|
+
def provide_help(option)
|
129
|
+
if new_option = changed_options[option.to_sym]
|
109
130
|
"\nPlease try #{new_option} instead of #{option}." if new_option
|
110
|
-
elsif
|
131
|
+
elsif removed_options.include?(option.to_sym)
|
111
132
|
"\nThe option #{option} was removed."
|
112
133
|
end
|
113
134
|
end
|
@@ -11,7 +11,7 @@ module Typhoeus
|
|
11
11
|
|
12
12
|
# Overrride add in order to execute callbacks in
|
13
13
|
# Typhoeus.before. Will break and return when a
|
14
|
-
# callback returns nil or
|
14
|
+
# callback returns nil, false or a response. Calls super
|
15
15
|
# otherwise.
|
16
16
|
#
|
17
17
|
# @example Add the request.
|
@@ -20,6 +20,7 @@ module Typhoeus
|
|
20
20
|
Typhoeus.before.each do |callback|
|
21
21
|
value = callback.call(request)
|
22
22
|
if value.nil? || value == false || value.is_a?(Response)
|
23
|
+
dequeue
|
23
24
|
return value
|
24
25
|
end
|
25
26
|
end
|
@@ -10,7 +10,7 @@ module Typhoeus
|
|
10
10
|
# Return the queued requests.
|
11
11
|
#
|
12
12
|
# @example Return queued requests.
|
13
|
-
#
|
13
|
+
# hydra.queued_requests
|
14
14
|
#
|
15
15
|
# @return [ Array<Typhoeus::Request> ] The queued requests.
|
16
16
|
def queued_requests
|
@@ -23,7 +23,7 @@ module Typhoeus
|
|
23
23
|
# anything about already running requests.
|
24
24
|
#
|
25
25
|
# @example Abort hydra.
|
26
|
-
#
|
26
|
+
# hydra.abort
|
27
27
|
def abort
|
28
28
|
queued_requests.clear
|
29
29
|
end
|
@@ -34,11 +34,23 @@ module Typhoeus
|
|
34
34
|
# request.
|
35
35
|
#
|
36
36
|
# @example Queue request.
|
37
|
-
#
|
37
|
+
# hydra.queue(request)
|
38
38
|
def queue(request)
|
39
39
|
request.hydra = self
|
40
40
|
queued_requests << request
|
41
41
|
end
|
42
|
+
|
43
|
+
# Removes a request from queued_requests and
|
44
|
+
# adds it to the hydra in order to be
|
45
|
+
# performed next.
|
46
|
+
#
|
47
|
+
# @example Dequeue request.
|
48
|
+
# hydra.dequeue
|
49
|
+
#
|
50
|
+
# @since 0.6.4
|
51
|
+
def dequeue
|
52
|
+
add(queued_requests.shift) unless queued_requests.empty?
|
53
|
+
end
|
42
54
|
end
|
43
55
|
end
|
44
56
|
end
|
data/lib/typhoeus/request.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'zlib'
|
1
2
|
require 'typhoeus/request/actions'
|
2
3
|
require 'typhoeus/request/before'
|
3
4
|
require 'typhoeus/request/block_connection'
|
@@ -123,7 +124,10 @@ module Typhoeus
|
|
123
124
|
#
|
124
125
|
# @since 0.5.5
|
125
126
|
def url
|
126
|
-
EasyFactory.new(self).get
|
127
|
+
easy = EasyFactory.new(self).get
|
128
|
+
url = easy.url
|
129
|
+
Typhoeus::Pool.release(easy)
|
130
|
+
url
|
127
131
|
end
|
128
132
|
|
129
133
|
# Returns whether other is equal to self.
|
@@ -148,7 +152,7 @@ module Typhoeus
|
|
148
152
|
#
|
149
153
|
# @api private
|
150
154
|
def hash
|
151
|
-
|
155
|
+
Zlib.crc32 "#{self.class.name}#{base_url}#{options}"
|
152
156
|
end
|
153
157
|
|
154
158
|
private
|
@@ -5,9 +5,10 @@ module Typhoeus
|
|
5
5
|
module Marshal
|
6
6
|
|
7
7
|
# Return the important data needed to serialize this Request, except the
|
8
|
-
# `on_complete`
|
8
|
+
# `on_complete`, `on_success`, `on_failure`, and `hydra`, since they cannot be marshalled.
|
9
9
|
def marshal_dump
|
10
|
-
|
10
|
+
unmarshallable = %w(@on_complete @on_success @on_failure @hydra)
|
11
|
+
(instance_variables - unmarshallable - unmarshallable.map(&:to_sym)).map do |name|
|
11
12
|
[name, instance_variable_get(name)]
|
12
13
|
end
|
13
14
|
end
|
data/lib/typhoeus/version.rb
CHANGED
data/perf/profile.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'ruby-prof'
|
3
|
+
|
4
|
+
calls = 50
|
5
|
+
base_url = "http://127.0.0.1:3000/"
|
6
|
+
|
7
|
+
RubyProf.start
|
8
|
+
calls.times do |i|
|
9
|
+
Typhoeus::Request.get(base_url+i.to_s)
|
10
|
+
end
|
11
|
+
result = RubyProf.stop
|
12
|
+
|
13
|
+
printer = RubyProf::FlatPrinter.new(result)
|
14
|
+
printer.print(STDOUT)
|
data/perf/vs_nethttp.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'net/http'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
URL = "http://localhost:300"
|
7
|
+
hydra = Typhoeus::Hydra.new(max_concurrency: 3)
|
8
|
+
|
9
|
+
if defined? require_relative
|
10
|
+
require_relative '../spec/support/localhost_server.rb'
|
11
|
+
require_relative '../spec/support/server.rb'
|
12
|
+
else
|
13
|
+
require '../spec/support/localhost_server.rb'
|
14
|
+
require '../spec/support/server.rb'
|
15
|
+
end
|
16
|
+
LocalhostServer.new(TESTSERVER.new, 3000)
|
17
|
+
LocalhostServer.new(TESTSERVER.new, 3001)
|
18
|
+
LocalhostServer.new(TESTSERVER.new, 3002)
|
19
|
+
|
20
|
+
def url_for(i)
|
21
|
+
"#{URL}#{i%3}/"
|
22
|
+
end
|
23
|
+
|
24
|
+
Benchmark.bm do |bm|
|
25
|
+
|
26
|
+
[1000].each do |calls|
|
27
|
+
puts "[ #{calls} requests ]"
|
28
|
+
|
29
|
+
bm.report("net/http ") do
|
30
|
+
calls.times do |i|
|
31
|
+
uri = URI.parse(url_for(i))
|
32
|
+
Net::HTTP.get_response(uri)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
bm.report("open ") do
|
37
|
+
calls.times do |i|
|
38
|
+
open(url_for(i))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
bm.report("request ") do
|
43
|
+
calls.times do |i|
|
44
|
+
Typhoeus::Request.get(url_for(i))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
bm.report("hydra ") do
|
49
|
+
calls.times do |i|
|
50
|
+
hydra.queue(Typhoeus::Request.new(url_for(i)))
|
51
|
+
end
|
52
|
+
hydra.run
|
53
|
+
end
|
54
|
+
|
55
|
+
bm.report("hydra memoize ") do
|
56
|
+
Typhoeus::Config.memoize = true
|
57
|
+
calls.times do |i|
|
58
|
+
hydra.queue(Typhoeus::Request.new(url_for(i)))
|
59
|
+
end
|
60
|
+
hydra.run
|
61
|
+
Typhoeus::Config.memoize = false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "rack/typhoeus"
|
3
|
+
|
4
|
+
describe "Rack::Typhoeus::Middleware::ParamsDecoder::Helper" do
|
5
|
+
|
6
|
+
let(:klass) do
|
7
|
+
Class.new do
|
8
|
+
include Rack::Typhoeus::Middleware::ParamsDecoder::Helper
|
9
|
+
end.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#decode" do
|
13
|
+
let(:decoded) { klass.decode(params) }
|
14
|
+
let(:params) { { :array => {'0' => :a, '1' => :b } } }
|
15
|
+
|
16
|
+
it "decodes" do
|
17
|
+
expect(decoded[:array]).to match_array([:a, :b])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "doesn't modify" do
|
21
|
+
expect(decoded).to_not be(params)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#decode!" do
|
26
|
+
let(:decoded) { klass.decode!(params) }
|
27
|
+
|
28
|
+
context "when hash" do
|
29
|
+
context "when encoded" do
|
30
|
+
context "when simple" do
|
31
|
+
let(:params) { { :array => {'0' => :a, '1' => :b } } }
|
32
|
+
|
33
|
+
it "decodes" do
|
34
|
+
expect(decoded[:array]).to match_array([:a, :b])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "modifies" do
|
38
|
+
expect(decoded).to eq(params)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when nested" do
|
43
|
+
let(:params) do
|
44
|
+
{ :array => { '0' => 0, '1' => { '0' => 'sub0', '1' => 'sub1' } } }
|
45
|
+
end
|
46
|
+
|
47
|
+
it "decodes" do
|
48
|
+
expect(decoded[:array]).to include(0)
|
49
|
+
expect(decoded[:array].find{|e| e.is_a?(Array)}).to(
|
50
|
+
match_array(['sub0', 'sub1'])
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "modifies" do
|
55
|
+
expect(decoded).to eq(params)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when not encoded" do
|
61
|
+
let(:params) { {:a => :a} }
|
62
|
+
|
63
|
+
it "doesn't modify" do
|
64
|
+
expect(decoded).to be(params)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when no hash" do
|
70
|
+
let(:params) { "a" }
|
71
|
+
|
72
|
+
it "returns self" do
|
73
|
+
expect(decoded).to be(params)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#encoded?" do
|
79
|
+
let(:encoded) { klass.send(:encoded?, params) }
|
80
|
+
|
81
|
+
context "when there is only one key" do
|
82
|
+
context "and its 0" do
|
83
|
+
let(:params){ {'0' => 1} }
|
84
|
+
it 'returns true' do
|
85
|
+
expect(encoded).to be_true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
context "and its not 0" do
|
89
|
+
let(:params){ {'some-key' => 1}}
|
90
|
+
it 'returns false' do
|
91
|
+
expect(encoded).to be_false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when keys are ascending numbers starting with zero" do
|
97
|
+
let(:params) { Hash[12.times.map {|i| [i, (i+65).chr]}] }
|
98
|
+
|
99
|
+
it "returns true" do
|
100
|
+
expect(encoded).to be_true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when keys are not ascending numbers starting with zero" do
|
105
|
+
let(:params) { {:a => 1} }
|
106
|
+
|
107
|
+
it "returns false" do
|
108
|
+
expect(encoded).to be_false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#convert" do
|
114
|
+
let(:converted) { klass.send(:convert, params) }
|
115
|
+
|
116
|
+
context "when encoded" do
|
117
|
+
let(:params) { {'0' => :a, '1' => :b} }
|
118
|
+
|
119
|
+
it "returns values" do
|
120
|
+
expect(converted).to match_array([:a, :b])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when not encoded" do
|
125
|
+
let(:params) { {:a => :a} }
|
126
|
+
|
127
|
+
it "returns unmodified" do
|
128
|
+
expect(converted).to be(params)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|