typhoeus 1.0.1 → 1.4.0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -7
  3. data/CHANGELOG.md +34 -2
  4. data/CONTRIBUTING.md +4 -0
  5. data/Gemfile +14 -3
  6. data/LICENSE +1 -1
  7. data/README.md +67 -42
  8. data/lib/typhoeus/adapters/faraday.rb +30 -9
  9. data/lib/typhoeus/cache/dalli.rb +28 -0
  10. data/lib/typhoeus/cache/rails.rb +28 -0
  11. data/lib/typhoeus/cache/redis.rb +35 -0
  12. data/lib/typhoeus/config.rb +8 -1
  13. data/lib/typhoeus/easy_factory.rb +8 -3
  14. data/lib/typhoeus/hydra/cacheable.rb +1 -1
  15. data/lib/typhoeus/pool.rb +2 -0
  16. data/lib/typhoeus/request/actions.rb +7 -7
  17. data/lib/typhoeus/request/cacheable.rb +14 -3
  18. data/lib/typhoeus/request/callbacks.rb +21 -3
  19. data/lib/typhoeus/request/marshal.rb +2 -2
  20. data/lib/typhoeus/request/streamable.rb +1 -1
  21. data/lib/typhoeus/request.rb +2 -0
  22. data/lib/typhoeus/response/header.rb +13 -5
  23. data/lib/typhoeus/response/informations.rb +7 -3
  24. data/lib/typhoeus/response/status.rb +22 -2
  25. data/lib/typhoeus/response.rb +1 -1
  26. data/lib/typhoeus/version.rb +1 -1
  27. data/lib/typhoeus.rb +19 -3
  28. data/spec/support/server.rb +8 -0
  29. data/spec/typhoeus/adapters/faraday_spec.rb +237 -191
  30. data/spec/typhoeus/cache/dalli_spec.rb +41 -0
  31. data/spec/typhoeus/cache/redis_spec.rb +41 -0
  32. data/spec/typhoeus/config_spec.rb +1 -1
  33. data/spec/typhoeus/easy_factory_spec.rb +6 -0
  34. data/spec/typhoeus/hydra/before_spec.rb +9 -8
  35. data/spec/typhoeus/hydra/cacheable_spec.rb +31 -1
  36. data/spec/typhoeus/hydra/runnable_spec.rb +4 -3
  37. data/spec/typhoeus/pool_spec.rb +43 -2
  38. data/spec/typhoeus/request/before_spec.rb +9 -8
  39. data/spec/typhoeus/request/cacheable_spec.rb +24 -0
  40. data/spec/typhoeus/request/callbacks_spec.rb +2 -2
  41. data/spec/typhoeus/request/marshal_spec.rb +1 -1
  42. data/spec/typhoeus/request_spec.rb +21 -3
  43. data/spec/typhoeus/response/header_spec.rb +51 -1
  44. data/spec/typhoeus/response/informations_spec.rb +12 -1
  45. data/spec/typhoeus/response/status_spec.rb +54 -0
  46. data/typhoeus.gemspec +1 -1
  47. metadata +12 -5
@@ -89,6 +89,24 @@ module Typhoeus
89
89
  @on_headers << block if block_given?
90
90
  @on_headers
91
91
  end
92
+
93
+ # Set on_progress callback.
94
+ #
95
+ # @example Set on_progress.
96
+ # request.on_progress do |dltotal, dlnow, ultotal, ulnow|
97
+ # puts "dltotal (#{dltotal}), dlnow (#{dlnow}), ultotal (#{ultotal}), ulnow (#{ulnow})"
98
+ # end
99
+ #
100
+ # @param [ Block ] block The block to execute.
101
+ #
102
+ # @yield [ Typhoeus::Response ]
103
+ #
104
+ # @return [ Array<Block> ] All on_progress blocks.
105
+ def on_progress(&block)
106
+ @on_progress ||= []
107
+ @on_progress << block if block_given?
108
+ @on_progress
109
+ end
92
110
  end
93
111
 
94
112
  # Execute the headers callbacks and yields response.
@@ -106,8 +124,8 @@ module Typhoeus
106
124
  end
107
125
 
108
126
  # Execute necessary callback and yields response. This
109
- # include in every case on_complete, on_success if
110
- # successful and on_failure if not.
127
+ # include in every case on_complete and on_progress, on_success
128
+ # if successful and on_failure if not.
111
129
  #
112
130
  # @example Execute callbacks.
113
131
  # request.execute_callbacks
@@ -116,7 +134,7 @@ module Typhoeus
116
134
  #
117
135
  # @api private
118
136
  def execute_callbacks
119
- callbacks = Typhoeus.on_complete + on_complete
137
+ callbacks = Typhoeus.on_complete + Typhoeus.on_progress + on_complete + on_progress
120
138
 
121
139
  if response && response.success?
122
140
  callbacks += Typhoeus.on_success + on_success
@@ -5,9 +5,9 @@ module Typhoeus
5
5
  module Marshal
6
6
 
7
7
  # Return the important data needed to serialize this Request, except the
8
- # `on_complete`, `on_success`, `on_failure`, and `hydra`, since they cannot be marshalled.
8
+ # request callbacks and `hydra`, since they cannot be marshalled.
9
9
  def marshal_dump
10
- unmarshallable = %w(@on_complete @on_success @on_failure @on_headers @on_body @hydra)
10
+ unmarshallable = %w(@on_complete @on_success @on_failure @on_progress @on_headers @on_body @hydra)
11
11
  (instance_variables - unmarshallable - unmarshallable.map(&:to_sym)).map do |name|
12
12
  [name, instance_variable_get(name)]
13
13
  end
@@ -10,7 +10,7 @@ module Typhoeus
10
10
  # Setting an on_body callback will cause the response body to be empty.
11
11
  #
12
12
  # @example Set on_body.
13
- # request.on_body { |response, body_chunk| puts "Got #{body_chunk.bytesize} bytes" }
13
+ # request.on_body { |body_chunk, response| puts "Got #{body_chunk.bytesize} bytes" }
14
14
  #
15
15
  # @param [ Block ] block The block to execute.
16
16
  #
@@ -212,8 +212,10 @@ module Typhoeus
212
212
  default_user_agent = Config.user_agent || Typhoeus::USER_AGENT
213
213
 
214
214
  options[:headers] = {'User-Agent' => default_user_agent}.merge(options[:headers] || {})
215
+ options[:headers]['Expect'] ||= ''
215
216
  options[:verbose] = Typhoeus::Config.verbose if options[:verbose].nil? && !Typhoeus::Config.verbose.nil?
216
217
  options[:maxredirs] ||= 50
218
+ options[:proxy] = Typhoeus::Config.proxy unless options.has_key?(:proxy) || Typhoeus::Config.proxy.nil?
217
219
  end
218
220
  end
219
221
  end
@@ -1,11 +1,14 @@
1
+ require 'delegate'
2
+
1
3
  module Typhoeus
2
4
  class Response
3
5
 
4
6
  # This class represents the response header.
5
7
  # It can be accessed like a hash.
8
+ # Values can be strings (normal case) or arrays of strings (for duplicates headers)
6
9
  #
7
10
  # @api private
8
- class Header < Hash
11
+ class Header < DelegateClass(Hash)
9
12
 
10
13
  # Create a new header.
11
14
  #
@@ -14,10 +17,14 @@ module Typhoeus
14
17
  #
15
18
  # @param [ String ] raw The raw header.
16
19
  def initialize(raw)
20
+ super({})
17
21
  @raw = raw
18
22
  @sanitized = {}
19
23
  parse
20
- set_default_proc_on(self, lambda { |h, k| @sanitized[k.to_s.downcase] })
24
+ end
25
+
26
+ def [](key)
27
+ fetch(key) { @sanitized[key.to_s.downcase] }
21
28
  end
22
29
 
23
30
  # Parses the raw header.
@@ -31,8 +38,9 @@ module Typhoeus
31
38
  process_pair(k, v)
32
39
  end
33
40
  when String
34
- raw.lines.each do |header|
35
- next if header.empty? || header.start_with?( 'HTTP/1.' )
41
+ raw.split(/\r?\n(?!\s)/).each do |header|
42
+ header.strip!
43
+ next if header.empty? || header.start_with?( 'HTTP/' )
36
44
  process_line(header)
37
45
  end
38
46
  end
@@ -45,7 +53,7 @@ module Typhoeus
45
53
  # @return [ void ]
46
54
  def process_line(header)
47
55
  key, value = header.split(':', 2)
48
- process_pair(key.strip, value.strip)
56
+ process_pair(key.strip, (value ? value.strip.gsub(/\r?\n\s*/, ' ') : ''))
49
57
  end
50
58
 
51
59
  # Sets key value pair for self and @sanitized.
@@ -47,9 +47,13 @@ module Typhoeus
47
47
  def response_headers
48
48
  return options[:response_headers] if options[:response_headers]
49
49
  if mock? && h = options[:headers]
50
- h.map{ |k,v| [k, v.respond_to?(:join) ? v.join : v] }.
51
- map{ |e| "#{e.first}: #{e.last}" }.
52
- join("\r\n")
50
+ status_code = return_code || "200"
51
+ reason_phrase = status_code == "200" ? "OK" : "Mock Reason Phrase"
52
+ status_line = "HTTP/1.1 #{status_code} #{reason_phrase}"
53
+ actual_headers = h.map{ |k,v| [k, v.respond_to?(:join) ? v.join(',') : v] }.
54
+ map{ |e| "#{e.first}: #{e.last}" }
55
+
56
+ [status_line, *actual_headers].join("\r\n")
53
57
  end
54
58
  end
55
59
 
@@ -39,14 +39,24 @@ module Typhoeus
39
39
  @http_version ||= first_header_line ? first_header_line[/HTTP\/(\S+)/, 1] : nil
40
40
  end
41
41
 
42
- # Return wether the response is a success.
42
+ # Return whether the response is a success.
43
43
  #
44
44
  # @example Return if the response was successful.
45
45
  # response.success?
46
46
  #
47
47
  # @return [ Boolean ] Return true if successful, false else.
48
48
  def success?
49
- (mock || return_code == :ok) && response_code && response_code >= 200 && response_code < 300
49
+ (mock || return_code == :ok) && response_code && has_good_response_code?
50
+ end
51
+
52
+ # Return whether the response is a failure.
53
+ #
54
+ # @example Return if the response was failed.
55
+ # response.failure?
56
+ #
57
+ # @return [ Boolean ] Return true if failure, false else.
58
+ def failure?
59
+ (mock || return_code == :internal_server_error) && response_code && has_bad_response_code?
50
60
  end
51
61
 
52
62
  # Return wether the response is modified.
@@ -81,6 +91,16 @@ module Typhoeus
81
91
  end
82
92
  end
83
93
  end
94
+
95
+ # :nodoc:
96
+ def has_good_response_code?
97
+ response_code >= 200 && response_code < 300
98
+ end
99
+
100
+ # :nodoc:
101
+ def has_bad_response_code?
102
+ !has_good_response_code?
103
+ end
84
104
  end
85
105
  end
86
106
  end
@@ -14,7 +14,7 @@ module Typhoeus
14
14
  # Remembers the corresponding request.
15
15
  #
16
16
  # @example Get request.
17
- # request = Typhoeus::Request.get("www.example.com")
17
+ # request = Typhoeus::Request.new("www.example.com")
18
18
  # response = request.run
19
19
  # request == response.request
20
20
  # #=> true
@@ -1,5 +1,5 @@
1
1
  module Typhoeus
2
2
 
3
3
  # The current Typhoeus version.
4
- VERSION = '1.0.1'
4
+ VERSION = '1.4.0'
5
5
  end
data/lib/typhoeus.rb CHANGED
@@ -17,6 +17,21 @@ if defined?(Rack)
17
17
  require "rack/typhoeus"
18
18
  end
19
19
 
20
+ # If the Redis gem is available, load the redis cache adapter
21
+ if defined?(Redis)
22
+ require "typhoeus/cache/redis"
23
+ end
24
+
25
+ # If the Dalli gem is available, load the Dalli cache adapter
26
+ if defined?(Dalli)
27
+ require "typhoeus/cache/dalli"
28
+ end
29
+
30
+ # If we are using Rails, load the Rails cache adapter
31
+ if defined?(Rails)
32
+ require "typhoeus/cache/rails"
33
+ end
34
+
20
35
  # If we are using Rails, then we will include the Typhoeus railtie.
21
36
  # if defined?(Rails)
22
37
  # require "typhoeus/railtie"
@@ -112,11 +127,12 @@ module Typhoeus
112
127
  # #=> :ok
113
128
  # end
114
129
  #
115
- # @param [ Block ] block The block to execute.
116
- #
130
+ # @yield Yields control to the block after disabling block_connection.
131
+ # Afterwards, the block_connection is set to its original
132
+ # value.
117
133
  # @return [ Object ] Returns the return value of the block.
118
134
  #
119
- # @see Typhoeus::Config#block_connection
135
+ # @see Typhoeus::Config.block_connection
120
136
  def self.with_connection
121
137
  old = Config.block_connection
122
138
  Config.block_connection = false
@@ -23,6 +23,14 @@ TESTSERVER = Sinatra.new do
23
23
  [200, { 'Set-Cookie' => %w[ foo bar ], 'Content-Type' => 'text/plain' }, ['']]
24
24
  end
25
25
 
26
+ get '/cookies-test' do
27
+ [200, { 'Set-Cookie' => %w(foo=bar bar=foo), 'Content-Type' => 'text/plain' }, ['']]
28
+ end
29
+
30
+ get '/cookies-test2' do
31
+ [200, { 'Set-Cookie' => %w(foo2=bar bar2=foo), 'Content-Type' => 'text/plain' }, ['']]
32
+ end
33
+
26
34
  get '/fail/:number' do
27
35
  if fail_count >= params[:number].to_i
28
36
  "ok"