typhoeus 1.0.1 → 1.4.0

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