typhoeus 1.6.0 → 1.7.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +217 -1
  3. data/README.md +338 -160
  4. data/UPGRADE.md +29 -0
  5. data/lib/rack/typhoeus/middleware/params_decoder/helper.rb +67 -14
  6. data/lib/rack/typhoeus/middleware/params_decoder.rb +8 -19
  7. data/lib/rack/typhoeus.rb +2 -0
  8. data/lib/typhoeus/adapters/faraday.rb +89 -28
  9. data/lib/typhoeus/cache/dalli.rb +2 -0
  10. data/lib/typhoeus/cache/rails.rb +3 -1
  11. data/lib/typhoeus/cache/redis.rb +2 -0
  12. data/lib/typhoeus/config.rb +51 -7
  13. data/lib/typhoeus/easy_factory.rb +129 -23
  14. data/lib/typhoeus/errors/invalid_option.rb +23 -0
  15. data/lib/typhoeus/errors/no_response.rb +18 -0
  16. data/lib/typhoeus/errors/no_stub.rb +8 -1
  17. data/lib/typhoeus/errors/typhoeus_error.rb +2 -0
  18. data/lib/typhoeus/errors.rb +4 -0
  19. data/lib/typhoeus/expectation.rb +33 -1
  20. data/lib/typhoeus/hydra/queueable.rb +29 -4
  21. data/lib/typhoeus/hydra.rb +349 -21
  22. data/lib/typhoeus/pool.rb +80 -17
  23. data/lib/typhoeus/railtie.rb +4 -2
  24. data/lib/typhoeus/request/actions.rb +2 -0
  25. data/lib/typhoeus/request/callbacks.rb +11 -4
  26. data/lib/typhoeus/request/marshal.rb +5 -2
  27. data/lib/typhoeus/request/streamable.rb +2 -0
  28. data/lib/typhoeus/request.rb +317 -30
  29. data/lib/typhoeus/response/cacheable.rb +2 -0
  30. data/lib/typhoeus/response/header.rb +234 -14
  31. data/lib/typhoeus/response/informations.rb +75 -12
  32. data/lib/typhoeus/response/status.rb +4 -13
  33. data/lib/typhoeus/response.rb +35 -0
  34. data/lib/typhoeus/version.rb +3 -1
  35. data/lib/typhoeus.rb +89 -26
  36. data/typhoeus.gemspec +15 -3
  37. metadata +19 -22
  38. data/lib/typhoeus/hydra/addable.rb +0 -23
  39. data/lib/typhoeus/hydra/before.rb +0 -31
  40. data/lib/typhoeus/hydra/block_connection.rb +0 -35
  41. data/lib/typhoeus/hydra/cacheable.rb +0 -15
  42. data/lib/typhoeus/hydra/memoizable.rb +0 -56
  43. data/lib/typhoeus/hydra/runnable.rb +0 -19
  44. data/lib/typhoeus/hydra/stubbable.rb +0 -28
  45. data/lib/typhoeus/request/before.rb +0 -30
  46. data/lib/typhoeus/request/block_connection.rb +0 -52
  47. data/lib/typhoeus/request/cacheable.rb +0 -38
  48. data/lib/typhoeus/request/memoizable.rb +0 -38
  49. data/lib/typhoeus/request/operations.rb +0 -40
  50. data/lib/typhoeus/request/responseable.rb +0 -29
  51. data/lib/typhoeus/request/stubbable.rb +0 -30
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Typhoeus
2
4
  class Response
3
5
 
@@ -27,6 +29,17 @@ module Typhoeus
27
29
  Ethon::Curl.easy_strerror(return_code) if return_code
28
30
  end
29
31
 
32
+ # Returns the detailed error message from libcurl's error buffer,
33
+ # only available when the request was made with errorbuffer: true.
34
+ #
35
+ # @example Get error_message.
36
+ # response.error_message
37
+ #
38
+ # @return [ String, nil ] The error_message.
39
+ def error_message
40
+ options[:error_message]
41
+ end
42
+
30
43
  # Return the http response body.
31
44
  #
32
45
  # @example Get response_body.
@@ -34,7 +47,8 @@ module Typhoeus
34
47
  #
35
48
  # @return [ String ] The response_body.
36
49
  def response_body
37
- options[:response_body] || options[:body]
50
+ body = options[:response_body] || options[:body]
51
+ apply_content_type_charset(body)
38
52
  end
39
53
  alias :body :response_body
40
54
 
@@ -47,13 +61,13 @@ module Typhoeus
47
61
  def response_headers
48
62
  return options[:response_headers] if options[:response_headers]
49
63
  if mock? && h = options[:headers]
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}" }
64
+ status_code = options[:response_code] || options[:code] || 200
65
+ reason_phrase = status_code.to_i == 200 ? "OK" : "Mock Reason Phrase"
66
+ status_line = "HTTP/1.1 #{status_code} #{reason_phrase}"
67
+ actual_headers = h.map{ |k,v| [k, v.respond_to?(:join) ? v.join(',') : v] }.
68
+ map{ |e| "#{e.first}: #{e.last}" }
55
69
 
56
- [status_line, *actual_headers].join("\r\n")
70
+ [status_line, *actual_headers].join("\r\n")
57
71
  end
58
72
  end
59
73
 
@@ -67,7 +81,14 @@ module Typhoeus
67
81
  #
68
82
  # @return [ Integer ] The response_code.
69
83
  def response_code
70
- (options[:response_code] || options[:code]).to_i
84
+ code = options[:response_code] || options[:code]
85
+ return code.to_i unless code.nil?
86
+
87
+ # A response built from raw headers, such as one returned by
88
+ # #redirections, has no option describing the status.
89
+ line = first_header_line
90
+ status = line && line[/\AHTTP\/\S+\s+(\d{3})/, 1]
91
+ status ? status.to_i : 0
71
92
  end
72
93
  alias :code :response_code
73
94
 
@@ -282,9 +303,9 @@ module Typhoeus
282
303
  #
283
304
  # @return [ Typhoeus::Header ] The response header.
284
305
  def headers
285
- return Header.new(options[:headers]) if mock? && options[:headers]
286
- return nil if response_headers.nil? && !defined?(@headers)
287
- @headers ||= Header.new(response_headers.split("\r\n\r\n").last)
306
+ return @headers if defined?(@headers) && @headers
307
+ return nil if response_headers.nil?
308
+ @headers = Header.new(last_response_block)
288
309
  end
289
310
  alias :headers_hash :headers
290
311
 
@@ -297,7 +318,49 @@ module Typhoeus
297
318
  # @return [ Array<Typhoeus::Response> ] The redirections
298
319
  def redirections
299
320
  return [] unless response_headers
300
- response_headers.split("\r\n\r\n")[0..-2].map{ |h| Response.new(:response_headers => h) }
321
+
322
+ http_blocks = response_blocks.select { |block| block.start_with?("HTTP/") }
323
+ blocks = http_blocks.empty? ? response_blocks[0..-2] : http_blocks[0..-2]
324
+ blocks.map { |header| Response.new(:response_headers => header) }
325
+ end
326
+
327
+ private
328
+
329
+ # Split the raw response headers into their header blocks.
330
+ #
331
+ # @return [ Array<String> ] The blocks.
332
+ def response_blocks
333
+ response_headers.to_s.split("\r\n\r\n")
334
+ end
335
+
336
+ # Return the last block that starts a new response. HTTP/1.1 trailers
337
+ # add a block without a status line after the response headers.
338
+ #
339
+ # @return [ String ] The response block.
340
+ def last_response_block
341
+ http_blocks = response_blocks.select { |block| block.start_with?("HTTP/") }
342
+ (http_blocks.empty? ? response_blocks.last : http_blocks.last).to_s
343
+ end
344
+
345
+ # Force the body to the charset advertised by the Content-Type
346
+ # header, but leave binary and already encoded bodies alone.
347
+ #
348
+ # @param [ String, nil ] body The response body.
349
+ #
350
+ # @return [ String, nil ] The response body.
351
+ def apply_content_type_charset(body)
352
+ return body unless body.is_a?(String) && !body.frozen?
353
+ return body unless body.encoding == Encoding::BINARY
354
+
355
+ content_type = headers && headers["Content-Type"]
356
+ return body unless content_type
357
+
358
+ charset = content_type.to_s[/;\s*charset\s*=\s*["']?([^"';,\s]+)/i, 1]
359
+ return body unless charset
360
+
361
+ body.force_encoding(Encoding.find(charset))
362
+ rescue ArgumentError
363
+ body
301
364
  end
302
365
  end
303
366
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Typhoeus
2
4
  class Response
3
5
 
@@ -56,7 +58,7 @@ module Typhoeus
56
58
  #
57
59
  # @return [ Boolean ] Return true if failure, false else.
58
60
  def failure?
59
- (mock || return_code == :internal_server_error) && response_code && has_bad_response_code?
61
+ (mock || !return_code.nil?) && !success?
60
62
  end
61
63
 
62
64
  # Return wether the response is modified.
@@ -83,24 +85,13 @@ module Typhoeus
83
85
 
84
86
  # :nodoc:
85
87
  def first_header_line
86
- @first_header_line ||= begin
87
- if response_headers.to_s.include?("\r\n\r\n")
88
- response_headers.to_s.split("\r\n\r\n").last.split("\r\n").first
89
- else
90
- response_headers.to_s.split("\r\n").first
91
- end
92
- end
88
+ @first_header_line ||= last_response_block.split("\r\n").first
93
89
  end
94
90
 
95
91
  # :nodoc:
96
92
  def has_good_response_code?
97
93
  response_code >= 200 && response_code < 300
98
94
  end
99
-
100
- # :nodoc:
101
- def has_bad_response_code?
102
- !has_good_response_code?
103
- end
104
95
  end
105
96
  end
106
97
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'typhoeus/response/header'
2
4
  require 'typhoeus/response/informations'
3
5
  require 'typhoeus/response/status'
@@ -47,6 +49,20 @@ module Typhoeus
47
49
  @headers = Header.new(options[:headers]) if options[:headers]
48
50
  end
49
51
 
52
+ # Keep duplicated responses independent. Memoization hands a copy of the
53
+ # leader's response to every follower, so shared options, headers, bodies,
54
+ # or callback results would let one request change another one's response.
55
+ def initialize_copy(other)
56
+ super
57
+ @options = duplicate_value(other.options)
58
+ @handled_response = nil
59
+ if other.instance_variable_defined?(:@headers)
60
+ headers = other.instance_variable_get(:@headers)
61
+ @headers = headers.dup if headers
62
+ end
63
+ end
64
+ private :initialize_copy
65
+
50
66
  # Returns whether this request is mocked
51
67
  # or not.
52
68
  #
@@ -64,5 +80,24 @@ module Typhoeus
64
80
  def handled_response
65
81
  @handled_response || self
66
82
  end
83
+
84
+ private
85
+
86
+ # Duplicate the mutable containers a response may share with its copy.
87
+ # Other option values are opaque and are left alone.
88
+ def duplicate_value(value)
89
+ case value
90
+ when Hash
91
+ value.each_with_object({}) do |(key, nested), copy|
92
+ copy[duplicate_value(key)] = duplicate_value(nested)
93
+ end
94
+ when Array
95
+ value.map { |nested| duplicate_value(nested) }
96
+ when String
97
+ value.dup
98
+ else
99
+ value
100
+ end
101
+ end
67
102
  end
68
103
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Typhoeus
2
4
 
3
5
  # The current Typhoeus version.
4
- VERSION = '1.6.0'
6
+ VERSION = '1.7.0'
5
7
  end
data/lib/typhoeus.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest/sha2'
2
4
  require 'ethon'
3
5
 
@@ -11,26 +13,19 @@ require 'typhoeus/request'
11
13
  require 'typhoeus/response'
12
14
  require 'typhoeus/version'
13
15
 
14
- # If we are using any Rack-based application, then we need the Typhoeus rack
15
- # middleware to ensure our app is running properly.
16
- if defined?(Rack)
16
+ # Load the optional integrations when their dependency is installed, not when
17
+ # the dependency happens to be loaded before Typhoeus. Requiring the adapter
18
+ # files is safe because they only reference the dependency at call time.
19
+ begin
20
+ require "rack"
17
21
  require "rack/typhoeus"
22
+ rescue LoadError
23
+ # Rack is optional.
18
24
  end
19
25
 
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
26
+ require "typhoeus/cache/redis"
27
+ require "typhoeus/cache/dalli"
28
+ require "typhoeus/cache/rails"
34
29
 
35
30
  # If we are using Rails, then we will include the Typhoeus railtie.
36
31
  # if defined?(Rails)
@@ -114,8 +109,29 @@ module Typhoeus
114
109
  @before
115
110
  end
116
111
 
112
+ # Returns the callbacks that run before a request. Returns nil when before
113
+ # callbacks are skipped or when there are none, so the common path does not
114
+ # allocate a callback array.
115
+ #
116
+ # @param [ Typhoeus::Request ] request The request that is about to run.
117
+ #
118
+ # @return [ Array<Proc>, nil ] The callbacks or nil.
119
+ #
120
+ # @api private
121
+ def self.before_callbacks_for(request)
122
+ return unless Config.feature_enabled?(:before)
123
+
124
+ global = before
125
+ local = request.before
126
+ return if global.empty? && local.empty?
127
+
128
+ global + local
129
+ end
130
+
117
131
  # Execute given block as if block connection is turned off.
118
- # The old block connection state is restored afterwards.
132
+ # The old block connection state is restored afterwards. Stubs are bypassed
133
+ # inside the block, so a stub can forward to the real service without
134
+ # recursing into itself.
119
135
  #
120
136
  # @example Make a real request, no matter if it's blocked.
121
137
  # Typhoeus::Config.block_connection = true
@@ -127,17 +143,64 @@ module Typhoeus
127
143
  # #=> :ok
128
144
  # end
129
145
  #
130
- # @yield Yields control to the block after disabling block_connection.
131
- # Afterwards, the block_connection is set to its original
132
- # value.
146
+ # @example Let one stubbed URL reach the real service.
147
+ # Typhoeus.stub("http://elastic:9200") do |request|
148
+ # Typhoeus.with_connection { request.run }
149
+ # end
150
+ #
151
+ # @yield Yields control to the block after disabling block_connection for
152
+ # the current thread. Other threads keep their block_connection
153
+ # setting.
133
154
  # @return [ Object ] Returns the return value of the block.
134
155
  #
135
156
  # @see Typhoeus::Config.block_connection
136
157
  def self.with_connection
137
- old = Config.block_connection
138
- Config.block_connection = false
139
- result = yield if block_given?
140
- Config.block_connection = old
141
- result
158
+ # Fibers on the same thread share the override. Save the previous values
159
+ # when the outermost call enters and restore them only when the last call
160
+ # leaves, so a fiber that finishes while another is still inside the block
161
+ # does not clear it.
162
+ depth = Thread.current.thread_variable_get(:typhoeus_connection_depth).to_i
163
+ if depth.zero?
164
+ Thread.current.thread_variable_set(
165
+ :typhoeus_previous_connection,
166
+ [Thread.current.thread_variable_get(:typhoeus_block_connection),
167
+ Thread.current.thread_variable_get(:typhoeus_stubs_disabled)]
168
+ )
169
+ end
170
+ Thread.current.thread_variable_set(:typhoeus_connection_depth, depth + 1)
171
+ Thread.current.thread_variable_set(:typhoeus_block_connection, false)
172
+ Thread.current.thread_variable_set(:typhoeus_stubs_disabled, true)
173
+ yield if block_given?
174
+ ensure
175
+ depth = Thread.current.thread_variable_get(:typhoeus_connection_depth).to_i - 1
176
+ Thread.current.thread_variable_set(:typhoeus_connection_depth, depth)
177
+ if depth.zero?
178
+ old_block_connection, old_stubs_disabled =
179
+ Thread.current.thread_variable_get(:typhoeus_previous_connection)
180
+ Thread.current.thread_variable_set(:typhoeus_block_connection, old_block_connection)
181
+ Thread.current.thread_variable_set(:typhoeus_stubs_disabled, old_stubs_disabled)
182
+ Thread.current.thread_variable_set(:typhoeus_previous_connection, nil)
183
+ end
184
+ end
185
+
186
+ # Whether connections are blocked for the current thread. The override is
187
+ # thread-local so {with_connection} cannot unblock another thread.
188
+ #
189
+ # @api private
190
+ #
191
+ # @return [ Boolean, nil ] The configured value, or the thread override.
192
+ def self.connection_blocked?
193
+ override = Thread.current.thread_variable_get(:typhoeus_block_connection)
194
+ override.nil? ? Config.block_connection : override
195
+ end
196
+
197
+ # Whether the current thread is inside {with_connection} and therefore
198
+ # bypasses stubs.
199
+ #
200
+ # @api private
201
+ #
202
+ # @return [ Boolean ] True when stubs should be skipped.
203
+ def self.stubs_disabled?
204
+ Thread.current.thread_variable_get(:typhoeus_stubs_disabled)
142
205
  end
143
206
  end
data/typhoeus.gemspec CHANGED
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  lib = File.expand_path('../lib/', __FILE__)
3
4
  $:.unshift lib unless $:.include?(lib)
4
5
 
@@ -24,10 +25,21 @@ Gem::Specification.new do |s|
24
25
  'source_code_uri' => "https://github.com/typhoeus/typhoeus/tree/v#{s.version}"
25
26
  }
26
27
 
27
- s.add_dependency('ethon', [">= 0.18.0"])
28
+ s.add_dependency('ethon', [">= 0.19.0", "< 0.20.0"])
28
29
 
29
30
  s.files = Dir.chdir(__dir__) do
30
- `git ls-files -z`.split("\x0").reject do |file|
31
+ files = begin
32
+ IO.popen(["git", "ls-files", "-z"], :err => File::NULL, &:read).split("\x0")
33
+ rescue SystemCallError
34
+ []
35
+ end
36
+ # Building from a source tarball or a container without git must still
37
+ # produce a working gem.
38
+ if files.empty?
39
+ files = Dir["lib/**/*", "*.md", "LICENSE", "typhoeus.gemspec"].
40
+ select { |file| File.file?(file) }
41
+ end
42
+ files.reject do |file|
31
43
  file.start_with?(*%w[. Gemfile Guardfile Rakefile perf spec])
32
44
  end
33
45
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typhoeus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Balatero
8
8
  - Paul Dix
9
9
  - Hans Hasselberg
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 1980-01-02 00:00:00.000000000 Z
13
+ date: 2026-10-28 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: ethon
@@ -17,14 +18,20 @@ dependencies:
17
18
  requirements:
18
19
  - - ">="
19
20
  - !ruby/object:Gem::Version
20
- version: 0.18.0
21
+ version: 0.19.0
22
+ - - "<"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.20.0
21
25
  type: :runtime
22
26
  prerelease: false
23
27
  version_requirements: !ruby/object:Gem::Requirement
24
28
  requirements:
25
29
  - - ">="
26
30
  - !ruby/object:Gem::Version
27
- version: 0.18.0
31
+ version: 0.19.0
32
+ - - "<"
33
+ - !ruby/object:Gem::Version
34
+ version: 0.20.0
28
35
  description: Like a modern code version of the mythical beast with 100 serpent heads,
29
36
  Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic.
30
37
  email:
@@ -49,32 +56,20 @@ files:
49
56
  - lib/typhoeus/config.rb
50
57
  - lib/typhoeus/easy_factory.rb
51
58
  - lib/typhoeus/errors.rb
59
+ - lib/typhoeus/errors/invalid_option.rb
60
+ - lib/typhoeus/errors/no_response.rb
52
61
  - lib/typhoeus/errors/no_stub.rb
53
62
  - lib/typhoeus/errors/typhoeus_error.rb
54
63
  - lib/typhoeus/expectation.rb
55
64
  - lib/typhoeus/hydra.rb
56
- - lib/typhoeus/hydra/addable.rb
57
- - lib/typhoeus/hydra/before.rb
58
- - lib/typhoeus/hydra/block_connection.rb
59
- - lib/typhoeus/hydra/cacheable.rb
60
- - lib/typhoeus/hydra/memoizable.rb
61
65
  - lib/typhoeus/hydra/queueable.rb
62
- - lib/typhoeus/hydra/runnable.rb
63
- - lib/typhoeus/hydra/stubbable.rb
64
66
  - lib/typhoeus/pool.rb
65
67
  - lib/typhoeus/railtie.rb
66
68
  - lib/typhoeus/request.rb
67
69
  - lib/typhoeus/request/actions.rb
68
- - lib/typhoeus/request/before.rb
69
- - lib/typhoeus/request/block_connection.rb
70
- - lib/typhoeus/request/cacheable.rb
71
70
  - lib/typhoeus/request/callbacks.rb
72
71
  - lib/typhoeus/request/marshal.rb
73
- - lib/typhoeus/request/memoizable.rb
74
- - lib/typhoeus/request/operations.rb
75
- - lib/typhoeus/request/responseable.rb
76
72
  - lib/typhoeus/request/streamable.rb
77
- - lib/typhoeus/request/stubbable.rb
78
73
  - lib/typhoeus/response.rb
79
74
  - lib/typhoeus/response/cacheable.rb
80
75
  - lib/typhoeus/response/header.rb
@@ -87,10 +82,11 @@ licenses:
87
82
  - MIT
88
83
  metadata:
89
84
  bug_tracker_uri: https://github.com/typhoeus/typhoeus/issues
90
- changelog_uri: https://github.com/typhoeus/typhoeus/blob/v1.6.0/CHANGELOG.md
91
- documentation_uri: https://www.rubydoc.info/gems/typhoeus/1.6.0
85
+ changelog_uri: https://github.com/typhoeus/typhoeus/blob/v1.7.0/CHANGELOG.md
86
+ documentation_uri: https://www.rubydoc.info/gems/typhoeus/1.7.0
92
87
  rubygems_mfa_required: 'true'
93
- source_code_uri: https://github.com/typhoeus/typhoeus/tree/v1.6.0
88
+ source_code_uri: https://github.com/typhoeus/typhoeus/tree/v1.7.0
89
+ post_install_message:
94
90
  rdoc_options: []
95
91
  require_paths:
96
92
  - lib
@@ -105,7 +101,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
101
  - !ruby/object:Gem::Version
106
102
  version: '0'
107
103
  requirements: []
108
- rubygems_version: 4.0.3
104
+ rubygems_version: 3.4.19
105
+ signing_key:
109
106
  specification_version: 4
110
107
  summary: Parallel HTTP library on top of libcurl multi.
111
108
  test_files: []
@@ -1,23 +0,0 @@
1
- module Typhoeus
2
- class Hydra
3
-
4
- # This module handles the request adding on
5
- # hydra.
6
- #
7
- # @api private
8
- module Addable
9
-
10
- # Adds request to multi.
11
- #
12
- # @example Add request.
13
- # hydra.add(request)
14
- #
15
- # @param [ Typhoeus::Request ] request to add.
16
- #
17
- # @return [ void ]
18
- def add(request)
19
- multi.add(EasyFactory.new(request, self).get)
20
- end
21
- end
22
- end
23
- end
@@ -1,31 +0,0 @@
1
- module Typhoeus
2
- class Hydra
3
-
4
- # This module provides a way to hook into before
5
- # a request gets queued in hydra. This is very powerful
6
- # and you should be careful because when you accidently
7
- # return a falsy value the request won't be executed.
8
- #
9
- # @api private
10
- module Before
11
-
12
- # Overrride add in order to execute callbacks in
13
- # Typhoeus.before. Will break and return when a
14
- # callback returns nil, false or a response. Calls super
15
- # otherwise.
16
- #
17
- # @example Add the request.
18
- # hydra.add(request)
19
- def add(request)
20
- Typhoeus.before.each do |callback|
21
- value = callback.call(request)
22
- if value.nil? || value == false || value.is_a?(Response)
23
- dequeue
24
- return value
25
- end
26
- end
27
- super
28
- end
29
- end
30
- end
31
- end
@@ -1,35 +0,0 @@
1
- module Typhoeus
2
- class Hydra
3
-
4
- # This module handles the blocked connection request mode on
5
- # the hydra side, where only stubbed requests
6
- # are allowed.
7
- # Connection blocking needs to be turned on:
8
- # Typhoeus.configure do |config|
9
- # config.block_connection = true
10
- # end
11
- #
12
- # When trying to do real requests a NoStub error
13
- # is raised.
14
- #
15
- # @api private
16
- module BlockConnection
17
-
18
- # Overrides add in order to check before if block connection
19
- # is turned on. If thats the case a NoStub error is
20
- # raised.
21
- #
22
- # @example Add the request.
23
- # hydra.add(request)
24
- #
25
- # @param [ Request ] request The request to enqueue.
26
- def add(request)
27
- if request.blocked?
28
- raise Typhoeus::Errors::NoStub.new(request)
29
- else
30
- super
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,15 +0,0 @@
1
- module Typhoeus
2
- class Hydra
3
- module Cacheable
4
- def add(request)
5
- if request.cacheable? && response = request.cached_response
6
- response.cached = true
7
- request.finish(response)
8
- dequeue
9
- else
10
- super
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,56 +0,0 @@
1
- module Typhoeus
2
- class Hydra
3
-
4
- # This module handles the GET request memoization
5
- # on the hydra side. Memoization needs to be turned
6
- # on:
7
- # Typhoeus.configure do |config|
8
- # config.memoize = true
9
- # end
10
- #
11
- # @api private
12
- module Memoizable
13
-
14
- # Return the memory.
15
- #
16
- # @example Return the memory.
17
- # hydra.memory
18
- #
19
- # @return [ Hash ] The memory.
20
- def memory
21
- @memory ||= {}
22
- end
23
-
24
- # Overrides add in order to check before if request
25
- # is memoizable and already in memory. If thats the case,
26
- # super is not called, instead the response is set and
27
- # the on_complete callback called.
28
- #
29
- # @example Add the request.
30
- # hydra.add(request)
31
- #
32
- # @param [ Request ] request The request to add.
33
- #
34
- # @return [ Request ] The added request.
35
- def add(request)
36
- if request.memoizable? && memory.has_key?(request)
37
- response = memory[request]
38
- request.finish(response, true)
39
- dequeue
40
- else
41
- super
42
- end
43
- end
44
-
45
- # Overrides run to make sure the memory is cleared after
46
- # each run.
47
- #
48
- # @example Run hydra.
49
- # hydra.run
50
- def run
51
- super
52
- memory.clear
53
- end
54
- end
55
- end
56
- end