tech-angels-typhoeus 0.1.36
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.
- data/.gitignore +2 -0
- data/README.textile +312 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/benchmarks/profile.rb +25 -0
- data/benchmarks/vs_nethttp.rb +35 -0
- data/examples/twitter.rb +21 -0
- data/ext/typhoeus/.gitignore +5 -0
- data/ext/typhoeus/Makefile +157 -0
- data/ext/typhoeus/extconf.rb +65 -0
- data/ext/typhoeus/native.c +11 -0
- data/ext/typhoeus/native.h +21 -0
- data/ext/typhoeus/typhoeus_easy.c +207 -0
- data/ext/typhoeus/typhoeus_easy.h +19 -0
- data/ext/typhoeus/typhoeus_multi.c +225 -0
- data/ext/typhoeus/typhoeus_multi.h +16 -0
- data/lib/typhoeus.rb +55 -0
- data/lib/typhoeus/.gitignore +1 -0
- data/lib/typhoeus/easy.rb +329 -0
- data/lib/typhoeus/filter.rb +28 -0
- data/lib/typhoeus/hydra.rb +235 -0
- data/lib/typhoeus/multi.rb +35 -0
- data/lib/typhoeus/remote.rb +306 -0
- data/lib/typhoeus/remote_method.rb +108 -0
- data/lib/typhoeus/remote_proxy_object.rb +48 -0
- data/lib/typhoeus/request.rb +159 -0
- data/lib/typhoeus/response.rb +49 -0
- data/lib/typhoeus/service.rb +20 -0
- data/profilers/valgrind.rb +24 -0
- data/spec/fixtures/result_set.xml +60 -0
- data/spec/servers/app.rb +73 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/typhoeus/easy_spec.rb +236 -0
- data/spec/typhoeus/filter_spec.rb +35 -0
- data/spec/typhoeus/hydra_spec.rb +311 -0
- data/spec/typhoeus/multi_spec.rb +74 -0
- data/spec/typhoeus/remote_method_spec.rb +141 -0
- data/spec/typhoeus/remote_proxy_object_spec.rb +65 -0
- data/spec/typhoeus/remote_spec.rb +695 -0
- data/spec/typhoeus/request_spec.rb +169 -0
- data/spec/typhoeus/response_spec.rb +63 -0
- data/typhoeus.gemspec +112 -0
- metadata +203 -0
data/spec/servers/app.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'sinatra'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
@@fail_count = 0
|
7
|
+
get '/fail/:number' do
|
8
|
+
if @@fail_count >= params[:number].to_i
|
9
|
+
"ok"
|
10
|
+
else
|
11
|
+
@@fail_count += 1
|
12
|
+
error 500, "oh noes!"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
get '/fail_forever' do
|
17
|
+
error 500, "oh noes!"
|
18
|
+
end
|
19
|
+
|
20
|
+
get '/redirect' do
|
21
|
+
redirect '/'
|
22
|
+
end
|
23
|
+
|
24
|
+
get '/bad_redirect' do
|
25
|
+
redirect '/bad_redirect'
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/auth_basic/:username/:password' do
|
29
|
+
@auth ||= Rack::Auth::Basic::Request.new(request.env)
|
30
|
+
# Check that we've got a basic auth, and that it's credentials match the ones
|
31
|
+
# provided in the request
|
32
|
+
if @auth.provided? && @auth.basic? && @auth.credentials == [ params[:username], params[:password] ]
|
33
|
+
# auth is valid - confirm it
|
34
|
+
true
|
35
|
+
else
|
36
|
+
# invalid auth - request the authentication
|
37
|
+
response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth")
|
38
|
+
throw(:halt, [401, "Not authorized\n"])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
get '/auth_ntlm' do
|
43
|
+
# we're just checking for the existence if NTLM auth header here. It's validation
|
44
|
+
# is too troublesome and really doesn't bother is much, it's up to libcurl to make
|
45
|
+
# it valid
|
46
|
+
is_ntlm_auth = /^NTLM/ =~ request.env['HTTP_AUTHORIZATION']
|
47
|
+
true if is_ntlm_auth
|
48
|
+
throw(:halt, [401, "Not authorized\n"]) if !is_ntlm_auth
|
49
|
+
end
|
50
|
+
|
51
|
+
get '/**' do
|
52
|
+
sleep params["delay"].to_i if params.has_key?("delay")
|
53
|
+
request.env.merge!(:body => request.body.read).to_json
|
54
|
+
end
|
55
|
+
|
56
|
+
head '/**' do
|
57
|
+
sleep params["delay"].to_i if params.has_key?("delay")
|
58
|
+
end
|
59
|
+
|
60
|
+
put '/**' do
|
61
|
+
puts request.inspect
|
62
|
+
request.env.merge!(:body => request.body.read).to_json
|
63
|
+
end
|
64
|
+
|
65
|
+
post '/**' do
|
66
|
+
puts request.inspect
|
67
|
+
request.env.merge!(:body => request.body.read).to_json
|
68
|
+
end
|
69
|
+
|
70
|
+
delete '/**' do
|
71
|
+
puts request.inspect
|
72
|
+
request.env.merge!(:body => request.body.read).to_json
|
73
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'json'
|
3
|
+
require "spec"
|
4
|
+
|
5
|
+
# gem install redgreen for colored test output
|
6
|
+
begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
|
7
|
+
|
8
|
+
path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
9
|
+
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
10
|
+
|
11
|
+
require "lib/typhoeus"
|
@@ -0,0 +1,236 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Typhoeus::Easy do
|
4
|
+
describe "#supports_zlib" do
|
5
|
+
before(:each) do
|
6
|
+
@easy = Typhoeus::Easy.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return true if the version string has zlib" do
|
10
|
+
@easy.stub!(:curl_version).and_return("libcurl/7.20.0 OpenSSL/0.9.8l zlib/1.2.3 libidn/1.16")
|
11
|
+
@easy.supports_zlib?.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return false if the version string doesn't have zlib" do
|
15
|
+
@easy.stub!(:curl_version).and_return("libcurl/7.20.0 OpenSSL/0.9.8l libidn/1.16")
|
16
|
+
@easy.supports_zlib?.should be_false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "options" do
|
21
|
+
it "should not follow redirects if not instructed to" do
|
22
|
+
e = Typhoeus::Easy.new
|
23
|
+
e.url = "http://localhost:3001/redirect"
|
24
|
+
e.method = :get
|
25
|
+
e.perform
|
26
|
+
e.response_code.should == 302
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow for following redirects" do
|
30
|
+
e = Typhoeus::Easy.new
|
31
|
+
e.url = "http://localhost:3001/redirect"
|
32
|
+
e.method = :get
|
33
|
+
e.follow_location = true
|
34
|
+
e.perform
|
35
|
+
e.response_code.should == 200
|
36
|
+
JSON.parse(e.response_body)["REQUEST_METHOD"].should == "GET"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should allow you to set the user agent" do
|
40
|
+
easy = Typhoeus::Easy.new
|
41
|
+
easy.url = "http://localhost:3002"
|
42
|
+
easy.method = :get
|
43
|
+
easy.user_agent = "myapp"
|
44
|
+
easy.perform
|
45
|
+
easy.response_code.should == 200
|
46
|
+
JSON.parse(easy.response_body)["HTTP_USER_AGENT"].should == "myapp"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should provide a timeout in milliseconds" do
|
50
|
+
e = Typhoeus::Easy.new
|
51
|
+
e.url = "http://localhost:3001"
|
52
|
+
e.method = :get
|
53
|
+
e.timeout = 50
|
54
|
+
e.perform
|
55
|
+
# this doesn't work on a mac for some reason
|
56
|
+
# e.timed_out?.should == true
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow the setting of the max redirects to follow" do
|
60
|
+
e = Typhoeus::Easy.new
|
61
|
+
e.url = "http://localhost:3001/redirect"
|
62
|
+
e.method = :get
|
63
|
+
e.follow_location = true
|
64
|
+
e.max_redirects = 5
|
65
|
+
e.perform
|
66
|
+
e.response_code.should == 200
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should handle our bad redirect action, provided we've set max_redirects properly" do
|
70
|
+
e = Typhoeus::Easy.new
|
71
|
+
e.url = "http://localhost:3001/bad_redirect"
|
72
|
+
e.method = :get
|
73
|
+
e.follow_location = true
|
74
|
+
e.max_redirects = 5
|
75
|
+
e.perform
|
76
|
+
e.response_code.should == 302
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "authentication" do
|
81
|
+
it "should allow to set username and password" do
|
82
|
+
e = Typhoeus::Easy.new
|
83
|
+
username, password = 'foo', 'bar'
|
84
|
+
e.auth = { :username => username, :password => password }
|
85
|
+
e.url = "http://localhost:3001/auth_basic/#{username}/#{password}"
|
86
|
+
e.method = :get
|
87
|
+
e.perform
|
88
|
+
e.response_code.should == 200
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should allow to query auth methods support by the server" do
|
92
|
+
e = Typhoeus::Easy.new
|
93
|
+
e.url = "http://localhost:3001/auth_basic/foo/bar"
|
94
|
+
e.method = :get
|
95
|
+
e.perform
|
96
|
+
e.auth_methods.should == Typhoeus::Easy::AUTH_TYPES[:CURLAUTH_BASIC]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should allow to set authentication method" do
|
100
|
+
e = Typhoeus::Easy.new
|
101
|
+
e.auth = { :username => 'username', :password => 'password', :method => Typhoeus::Easy::AUTH_TYPES[:CURLAUTH_NTLM] }
|
102
|
+
e.url = "http://localhost:3001/auth_ntlm"
|
103
|
+
e.method = :get
|
104
|
+
e.perform
|
105
|
+
e.response_code.should == 200
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "get" do
|
110
|
+
it "should perform a get" do
|
111
|
+
easy = Typhoeus::Easy.new
|
112
|
+
easy.url = "http://localhost:3002"
|
113
|
+
easy.method = :get
|
114
|
+
easy.perform
|
115
|
+
easy.response_code.should == 200
|
116
|
+
JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "GET"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "purge" do
|
121
|
+
it "should set custom request to purge" do
|
122
|
+
easy = Typhoeus::Easy.new
|
123
|
+
easy.should_receive(:set_option).with(Typhoeus::Easy::OPTION_VALUES[:CURLOPT_CUSTOMREQUEST], "PURGE").once
|
124
|
+
easy.method = :purge
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "head" do
|
129
|
+
it "should perform a head" do
|
130
|
+
easy = Typhoeus::Easy.new
|
131
|
+
easy.url = "http://localhost:3002"
|
132
|
+
easy.method = :head
|
133
|
+
easy.perform
|
134
|
+
easy.response_code.should == 200
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "start_time" do
|
139
|
+
it "should be get/settable" do
|
140
|
+
time = Time.now
|
141
|
+
easy = Typhoeus::Easy.new
|
142
|
+
easy.start_time.should be_nil
|
143
|
+
easy.start_time = time
|
144
|
+
easy.start_time.should == time
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "params=" do
|
149
|
+
it "should handle arrays of params" do
|
150
|
+
easy = Typhoeus::Easy.new
|
151
|
+
easy.url = "http://localhost:3002/index.html"
|
152
|
+
easy.method = :get
|
153
|
+
easy.request_body = "this is a body!"
|
154
|
+
easy.params = {
|
155
|
+
:foo => 'bar',
|
156
|
+
:username => ['dbalatero', 'dbalatero2']
|
157
|
+
}
|
158
|
+
|
159
|
+
easy.url.should =~ /\?.*username=dbalatero&username=dbalatero2/
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
describe "put" do
|
165
|
+
it "should perform a put" do
|
166
|
+
easy = Typhoeus::Easy.new
|
167
|
+
easy.url = "http://localhost:3002"
|
168
|
+
easy.method = :put
|
169
|
+
easy.perform
|
170
|
+
easy.response_code.should == 200
|
171
|
+
JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "PUT"
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should send a request body" do
|
175
|
+
easy = Typhoeus::Easy.new
|
176
|
+
easy.url = "http://localhost:3002"
|
177
|
+
easy.method = :put
|
178
|
+
easy.request_body = "this is a body!"
|
179
|
+
easy.perform
|
180
|
+
easy.response_code.should == 200
|
181
|
+
easy.response_body.should include("this is a body!")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "post" do
|
186
|
+
it "should perform a post" do
|
187
|
+
easy = Typhoeus::Easy.new
|
188
|
+
easy.url = "http://localhost:3002"
|
189
|
+
easy.method = :post
|
190
|
+
easy.perform
|
191
|
+
easy.response_code.should == 200
|
192
|
+
JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "POST"
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should send a request body" do
|
196
|
+
easy = Typhoeus::Easy.new
|
197
|
+
easy.url = "http://localhost:3002"
|
198
|
+
easy.method = :post
|
199
|
+
easy.request_body = "this is a body!"
|
200
|
+
easy.perform
|
201
|
+
easy.response_code.should == 200
|
202
|
+
easy.response_body.should include("this is a body!")
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should handle params" do
|
206
|
+
easy = Typhoeus::Easy.new
|
207
|
+
easy.url = "http://localhost:3002"
|
208
|
+
easy.method = :post
|
209
|
+
easy.params = {:foo => "bar"}
|
210
|
+
easy.perform
|
211
|
+
easy.response_code.should == 200
|
212
|
+
easy.response_body.should include("foo=bar")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "delete" do
|
217
|
+
it "should perform a delete" do
|
218
|
+
easy = Typhoeus::Easy.new
|
219
|
+
easy.url = "http://localhost:3002"
|
220
|
+
easy.method = :delete
|
221
|
+
easy.perform
|
222
|
+
easy.response_code.should == 200
|
223
|
+
JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "DELETE"
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should send a request body" do
|
227
|
+
easy = Typhoeus::Easy.new
|
228
|
+
easy.url = "http://localhost:3002"
|
229
|
+
easy.method = :delete
|
230
|
+
easy.request_body = "this is a body!"
|
231
|
+
easy.perform
|
232
|
+
easy.response_code.should == 200
|
233
|
+
easy.response_body.should include("this is a body!")
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Typhoeus::Filter do
|
4
|
+
it "should take a method name and optionally take options" do
|
5
|
+
filter = Typhoeus::Filter.new(:bar, :only => :foo)
|
6
|
+
filter = Typhoeus::Filter.new(:bar)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#apply_filter?" do
|
10
|
+
it "should return true for any method when :only and :except aren't specified" do
|
11
|
+
filter = Typhoeus::Filter.new(:bar)
|
12
|
+
filter.apply_filter?(:asdf).should be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return true if a method is in only" do
|
16
|
+
filter = Typhoeus::Filter.new(:bar, :only => :foo)
|
17
|
+
filter.apply_filter?(:foo).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return false if a method isn't in only" do
|
21
|
+
filter = Typhoeus::Filter.new(:bar, :only => :foo)
|
22
|
+
filter.apply_filter?(:bar).should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return true if a method isn't in except" do
|
26
|
+
filter = Typhoeus::Filter.new(:bar, :except => :foo)
|
27
|
+
filter.apply_filter?(:bar).should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return false if a method is in except" do
|
31
|
+
filter = Typhoeus::Filter.new(:bar, :except => :foo)
|
32
|
+
filter.apply_filter?(:foo).should be_false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,311 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
# some of these tests assume that you have some local services running.
|
4
|
+
# ruby spec/servers/app.rb -p 3000
|
5
|
+
# ruby spec/servers/app.rb -p 3001
|
6
|
+
# ruby spec/servers/app.rb -p 3002
|
7
|
+
describe Typhoeus::Hydra do
|
8
|
+
before(:all) do
|
9
|
+
cache_class = Class.new do
|
10
|
+
def initialize
|
11
|
+
@cache = {}
|
12
|
+
end
|
13
|
+
def get(key)
|
14
|
+
@cache[key]
|
15
|
+
end
|
16
|
+
def set(key, object, timeout = 0)
|
17
|
+
@cache[key] = object
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@cache = cache_class.new
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has a singleton" do
|
24
|
+
Typhoeus::Hydra.hydra.should be_a Typhoeus::Hydra
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has a setter for the singleton" do
|
28
|
+
Typhoeus::Hydra.hydra = :foo
|
29
|
+
Typhoeus::Hydra.hydra.should == :foo
|
30
|
+
Typhoeus::Hydra.hydra = Typhoeus::Hydra.new
|
31
|
+
end
|
32
|
+
|
33
|
+
context "#stub" do
|
34
|
+
before do
|
35
|
+
@hydra = Typhoeus::Hydra.new
|
36
|
+
@on_complete_handler_called = nil
|
37
|
+
@request = Typhoeus::Request.new("http://localhost:3000/foo")
|
38
|
+
@request.on_complete do |response|
|
39
|
+
@on_complete_handler_called = true
|
40
|
+
response.code.should == 404
|
41
|
+
response.headers.should == "whatever"
|
42
|
+
end
|
43
|
+
@response = Typhoeus::Response.new(:code => 404, :headers => "whatever", :body => "not found", :time => 0.1)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "stubs requests to a specific URI" do
|
47
|
+
@hydra.stub(:get, "http://localhost:3000/foo").and_return(@response)
|
48
|
+
@hydra.queue(@request)
|
49
|
+
@hydra.run
|
50
|
+
@on_complete_handler_called.should be_true
|
51
|
+
@response.request.should == @request
|
52
|
+
end
|
53
|
+
|
54
|
+
it "stubs requests to URIs matching a pattern" do
|
55
|
+
@hydra.stub(:get, /foo/).and_return(@response)
|
56
|
+
@hydra.queue(@request)
|
57
|
+
@hydra.run
|
58
|
+
@on_complete_handler_called.should be_true
|
59
|
+
@response.request.should == @request
|
60
|
+
end
|
61
|
+
|
62
|
+
it "can clear stubs" do
|
63
|
+
@hydra.clear_stubs
|
64
|
+
end
|
65
|
+
|
66
|
+
it "clears out previously queued requests once they are called" do
|
67
|
+
@hydra.stub(:get, "asdf").and_return(@response)
|
68
|
+
|
69
|
+
call_count = 0
|
70
|
+
request = Typhoeus::Request.new("asdf")
|
71
|
+
request.on_complete do |response|
|
72
|
+
call_count += 1
|
73
|
+
end
|
74
|
+
@hydra.queue(request)
|
75
|
+
@hydra.run
|
76
|
+
call_count.should == 1
|
77
|
+
@hydra.run
|
78
|
+
call_count.should == 1
|
79
|
+
end
|
80
|
+
|
81
|
+
it "calls stubs for requests that are queued up in the on_complete of a first stub" do
|
82
|
+
@hydra.stub(:get, "asdf").and_return(@response)
|
83
|
+
@hydra.stub(:get, "bar").and_return(@response)
|
84
|
+
|
85
|
+
second_handler_called = false
|
86
|
+
request = Typhoeus::Request.new("asdf")
|
87
|
+
request.on_complete do |response|
|
88
|
+
r = Typhoeus::Request.new("bar")
|
89
|
+
r.on_complete do |res|
|
90
|
+
second_handler_called = true
|
91
|
+
end
|
92
|
+
@hydra.queue(r)
|
93
|
+
end
|
94
|
+
@hydra.queue(request)
|
95
|
+
@hydra.run
|
96
|
+
|
97
|
+
second_handler_called.should be_true
|
98
|
+
end
|
99
|
+
|
100
|
+
it "matches a stub only when the HTTP method also matches"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "queues a request" do
|
104
|
+
hydra = Typhoeus::Hydra.new
|
105
|
+
hydra.queue Typhoeus::Request.new("http://localhost:3000")
|
106
|
+
end
|
107
|
+
|
108
|
+
it "runs a batch of requests" do
|
109
|
+
hydra = Typhoeus::Hydra.new
|
110
|
+
first = Typhoeus::Request.new("http://localhost:3000/first")
|
111
|
+
second = Typhoeus::Request.new("http://localhost:3001/second")
|
112
|
+
hydra.queue first
|
113
|
+
hydra.queue second
|
114
|
+
hydra.run
|
115
|
+
first.response.body.should include("first")
|
116
|
+
second.response.body.should include("second")
|
117
|
+
end
|
118
|
+
|
119
|
+
it "has a cache_setter proc" do
|
120
|
+
hydra = Typhoeus::Hydra.new
|
121
|
+
hydra.cache_setter do |request|
|
122
|
+
# @cache.set(request.cache_key, request.response, request.cache_timeout)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it "has a cache_getter" do
|
127
|
+
hydra = Typhoeus::Hydra.new
|
128
|
+
hydra.cache_getter do |request|
|
129
|
+
# @cache.get(request.cache_key) rescue nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "memoizes GET reqeusts" do
|
134
|
+
hydra = Typhoeus::Hydra.new
|
135
|
+
first = Typhoeus::Request.new("http://localhost:3000/foo", :params => {:delay => 1})
|
136
|
+
second = Typhoeus::Request.new("http://localhost:3000/foo", :params => {:delay => 1})
|
137
|
+
hydra.queue first
|
138
|
+
hydra.queue second
|
139
|
+
start_time = Time.now
|
140
|
+
hydra.run
|
141
|
+
first.response.body.should include("foo")
|
142
|
+
first.handled_response.body.should include("foo")
|
143
|
+
first.response.should == second.response
|
144
|
+
first.handled_response.should == second.handled_response
|
145
|
+
(Time.now - start_time).should < 1.2 # if it had run twice it would be ~ 2 seconds
|
146
|
+
end
|
147
|
+
|
148
|
+
it "can turn off memoization for GET requests" do
|
149
|
+
hydra = Typhoeus::Hydra.new
|
150
|
+
hydra.disable_memoization
|
151
|
+
first = Typhoeus::Request.new("http://localhost:3000/foo")
|
152
|
+
second = Typhoeus::Request.new("http://localhost:3000/foo")
|
153
|
+
hydra.queue first
|
154
|
+
hydra.queue second
|
155
|
+
hydra.run
|
156
|
+
first.response.body.should include("foo")
|
157
|
+
first.response.object_id.should_not == second.response.object_id
|
158
|
+
end
|
159
|
+
|
160
|
+
it "pulls GETs from cache" do
|
161
|
+
hydra = Typhoeus::Hydra.new
|
162
|
+
start_time = Time.now
|
163
|
+
hydra.cache_getter do |request|
|
164
|
+
@cache.get(request.cache_key) rescue nil
|
165
|
+
end
|
166
|
+
hydra.cache_setter do |request|
|
167
|
+
@cache.set(request.cache_key, request.response, request.cache_timeout)
|
168
|
+
end
|
169
|
+
|
170
|
+
first = Typhoeus::Request.new("http://localhost:3000/foo", :params => {:delay => 1})
|
171
|
+
@cache.set(first.cache_key, :foo, 60)
|
172
|
+
hydra.queue first
|
173
|
+
hydra.run
|
174
|
+
(Time.now - start_time).should < 0.1
|
175
|
+
first.response.should == :foo
|
176
|
+
end
|
177
|
+
|
178
|
+
it "sets GET responses to cache when the request has a cache_timeout value" do
|
179
|
+
hydra = Typhoeus::Hydra.new
|
180
|
+
hydra.cache_getter do |request|
|
181
|
+
@cache.get(request.cache_key) rescue nil
|
182
|
+
end
|
183
|
+
hydra.cache_setter do |request|
|
184
|
+
@cache.set(request.cache_key, request.response, request.cache_timeout)
|
185
|
+
end
|
186
|
+
|
187
|
+
first = Typhoeus::Request.new("http://localhost:3000/first", :cache_timeout => 0)
|
188
|
+
second = Typhoeus::Request.new("http://localhost:3000/second")
|
189
|
+
hydra.queue first
|
190
|
+
hydra.queue second
|
191
|
+
hydra.run
|
192
|
+
first.response.body.should include("first")
|
193
|
+
@cache.get(first.cache_key).should == first.response
|
194
|
+
@cache.get(second.cache_key).should be_nil
|
195
|
+
end
|
196
|
+
|
197
|
+
it "has a global on_complete" do
|
198
|
+
foo = nil
|
199
|
+
hydra = Typhoeus::Hydra.new
|
200
|
+
hydra.on_complete do |response|
|
201
|
+
foo = :called
|
202
|
+
end
|
203
|
+
|
204
|
+
first = Typhoeus::Request.new("http://localhost:3000/first")
|
205
|
+
hydra.queue first
|
206
|
+
hydra.run
|
207
|
+
first.response.body.should include("first")
|
208
|
+
foo.should == :called
|
209
|
+
end
|
210
|
+
|
211
|
+
it "has a global on_complete setter" do
|
212
|
+
foo = nil
|
213
|
+
hydra = Typhoeus::Hydra.new
|
214
|
+
proc = Proc.new {|response| foo = :called}
|
215
|
+
hydra.on_complete = proc
|
216
|
+
|
217
|
+
first = Typhoeus::Request.new("http://localhost:3000/first")
|
218
|
+
hydra.queue first
|
219
|
+
hydra.run
|
220
|
+
first.response.body.should include("first")
|
221
|
+
foo.should == :called
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should reuse connections from the pool for a host"
|
225
|
+
|
226
|
+
it "should queue up requests while others are running" do
|
227
|
+
hydra = Typhoeus::Hydra.new
|
228
|
+
|
229
|
+
start_time = Time.now
|
230
|
+
@responses = []
|
231
|
+
|
232
|
+
request = Typhoeus::Request.new("http://localhost:3000/first", :params => {:delay => 1})
|
233
|
+
request.on_complete do |response|
|
234
|
+
@responses << response
|
235
|
+
response.body.should include("first")
|
236
|
+
end
|
237
|
+
|
238
|
+
request.after_complete do |object|
|
239
|
+
second_request = Typhoeus::Request.new("http://localhost:3001/second", :params => {:delay => 2})
|
240
|
+
second_request.on_complete do |response|
|
241
|
+
@responses << response
|
242
|
+
response.body.should include("second")
|
243
|
+
end
|
244
|
+
hydra.queue second_request
|
245
|
+
end
|
246
|
+
hydra.queue request
|
247
|
+
|
248
|
+
third_request = Typhoeus::Request.new("http://localhost:3002/third", :params => {:delay => 3})
|
249
|
+
third_request.on_complete do |response|
|
250
|
+
@responses << response
|
251
|
+
response.body.should include("third")
|
252
|
+
end
|
253
|
+
hydra.queue third_request
|
254
|
+
|
255
|
+
hydra.run
|
256
|
+
@responses.size.should == 3
|
257
|
+
(Time.now - start_time).should < 3.3
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should fire and forget" do
|
261
|
+
# this test is totally hacky. I have no clue how to make it verify. I just look at the test servers
|
262
|
+
# to verify that stuff is running
|
263
|
+
hydra = Typhoeus::Hydra.new
|
264
|
+
first = Typhoeus::Request.new("http://localhost:3000/first?delay=1")
|
265
|
+
second = Typhoeus::Request.new("http://localhost:3001/second?delay=2")
|
266
|
+
hydra.queue first
|
267
|
+
hydra.queue second
|
268
|
+
hydra.fire_and_forget
|
269
|
+
third = Typhoeus::Request.new("http://localhost:3002/third?delay=3")
|
270
|
+
hydra.queue third
|
271
|
+
hydra.fire_and_forget
|
272
|
+
sleep 3 # have to do this or future tests may break.
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should take the maximum number of concurrent requests as an argument" do
|
276
|
+
hydra = Typhoeus::Hydra.new(:max_concurrency => 2)
|
277
|
+
first = Typhoeus::Request.new("http://localhost:3000/first?delay=1")
|
278
|
+
second = Typhoeus::Request.new("http://localhost:3001/second?delay=1")
|
279
|
+
third = Typhoeus::Request.new("http://localhost:3002/third?delay=1")
|
280
|
+
hydra.queue first
|
281
|
+
hydra.queue second
|
282
|
+
hydra.queue third
|
283
|
+
|
284
|
+
start_time = Time.now
|
285
|
+
hydra.run
|
286
|
+
finish_time = Time.now
|
287
|
+
|
288
|
+
first.response.code.should == 200
|
289
|
+
second.response.code.should == 200
|
290
|
+
third.response.code.should == 200
|
291
|
+
(finish_time - start_time).should > 2.0
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should respect the follow_location option when set on a request" do
|
295
|
+
hydra = Typhoeus::Hydra.new
|
296
|
+
request = Typhoeus::Request.new("http://localhost:3000/redirect", :follow_location => true)
|
297
|
+
hydra.queue request
|
298
|
+
hydra.run
|
299
|
+
|
300
|
+
request.response.code.should == 200
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should pass through the max_redirects option when set on a request" do
|
304
|
+
hydra = Typhoeus::Hydra.new
|
305
|
+
request = Typhoeus::Request.new("http://localhost:3000/bad_redirect", :max_redirects => 5)
|
306
|
+
hydra.queue request
|
307
|
+
hydra.run
|
308
|
+
|
309
|
+
request.response.code.should == 302
|
310
|
+
end
|
311
|
+
end
|