typhoeus 0.1.6 → 0.1.28
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/CHANGELOG.markdown +9 -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/extconf.rb +3 -2
- data/ext/typhoeus/native.h +7 -0
- data/ext/typhoeus/typhoeus_multi.c +1 -2
- data/lib/typhoeus/.gitignore +1 -0
- data/lib/typhoeus/easy.rb +155 -37
- data/lib/typhoeus/hydra.rb +69 -21
- data/lib/typhoeus/multi.rb +4 -3
- data/lib/typhoeus/remote_proxy_object.rb +6 -6
- data/lib/typhoeus/request.rb +72 -26
- data/lib/typhoeus/response.rb +32 -2
- data/lib/typhoeus/service.rb +20 -0
- data/lib/typhoeus.rb +7 -7
- data/profilers/valgrind.rb +24 -0
- data/spec/fixtures/result_set.xml +60 -0
- data/spec/servers/app.rb +37 -1
- data/spec/typhoeus/easy_spec.rb +112 -3
- data/spec/typhoeus/hydra_spec.rb +311 -0
- data/spec/typhoeus/remote_spec.rb +1 -1
- data/spec/typhoeus/request_spec.rb +169 -0
- data/spec/typhoeus/response_spec.rb +27 -0
- data/typhoeus.gemspec +113 -0
- metadata +127 -32
data/lib/typhoeus/request.rb
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
module Typhoeus
|
|
2
2
|
class Request
|
|
3
|
-
attr_accessor :method, :params, :body, :headers, :timeout, :user_agent, :response, :cache_timeout
|
|
3
|
+
attr_accessor :method, :params, :body, :headers, :timeout, :user_agent, :response, :cache_timeout, :follow_location, :max_redirects, :proxy, :disable_ssl_peer_verification, :ssl_cert, :ssl_cert_type, :ssl_key, :ssl_key_type, :ssl_key_password, :ssl_cacert, :ssl_capath
|
|
4
|
+
|
|
5
|
+
|
|
4
6
|
attr_reader :url
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
# Initialize a new Request
|
|
9
|
+
#
|
|
10
|
+
# Options:
|
|
11
|
+
# * +url+ : Endpoint (URL) of the request
|
|
12
|
+
# * +options+ : A hash containing options among :
|
|
13
|
+
# ** +:method+ : :get (default) / :post / :put
|
|
14
|
+
# ** +:params+ : params as a Hash
|
|
15
|
+
# ** +:body+
|
|
16
|
+
# ** +:timeout+ : timeout (ms)
|
|
17
|
+
# ** +:headers+ : headers as Hash
|
|
18
|
+
# ** +:user_agent+ : user agent (string)
|
|
19
|
+
# ** +:cache_timeout+ : cache timeout (ms)
|
|
20
|
+
# ** +:follow_location
|
|
21
|
+
# ** +:max_redirects
|
|
22
|
+
# ** +:proxy
|
|
23
|
+
# ** +:disable_ssl_peer_verification
|
|
24
|
+
# ** +:ssl_cert
|
|
25
|
+
# ** +:ssl_cert_type
|
|
26
|
+
# ** +:ssl_key
|
|
27
|
+
# ** +:ssl_key_type
|
|
28
|
+
# ** +:ssl_key_password
|
|
29
|
+
# ** +:ssl_cacert
|
|
30
|
+
# ** +:ssl_capath
|
|
31
|
+
#
|
|
6
32
|
def initialize(url, options = {})
|
|
7
33
|
@method = options[:method] || :get
|
|
8
34
|
@params = options[:params]
|
|
@@ -11,12 +37,28 @@ module Typhoeus
|
|
|
11
37
|
@headers = options[:headers] || {}
|
|
12
38
|
@user_agent = options[:user_agent] || Typhoeus::USER_AGENT
|
|
13
39
|
@cache_timeout = options[:cache_timeout]
|
|
14
|
-
@
|
|
40
|
+
@follow_location = options[:follow_location]
|
|
41
|
+
@max_redirects = options[:max_redirects]
|
|
42
|
+
@proxy = options[:proxy]
|
|
43
|
+
@disable_ssl_peer_verification = options[:disable_ssl_peer_verification]
|
|
44
|
+
@ssl_cert = options[:ssl_cert]
|
|
45
|
+
@ssl_cert_type = options[:ssl_cert_type]
|
|
46
|
+
@ssl_key = options[:ssl_key]
|
|
47
|
+
@ssl_key_type = options[:ssl_key_type]
|
|
48
|
+
@ssl_key_password = options[:ssl_key_password]
|
|
49
|
+
@ssl_cacert = options[:ssl_cacert]
|
|
50
|
+
@ssl_capath = options[:ssl_capath]
|
|
51
|
+
|
|
52
|
+
if @method == :post
|
|
53
|
+
@url = url
|
|
54
|
+
else
|
|
55
|
+
@url = @params ? "#{url}?#{params_string}" : url
|
|
56
|
+
end
|
|
15
57
|
@on_complete = nil
|
|
16
58
|
@after_complete = nil
|
|
17
59
|
@handled_response = nil
|
|
18
60
|
end
|
|
19
|
-
|
|
61
|
+
|
|
20
62
|
def host
|
|
21
63
|
slash_location = @url.index('/', 8)
|
|
22
64
|
if slash_location
|
|
@@ -26,14 +68,14 @@ module Typhoeus
|
|
|
26
68
|
return query_string_location ? @url.slice(0, query_string_location) : @url
|
|
27
69
|
end
|
|
28
70
|
end
|
|
29
|
-
|
|
71
|
+
|
|
30
72
|
def headers
|
|
31
73
|
@headers["User-Agent"] = @user_agent
|
|
32
74
|
@headers
|
|
33
75
|
end
|
|
34
|
-
|
|
76
|
+
|
|
35
77
|
def params_string
|
|
36
|
-
params.keys.sort.collect do |k|
|
|
78
|
+
params.keys.sort { |a, b| a.to_s <=> b.to_s }.collect do |k|
|
|
37
79
|
value = params[k]
|
|
38
80
|
if value.is_a? Hash
|
|
39
81
|
value.keys.collect {|sk| Rack::Utils.escape("#{k}[#{sk}]") + "=" + Rack::Utils.escape(value[sk].to_s)}
|
|
@@ -45,67 +87,71 @@ module Typhoeus
|
|
|
45
87
|
end
|
|
46
88
|
end.flatten.join("&")
|
|
47
89
|
end
|
|
48
|
-
|
|
90
|
+
|
|
49
91
|
def on_complete(&block)
|
|
50
92
|
@on_complete = block
|
|
51
93
|
end
|
|
52
|
-
|
|
94
|
+
|
|
53
95
|
def on_complete=(proc)
|
|
54
96
|
@on_complete = proc
|
|
55
97
|
end
|
|
56
|
-
|
|
98
|
+
|
|
57
99
|
def after_complete(&block)
|
|
58
100
|
@after_complete = block
|
|
59
101
|
end
|
|
60
|
-
|
|
102
|
+
|
|
61
103
|
def after_complete=(proc)
|
|
62
104
|
@after_complete = proc
|
|
63
105
|
end
|
|
64
|
-
|
|
106
|
+
|
|
65
107
|
def call_handlers
|
|
66
108
|
if @on_complete
|
|
67
109
|
@handled_response = @on_complete.call(response)
|
|
68
110
|
call_after_complete
|
|
69
111
|
end
|
|
70
112
|
end
|
|
71
|
-
|
|
113
|
+
|
|
72
114
|
def call_after_complete
|
|
73
115
|
@after_complete.call(@handled_response) if @after_complete
|
|
74
116
|
end
|
|
75
|
-
|
|
117
|
+
|
|
76
118
|
def handled_response=(val)
|
|
77
119
|
@handled_response = val
|
|
78
120
|
end
|
|
79
|
-
|
|
121
|
+
|
|
80
122
|
def handled_response
|
|
81
123
|
@handled_response || response
|
|
82
124
|
end
|
|
83
|
-
|
|
125
|
+
|
|
84
126
|
def cache_key
|
|
85
127
|
Digest::SHA1.hexdigest(url)
|
|
86
128
|
end
|
|
87
|
-
|
|
129
|
+
|
|
88
130
|
def self.run(url, params)
|
|
89
131
|
r = new(url, params)
|
|
90
132
|
Typhoeus::Hydra.hydra.queue r
|
|
91
133
|
Typhoeus::Hydra.hydra.run
|
|
92
134
|
r.response
|
|
93
135
|
end
|
|
94
|
-
|
|
95
|
-
def self.get(url, params)
|
|
136
|
+
|
|
137
|
+
def self.get(url, params = {})
|
|
96
138
|
run(url, params.merge(:method => :get))
|
|
97
139
|
end
|
|
98
|
-
|
|
99
|
-
def self.post(url, params)
|
|
140
|
+
|
|
141
|
+
def self.post(url, params = {})
|
|
100
142
|
run(url, params.merge(:method => :post))
|
|
101
143
|
end
|
|
102
|
-
|
|
103
|
-
def self.put(url, params)
|
|
144
|
+
|
|
145
|
+
def self.put(url, params = {})
|
|
104
146
|
run(url, params.merge(:method => :put))
|
|
105
147
|
end
|
|
106
|
-
|
|
107
|
-
def self.delete(url, params)
|
|
148
|
+
|
|
149
|
+
def self.delete(url, params = {})
|
|
108
150
|
run(url, params.merge(:method => :delete))
|
|
109
151
|
end
|
|
152
|
+
|
|
153
|
+
def self.head(url, params = {})
|
|
154
|
+
run(url, params.merge(:method => :head))
|
|
155
|
+
end
|
|
110
156
|
end
|
|
111
|
-
end
|
|
157
|
+
end
|
data/lib/typhoeus/response.rb
CHANGED
|
@@ -3,8 +3,9 @@ module Typhoeus
|
|
|
3
3
|
attr_accessor :request
|
|
4
4
|
attr_reader :code, :headers, :body, :time,
|
|
5
5
|
:requested_url, :requested_remote_method,
|
|
6
|
-
:requested_http_method, :start_time
|
|
7
|
-
|
|
6
|
+
:requested_http_method, :start_time,
|
|
7
|
+
:effective_url
|
|
8
|
+
|
|
8
9
|
def initialize(params = {})
|
|
9
10
|
@code = params[:code]
|
|
10
11
|
@headers = params[:headers]
|
|
@@ -14,6 +15,35 @@ module Typhoeus
|
|
|
14
15
|
@requested_http_method = params[:requested_http_method]
|
|
15
16
|
@start_time = params[:start_time]
|
|
16
17
|
@request = params[:request]
|
|
18
|
+
@effective_url = params[:effective_url]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def headers_hash
|
|
22
|
+
headers.split("\n").map {|o| o.strip}.inject({}) do |hash, o|
|
|
23
|
+
if o.empty?
|
|
24
|
+
hash
|
|
25
|
+
else
|
|
26
|
+
i = o.index(":") || o.size
|
|
27
|
+
key = o.slice(0, i)
|
|
28
|
+
value = o.slice(i + 1, o.size)
|
|
29
|
+
value = value.strip unless value.nil?
|
|
30
|
+
if hash.has_key? key
|
|
31
|
+
hash[key] = [hash[key], value].flatten
|
|
32
|
+
else
|
|
33
|
+
hash[key] = value
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
hash
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def success?
|
|
42
|
+
@code >= 200 && @code < 300
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def modified?
|
|
46
|
+
@code != 304
|
|
17
47
|
end
|
|
18
48
|
end
|
|
19
49
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Typhoeus
|
|
2
|
+
class Service
|
|
3
|
+
def initialize(host, port)
|
|
4
|
+
@host = host
|
|
5
|
+
@port = port
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def get(resource, params)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def put(resource, params)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def post(resource, params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def delete(resource, params)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/typhoeus.rb
CHANGED
|
@@ -14,23 +14,23 @@ require 'typhoeus/request'
|
|
|
14
14
|
require 'typhoeus/hydra'
|
|
15
15
|
|
|
16
16
|
module Typhoeus
|
|
17
|
-
VERSION =
|
|
18
|
-
|
|
17
|
+
VERSION = File.read(File.dirname(__FILE__) + "/../VERSION").chomp
|
|
18
|
+
|
|
19
19
|
def self.easy_object_pool
|
|
20
20
|
@easy_objects ||= []
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
def self.init_easy_object_pool
|
|
24
24
|
20.times do
|
|
25
25
|
easy_object_pool << Typhoeus::Easy.new
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
def self.release_easy_object(easy)
|
|
30
30
|
easy.reset
|
|
31
31
|
easy_object_pool << easy
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
def self.get_easy_object
|
|
35
35
|
if easy_object_pool.empty?
|
|
36
36
|
Typhoeus::Easy.new
|
|
@@ -38,12 +38,12 @@ module Typhoeus
|
|
|
38
38
|
easy_object_pool.pop
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
def self.add_easy_request(easy_object)
|
|
43
43
|
Thread.current[:curl_multi] ||= Typhoeus::Multi.new
|
|
44
44
|
Thread.current[:curl_multi].add(easy_object)
|
|
45
45
|
end
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
def self.perform_easy_requests
|
|
48
48
|
multi = Thread.current[:curl_multi]
|
|
49
49
|
start_time = Time.now
|
|
@@ -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>
|
data/spec/servers/app.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
1
2
|
require 'rubygems'
|
|
2
3
|
require 'sinatra'
|
|
3
4
|
require 'json'
|
|
@@ -16,11 +17,46 @@ get '/fail_forever' do
|
|
|
16
17
|
error 500, "oh noes!"
|
|
17
18
|
end
|
|
18
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
|
+
|
|
19
51
|
get '/**' do
|
|
20
52
|
sleep params["delay"].to_i if params.has_key?("delay")
|
|
21
53
|
request.env.merge!(:body => request.body.read).to_json
|
|
22
54
|
end
|
|
23
55
|
|
|
56
|
+
head '/**' do
|
|
57
|
+
sleep params["delay"].to_i if params.has_key?("delay")
|
|
58
|
+
end
|
|
59
|
+
|
|
24
60
|
put '/**' do
|
|
25
61
|
puts request.inspect
|
|
26
62
|
request.env.merge!(:body => request.body.read).to_json
|
|
@@ -34,4 +70,4 @@ end
|
|
|
34
70
|
delete '/**' do
|
|
35
71
|
puts request.inspect
|
|
36
72
|
request.env.merge!(:body => request.body.read).to_json
|
|
37
|
-
end
|
|
73
|
+
end
|
data/spec/typhoeus/easy_spec.rb
CHANGED
|
@@ -1,9 +1,51 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
|
|
3
|
-
describe Typhoeus::Easy do
|
|
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
|
+
|
|
4
20
|
describe "options" do
|
|
5
|
-
it "should
|
|
6
|
-
|
|
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
|
+
|
|
7
49
|
it "should provide a timeout in milliseconds" do
|
|
8
50
|
e = Typhoeus::Easy.new
|
|
9
51
|
e.url = "http://localhost:3001"
|
|
@@ -13,6 +55,55 @@ describe Typhoeus::Easy do
|
|
|
13
55
|
# this doesn't work on a mac for some reason
|
|
14
56
|
# e.timed_out?.should == true
|
|
15
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
|
|
16
107
|
end
|
|
17
108
|
|
|
18
109
|
describe "get" do
|
|
@@ -26,6 +117,24 @@ describe Typhoeus::Easy do
|
|
|
26
117
|
end
|
|
27
118
|
end
|
|
28
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
|
+
|
|
29
138
|
describe "start_time" do
|
|
30
139
|
it "should be get/settable" do
|
|
31
140
|
time = Time.now
|