typhoeus 0.1.24 → 0.1.31

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.
@@ -130,17 +130,33 @@ module Typhoeus
130
130
 
131
131
  def get_easy_object(request)
132
132
  @running_requests += 1
133
+
133
134
  easy = @easy_pool.pop || Easy.new
135
+ easy.verbose = request.verbose
136
+ if request.username || request.password
137
+ auth = { :username => request.username, :password => request.password }
138
+ auth[:method] = Typhoeus::Easy::AUTH_TYPES["CURLAUTH_#{request.auth_method.to_s.upcase}".to_sym] if request.auth_method
139
+ easy.auth = auth
140
+ end
134
141
  easy.url = request.url
135
142
  easy.method = request.method
136
143
  easy.params = request.params if request.method == :post && !request.params.nil?
137
144
  easy.headers = request.headers if request.headers
138
145
  easy.request_body = request.body if request.body
139
146
  easy.timeout = request.timeout if request.timeout
147
+ easy.connect_timeout = request.connect_timeout if request.connect_timeout
140
148
  easy.follow_location = request.follow_location if request.follow_location
141
149
  easy.max_redirects = request.max_redirects if request.max_redirects
142
150
  easy.proxy = request.proxy if request.proxy
143
151
  easy.disable_ssl_peer_verification if request.disable_ssl_peer_verification
152
+ easy.ssl_cert = request.ssl_cert
153
+ easy.ssl_cert_type = request.ssl_cert_type
154
+ easy.ssl_key = request.ssl_key
155
+ easy.ssl_key_type = request.ssl_key_type
156
+ easy.ssl_key_password = request.ssl_key_password
157
+ easy.ssl_cacert = request.ssl_cacert
158
+ easy.ssl_capath = request.ssl_capath
159
+ easy.verbose = request.verbose
144
160
 
145
161
  easy.on_success do |easy|
146
162
  queue_next
@@ -192,6 +208,7 @@ module Typhoeus
192
208
  :headers => easy.response_header,
193
209
  :body => easy.response_body,
194
210
  :time => easy.total_time_taken,
211
+ :effective_url => easy.effective_url,
195
212
  :request => request)
196
213
  end
197
214
  private :response_from_easy
@@ -9,19 +9,20 @@ module Typhoeus
9
9
  def remove(easy)
10
10
  multi_remove_handle(easy)
11
11
  end
12
-
12
+
13
13
  def add(easy)
14
+ easy.set_headers() if easy.headers.empty?
14
15
  @easy_handles << easy
15
16
  multi_add_handle(easy)
16
17
  end
17
-
18
+
18
19
  def perform()
19
20
  while active_handle_count > 0 do
20
21
  multi_perform
21
22
  end
22
23
  reset_easy_handles
23
24
  end
24
-
25
+
25
26
  def cleanup()
26
27
  multi_cleanup
27
28
  end
@@ -1,13 +1,45 @@
1
1
  module Typhoeus
2
2
  class Request
3
- attr_accessor :method, :params, :body, :headers, :timeout, :user_agent, :response, :cache_timeout, :follow_location, :max_redirects, :proxy, :disable_ssl_peer_verification
3
+ attr_accessor :method, :params, :body, :headers, :connect_timeout, :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, :verbose, :username, :password,
4
+ :auth_method
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
+ # ** +:connect_timeout+ : connect timeout (ms)
18
+ # ** +:headers+ : headers as Hash
19
+ # ** +:user_agent+ : user agent (string)
20
+ # ** +:cache_timeout+ : cache timeout (ms)
21
+ # ** +:follow_location
22
+ # ** +:max_redirects
23
+ # ** +:proxy
24
+ # ** +:disable_ssl_peer_verification
25
+ # ** +:ssl_cert
26
+ # ** +:ssl_cert_type
27
+ # ** +:ssl_key
28
+ # ** +:ssl_key_type
29
+ # ** +:ssl_key_password
30
+ # ** +:ssl_cacert
31
+ # ** +:ssl_capath
32
+ # ** +:verbose
33
+ # ** +:username
34
+ # ** +:password
35
+ # ** +:auth_method
36
+ #
6
37
  def initialize(url, options = {})
7
38
  @method = options[:method] || :get
8
39
  @params = options[:params]
9
40
  @body = options[:body]
10
41
  @timeout = options[:timeout]
42
+ @connect_timeout = options[:connect_timeout]
11
43
  @headers = options[:headers] || {}
12
44
  @user_agent = options[:user_agent] || Typhoeus::USER_AGENT
13
45
  @cache_timeout = options[:cache_timeout]
@@ -15,6 +47,17 @@ module Typhoeus
15
47
  @max_redirects = options[:max_redirects]
16
48
  @proxy = options[:proxy]
17
49
  @disable_ssl_peer_verification = options[:disable_ssl_peer_verification]
50
+ @ssl_cert = options[:ssl_cert]
51
+ @ssl_cert_type = options[:ssl_cert_type]
52
+ @ssl_key = options[:ssl_key]
53
+ @ssl_key_type = options[:ssl_key_type]
54
+ @ssl_key_password = options[:ssl_key_password]
55
+ @ssl_cacert = options[:ssl_cacert]
56
+ @ssl_capath = options[:ssl_capath]
57
+ @verbose = options[:verbose]
58
+ @username = options[:username]
59
+ @password = options[:password]
60
+ @auth_method = options[:auth_method]
18
61
 
19
62
  if @method == :post
20
63
  @url = url
@@ -42,7 +85,7 @@ module Typhoeus
42
85
  end
43
86
 
44
87
  def params_string
45
- params.keys.sort.collect do |k|
88
+ params.keys.sort { |a, b| a.to_s <=> b.to_s }.collect do |k|
46
89
  value = params[k]
47
90
  if value.is_a? Hash
48
91
  value.keys.collect {|sk| Rack::Utils.escape("#{k}[#{sk}]") + "=" + Rack::Utils.escape(value[sk].to_s)}
@@ -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,8 +15,9 @@ 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]
17
19
  end
18
-
20
+
19
21
  def headers_hash
20
22
  headers.split("\n").map {|o| o.strip}.inject({}) do |hash, o|
21
23
  if o.empty?
@@ -30,16 +32,16 @@ module Typhoeus
30
32
  else
31
33
  hash[key] = value
32
34
  end
33
-
35
+
34
36
  hash
35
37
  end
36
38
  end
37
39
  end
38
-
40
+
39
41
  def success?
40
42
  @code >= 200 && @code < 300
41
43
  end
42
-
44
+
43
45
  def modified?
44
46
  @code != 304
45
47
  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,7 +14,7 @@ require 'typhoeus/request'
14
14
  require 'typhoeus/hydra'
15
15
 
16
16
  module Typhoeus
17
- VERSION = "0.1.24"
17
+ VERSION = File.read(File.dirname(__FILE__) + "/../VERSION").chomp
18
18
 
19
19
  def self.easy_object_pool
20
20
  @easy_objects ||= []
@@ -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
@@ -2,6 +2,7 @@
2
2
  require 'rubygems'
3
3
  require 'sinatra'
4
4
  require 'json'
5
+ require 'zlib'
5
6
 
6
7
  @@fail_count = 0
7
8
  get '/fail/:number' do
@@ -43,11 +44,21 @@ get '/auth_ntlm' do
43
44
  # we're just checking for the existence if NTLM auth header here. It's validation
44
45
  # is too troublesome and really doesn't bother is much, it's up to libcurl to make
45
46
  # it valid
47
+ response['WWW-Authenticate'] = 'NTLM'
46
48
  is_ntlm_auth = /^NTLM/ =~ request.env['HTTP_AUTHORIZATION']
47
49
  true if is_ntlm_auth
48
50
  throw(:halt, [401, "Not authorized\n"]) if !is_ntlm_auth
49
51
  end
50
52
 
53
+ get '/gzipped' do
54
+ req_env = request.env.to_json
55
+ z = Zlib::Deflate.new
56
+ gzipped_env = z.deflate(req_env, Zlib::FINISH)
57
+ z.close
58
+ response['Content-Encoding'] = 'gzip'
59
+ gzipped_env
60
+ end
61
+
51
62
  get '/**' do
52
63
  sleep params["delay"].to_i if params.has_key?("delay")
53
64
  request.env.merge!(:body => request.body.read).to_json
@@ -1,6 +1,22 @@
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
21
  it "should not follow redirects if not instructed to" do
6
22
  e = Typhoeus::Easy.new
@@ -101,6 +117,14 @@ describe Typhoeus::Easy do
101
117
  end
102
118
  end
103
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
+
104
128
  describe "head" do
105
129
  it "should perform a head" do
106
130
  easy = Typhoeus::Easy.new
@@ -208,5 +232,18 @@ describe Typhoeus::Easy do
208
232
  easy.response_code.should == 200
209
233
  easy.response_body.should include("this is a body!")
210
234
  end
211
- end
235
+ end
236
+
237
+ describe "encoding/compression support" do
238
+
239
+ it "should send valid encoding headers and decode the response" do
240
+ easy = Typhoeus::Easy.new
241
+ easy.url = "http://localhost:3002/gzipped"
242
+ easy.method = :get
243
+ easy.perform
244
+ easy.response_code.should == 200
245
+ JSON.parse(easy.response_body)["HTTP_ACCEPT_ENCODING"].should == "deflate, gzip"
246
+ end
247
+
248
+ end
212
249
  end