gravis-typhoeus 0.1.29

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