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