gravis-typhoeus 0.1.29

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.
Files changed (44) hide show
  1. data/.gitignore +2 -0
  2. data/README.textile +301 -0
  3. data/Rakefile +39 -0
  4. data/VERSION +1 -0
  5. data/benchmarks/profile.rb +25 -0
  6. data/benchmarks/vs_nethttp.rb +35 -0
  7. data/examples/twitter.rb +21 -0
  8. data/ext/typhoeus/.gitignore +5 -0
  9. data/ext/typhoeus/Makefile +157 -0
  10. data/ext/typhoeus/extconf.rb +65 -0
  11. data/ext/typhoeus/native.c +11 -0
  12. data/ext/typhoeus/native.h +21 -0
  13. data/ext/typhoeus/typhoeus_easy.c +207 -0
  14. data/ext/typhoeus/typhoeus_easy.h +19 -0
  15. data/ext/typhoeus/typhoeus_multi.c +225 -0
  16. data/ext/typhoeus/typhoeus_multi.h +16 -0
  17. data/lib/typhoeus/.gitignore +1 -0
  18. data/lib/typhoeus/easy.rb +322 -0
  19. data/lib/typhoeus/filter.rb +28 -0
  20. data/lib/typhoeus/hydra.rb +227 -0
  21. data/lib/typhoeus/multi.rb +35 -0
  22. data/lib/typhoeus/remote.rb +306 -0
  23. data/lib/typhoeus/remote_method.rb +108 -0
  24. data/lib/typhoeus/remote_proxy_object.rb +48 -0
  25. data/lib/typhoeus/request.rb +124 -0
  26. data/lib/typhoeus/response.rb +49 -0
  27. data/lib/typhoeus/service.rb +20 -0
  28. data/lib/typhoeus.rb +55 -0
  29. data/profilers/valgrind.rb +24 -0
  30. data/spec/fixtures/result_set.xml +60 -0
  31. data/spec/servers/app.rb +73 -0
  32. data/spec/spec.opts +2 -0
  33. data/spec/spec_helper.rb +11 -0
  34. data/spec/typhoeus/easy_spec.rb +228 -0
  35. data/spec/typhoeus/filter_spec.rb +35 -0
  36. data/spec/typhoeus/hydra_spec.rb +311 -0
  37. data/spec/typhoeus/multi_spec.rb +74 -0
  38. data/spec/typhoeus/remote_method_spec.rb +141 -0
  39. data/spec/typhoeus/remote_proxy_object_spec.rb +65 -0
  40. data/spec/typhoeus/remote_spec.rb +695 -0
  41. data/spec/typhoeus/request_spec.rb +169 -0
  42. data/spec/typhoeus/response_spec.rb +63 -0
  43. data/typhoeus.gemspec +112 -0
  44. metadata +203 -0
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ # go to ext/typhoeus and run ruby extconf.rb && make before running
3
+ # this.
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../ext")
6
+ require File.dirname(__FILE__) + "/../lib/typhoeus"
7
+
8
+ klass = Class.new { include Typhoeus }
9
+
10
+ loops = ENV['LOOPS'].to_i
11
+ url = ARGV.first || (raise "requires URL!")
12
+
13
+ loops.times do |i|
14
+ puts "On loop #{i}" if i % 10 == 0
15
+ results = []
16
+ 5.times do
17
+ results << klass.get(url)
18
+ end
19
+
20
+ # fire requests
21
+ results[0].code
22
+ end
23
+
24
+ puts "Ran #{loops} loops on #{url}!"
@@ -0,0 +1,60 @@
1
+ <result_set>
2
+ <ttl>20</ttl>
3
+ <result>
4
+ <id>1</id>
5
+ <name>hello</name>
6
+ <description>
7
+ this is a long description for a text field of some kind.
8
+ this is a long description for a text field of some kind.
9
+ this is a long description for a text field of some kind.
10
+ this is a long description for a text field of some kind.
11
+ this is a long description for a text field of some kind.
12
+ this is a long description for a text field of some kind.
13
+ this is a long description for a text field of some kind.
14
+ this is a long description for a text field of some kind.
15
+ this is a long description for a text field of some kind.
16
+ this is a long description for a text field of some kind.
17
+ this is a long description for a text field of some kind.
18
+ this is a long description for a text field of some kind.
19
+ this is a long description for a text field of some kind.
20
+ </description>
21
+ </result>
22
+ <result>
23
+ <id>2</id>
24
+ <name>hello</name>
25
+ <description>
26
+ this is a long description for a text field of some kind.
27
+ this is a long description for a text field of some kind.
28
+ this is a long description for a text field of some kind.
29
+ this is a long description for a text field of some kind.
30
+ this is a long description for a text field of some kind.
31
+ this is a long description for a text field of some kind.
32
+ this is a long description for a text field of some kind.
33
+ this is a long description for a text field of some kind.
34
+ this is a long description for a text field of some kind.
35
+ this is a long description for a text field of some kind.
36
+ this is a long description for a text field of some kind.
37
+ this is a long description for a text field of some kind.
38
+ this is a long description for a text field of some kind.
39
+ </description>
40
+ </result>
41
+ <result>
42
+ <id>3</id>
43
+ <name>hello</name>
44
+ <description>
45
+ this is a long description for a text field of some kind.
46
+ this is a long description for a text field of some kind.
47
+ this is a long description for a text field of some kind.
48
+ this is a long description for a text field of some kind.
49
+ this is a long description for a text field of some kind.
50
+ this is a long description for a text field of some kind.
51
+ this is a long description for a text field of some kind.
52
+ this is a long description for a text field of some kind.
53
+ this is a long description for a text field of some kind.
54
+ this is a long description for a text field of some kind.
55
+ this is a long description for a text field of some kind.
56
+ this is a long description for a text field of some kind.
57
+ this is a long description for a text field of some kind.
58
+ </description>
59
+ </result>
60
+ </result_set>
@@ -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
@@ -0,0 +1,2 @@
1
+ --diff
2
+ --color
@@ -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,228 @@
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 "head" do
121
+ it "should perform a head" do
122
+ easy = Typhoeus::Easy.new
123
+ easy.url = "http://localhost:3002"
124
+ easy.method = :head
125
+ easy.perform
126
+ easy.response_code.should == 200
127
+ end
128
+ end
129
+
130
+ describe "start_time" do
131
+ it "should be get/settable" do
132
+ time = Time.now
133
+ easy = Typhoeus::Easy.new
134
+ easy.start_time.should be_nil
135
+ easy.start_time = time
136
+ easy.start_time.should == time
137
+ end
138
+ end
139
+
140
+ describe "params=" do
141
+ it "should handle arrays of params" do
142
+ easy = Typhoeus::Easy.new
143
+ easy.url = "http://localhost:3002/index.html"
144
+ easy.method = :get
145
+ easy.request_body = "this is a body!"
146
+ easy.params = {
147
+ :foo => 'bar',
148
+ :username => ['dbalatero', 'dbalatero2']
149
+ }
150
+
151
+ easy.url.should =~ /\?.*username=dbalatero&username=dbalatero2/
152
+ end
153
+ end
154
+
155
+
156
+ describe "put" do
157
+ it "should perform a put" do
158
+ easy = Typhoeus::Easy.new
159
+ easy.url = "http://localhost:3002"
160
+ easy.method = :put
161
+ easy.perform
162
+ easy.response_code.should == 200
163
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "PUT"
164
+ end
165
+
166
+ it "should send a request body" do
167
+ easy = Typhoeus::Easy.new
168
+ easy.url = "http://localhost:3002"
169
+ easy.method = :put
170
+ easy.request_body = "this is a body!"
171
+ easy.perform
172
+ easy.response_code.should == 200
173
+ easy.response_body.should include("this is a body!")
174
+ end
175
+ end
176
+
177
+ describe "post" do
178
+ it "should perform a post" do
179
+ easy = Typhoeus::Easy.new
180
+ easy.url = "http://localhost:3002"
181
+ easy.method = :post
182
+ easy.perform
183
+ easy.response_code.should == 200
184
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "POST"
185
+ end
186
+
187
+ it "should send a request body" do
188
+ easy = Typhoeus::Easy.new
189
+ easy.url = "http://localhost:3002"
190
+ easy.method = :post
191
+ easy.request_body = "this is a body!"
192
+ easy.perform
193
+ easy.response_code.should == 200
194
+ easy.response_body.should include("this is a body!")
195
+ end
196
+
197
+ it "should handle params" do
198
+ easy = Typhoeus::Easy.new
199
+ easy.url = "http://localhost:3002"
200
+ easy.method = :post
201
+ easy.params = {:foo => "bar"}
202
+ easy.perform
203
+ easy.response_code.should == 200
204
+ easy.response_body.should include("foo=bar")
205
+ end
206
+ end
207
+
208
+ describe "delete" do
209
+ it "should perform a delete" do
210
+ easy = Typhoeus::Easy.new
211
+ easy.url = "http://localhost:3002"
212
+ easy.method = :delete
213
+ easy.perform
214
+ easy.response_code.should == 200
215
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "DELETE"
216
+ end
217
+
218
+ it "should send a request body" do
219
+ easy = Typhoeus::Easy.new
220
+ easy.url = "http://localhost:3002"
221
+ easy.method = :delete
222
+ easy.request_body = "this is a body!"
223
+ easy.perform
224
+ easy.response_code.should == 200
225
+ easy.response_body.should include("this is a body!")
226
+ end
227
+ end
228
+ 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