typhoeus 0.4.2 → 0.5.0.rc

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 (57) hide show
  1. data/CHANGELOG.md +86 -28
  2. data/Gemfile +17 -1
  3. data/README.md +20 -422
  4. data/Rakefile +21 -12
  5. data/lib/typhoeus/config.rb +47 -0
  6. data/lib/typhoeus/errors/no_stub.rb +12 -0
  7. data/lib/typhoeus/errors/typhoeus_error.rb +8 -0
  8. data/lib/typhoeus/errors.rb +9 -0
  9. data/lib/typhoeus/expectation.rb +174 -0
  10. data/lib/typhoeus/hydra/before.rb +30 -0
  11. data/lib/typhoeus/hydra/block_connection.rb +35 -0
  12. data/lib/typhoeus/hydra/easy_factory.rb +79 -0
  13. data/lib/typhoeus/hydra/easy_pool.rb +42 -0
  14. data/lib/typhoeus/hydra/memoizable.rb +55 -0
  15. data/lib/typhoeus/hydra/queueable.rb +48 -0
  16. data/lib/typhoeus/hydra/runnable.rb +21 -0
  17. data/lib/typhoeus/hydra/stubbable.rb +26 -0
  18. data/lib/typhoeus/hydra.rb +83 -236
  19. data/lib/typhoeus/request/actions.rb +125 -0
  20. data/lib/typhoeus/request/before.rb +30 -0
  21. data/lib/typhoeus/request/block_connection.rb +52 -0
  22. data/lib/typhoeus/request/callbacks.rb +98 -0
  23. data/lib/typhoeus/request/marshal.rb +21 -0
  24. data/lib/typhoeus/request/memoizable.rb +38 -0
  25. data/lib/typhoeus/request/operations.rb +71 -0
  26. data/lib/typhoeus/request/responseable.rb +29 -0
  27. data/lib/typhoeus/request/stubbable.rb +28 -0
  28. data/lib/typhoeus/request.rb +144 -241
  29. data/lib/typhoeus/response/header.rb +54 -0
  30. data/lib/typhoeus/response/informations.rb +205 -0
  31. data/lib/typhoeus/response/status.rb +80 -0
  32. data/lib/typhoeus/response.rb +45 -118
  33. data/lib/typhoeus/version.rb +3 -1
  34. data/lib/typhoeus.rb +87 -39
  35. metadata +37 -143
  36. data/lib/typhoeus/curl.rb +0 -453
  37. data/lib/typhoeus/easy/auth.rb +0 -14
  38. data/lib/typhoeus/easy/callbacks.rb +0 -33
  39. data/lib/typhoeus/easy/ffi_helper.rb +0 -61
  40. data/lib/typhoeus/easy/infos.rb +0 -90
  41. data/lib/typhoeus/easy/options.rb +0 -115
  42. data/lib/typhoeus/easy/proxy.rb +0 -20
  43. data/lib/typhoeus/easy/ssl.rb +0 -82
  44. data/lib/typhoeus/easy.rb +0 -115
  45. data/lib/typhoeus/filter.rb +0 -28
  46. data/lib/typhoeus/form.rb +0 -61
  47. data/lib/typhoeus/header.rb +0 -54
  48. data/lib/typhoeus/hydra/callbacks.rb +0 -24
  49. data/lib/typhoeus/hydra/connect_options.rb +0 -61
  50. data/lib/typhoeus/hydra/stubbing.rb +0 -68
  51. data/lib/typhoeus/hydra_mock.rb +0 -131
  52. data/lib/typhoeus/multi.rb +0 -146
  53. data/lib/typhoeus/param_processor.rb +0 -43
  54. data/lib/typhoeus/remote.rb +0 -306
  55. data/lib/typhoeus/remote_method.rb +0 -108
  56. data/lib/typhoeus/remote_proxy_object.rb +0 -50
  57. data/lib/typhoeus/utils.rb +0 -50
@@ -1,247 +1,94 @@
1
- require 'typhoeus/hydra/callbacks'
2
- require 'typhoeus/hydra/connect_options'
3
- require 'typhoeus/hydra/stubbing'
1
+ require 'typhoeus/hydra/before'
2
+ require 'typhoeus/hydra/block_connection'
3
+ require 'typhoeus/hydra/easy_factory'
4
+ require 'typhoeus/hydra/easy_pool'
5
+ require 'typhoeus/hydra/memoizable'
6
+ require 'typhoeus/hydra/queueable'
7
+ require 'typhoeus/hydra/runnable'
8
+ require 'typhoeus/hydra/stubbable'
4
9
 
5
10
  module Typhoeus
6
- class Hydra
7
- include ConnectOptions
8
- include Stubbing
9
- extend Callbacks
10
-
11
- def initialize(options = {})
12
- @memoize_requests = true
13
- @multi = Multi.new
14
- @easy_pool = []
15
- initial_pool_size = options[:initial_pool_size] || 10
16
- @max_concurrency = options[:max_concurrency] || 200
17
- initial_pool_size.times { @easy_pool << Easy.new }
18
- @memoized_requests = {}
19
- @retrieved_from_cache = {}
20
- @queued_requests = []
21
- @running_requests = 0
22
-
23
- self.stubs = []
24
- @active_stubs = []
25
- end
26
-
27
- def self.hydra
28
- @hydra ||= new
29
- end
30
11
 
31
- def self.hydra=(val)
32
- @hydra = val
12
+ # Hydra manages making parallel HTTP requests. This
13
+ # is achieved by using libcurls multi interface:
14
+ # http://curl.haxx.se/libcurl/c/libcurl-multi.html
15
+ # The benefits are that you don't have to worry running
16
+ # the requests by yourself.
17
+ #
18
+ # Hydra will also handle how many requests you can
19
+ # make in parallel. Things will get flakey if you
20
+ # try to make too many requests at the same time.
21
+ # The built in limit is 200. When more requests than
22
+ # that are queued up, hydra will save them for later
23
+ # and start the requests as others are finished. You
24
+ # can raise or lower the concurrency limit through
25
+ # the Hydra constructor.
26
+ #
27
+ # Regarding the asynchronous behavior of the hydra,
28
+ # it is important to know that this is completely hidden
29
+ # from the developer and you are free to apply
30
+ # whatever technique you want to your code. That should not
31
+ # conflict with libcurls internal concurrency mechanism.
32
+ #
33
+ # @example Use the hydra to do multiple requests.
34
+ # hydra = Typhoeus::Hydra.new
35
+ # requests = (0..9).map{ Typhoeus::Request.new("www.example.com") }
36
+ # requests.each{ |request| hydra.queue(request) }
37
+ # hydra.run
38
+ class Hydra
39
+ include Hydra::EasyPool
40
+ include Hydra::Queueable
41
+ include Hydra::Runnable
42
+ include Hydra::Memoizable
43
+ include Hydra::BlockConnection
44
+ include Hydra::Stubbable
45
+ include Hydra::Before
46
+
47
+ # @example Set max_concurrency.
48
+ # Typhoeus::Hydra.new(:max_concurrency => 20)
49
+ attr_reader :max_concurrency
50
+
51
+ # @api private
52
+ attr_reader :multi
53
+
54
+ class << self
55
+
56
+ # Returns a memoized hydra instance.
57
+ #
58
+ # @example Get a hydra.
59
+ # Typhoeus::Hydra.hydra
60
+ #
61
+ # @return [Typhoeus::Hydra] A new hydra.
62
+ #
63
+ # @deprecated This is only for convenience because so
64
+ # much external code relies on it.
65
+ def hydra
66
+ @hydra ||= new
67
+ end
33
68
  end
34
69
 
70
+ # Create a new hydra. All
71
+ # {http://rubydoc.info/github/typhoeus/ethon/Ethon/Multi#initialize-instance_method Ethon::Multi#initialize}
72
+ # options are also available.
35
73
  #
36
- # Abort the run on a best-effort basis.
74
+ # @example Create a hydra.
75
+ # Typhoeus::Hydra.new
37
76
  #
38
- # It won't abort the current burst of @max_concurrency requests,
39
- # however it won't fire the rest of the queued requests so the run
40
- # will be aborted as soon as possible...
77
+ # @example Create a hydra with max_concurrency.
78
+ # Typhoeus::Hydra.new(:max_concurrency => 20)
41
79
  #
42
- def abort
43
- @queued_requests.clear
44
- end
45
-
46
- def clear_cache_callbacks
47
- @cache_setter = nil
48
- @cache_getter = nil
49
- end
50
-
51
- def fire_and_forget
52
- @queued_requests.each {|r| queue(r, false)}
53
- @multi.fire_and_forget
54
- end
55
-
56
- def queue(request, obey_concurrency_limit = true)
57
- return if assign_to_stub(request)
58
-
59
- # At this point, we are running over live HTTP. Make sure we haven't
60
- # disabled live requests.
61
- check_allow_net_connect!(request)
62
-
63
- if @running_requests >= @max_concurrency && obey_concurrency_limit
64
- @queued_requests << request
65
- else
66
- if request.method == :get
67
- if @memoize_requests && @memoized_requests.key?(request.url)
68
- if response = @retrieved_from_cache[request.url]
69
- request.response = response
70
- request.call_handlers
71
- else
72
- @memoized_requests[request.url] << request
73
- end
74
- else
75
- @memoized_requests[request.url] = [] if @memoize_requests
76
- get_from_cache_or_queue(request)
77
- end
78
- else
79
- get_from_cache_or_queue(request)
80
- end
81
- end
82
- end
83
-
84
- def run
85
- while !@active_stubs.empty?
86
- m = @active_stubs.first
87
- while request = m.requests.shift
88
- response = m.response
89
- response.request = request
90
- handle_request(request, response)
91
- end
92
- @active_stubs.delete(m)
93
- end
94
-
95
- @multi.perform
96
- ensure
97
- @multi.reset_easy_handles{|easy| release_easy_object(easy)}
98
- @memoized_requests = {}
99
- @retrieved_from_cache = {}
100
- @running_requests = 0
101
- end
102
-
103
- def disable_memoization
104
- @memoize_requests = false
105
- end
106
-
107
- def cache_getter(&block)
108
- @cache_getter = block
109
- end
110
-
111
- def cache_setter(&block)
112
- @cache_setter = block
113
- end
114
-
115
- def on_complete(&block)
116
- @on_complete = block
117
- end
118
-
119
- def on_complete=(proc)
120
- @on_complete = proc
121
- end
122
-
123
- private
124
-
125
- def get_from_cache_or_queue(request)
126
- if @cache_getter
127
- val = @cache_getter.call(request)
128
- if val
129
- @retrieved_from_cache[request.url] = val
130
- queue_next
131
- handle_request(request, val, false)
132
- else
133
- @multi.add(get_easy_object(request))
134
- end
135
- else
136
- @multi.add(get_easy_object(request))
137
- end
138
- end
139
-
140
- def get_easy_object(request)
141
- @running_requests += 1
142
-
143
- easy = @easy_pool.pop || Easy.new
144
- easy.verbose = request.verbose
145
- if request.username || request.password
146
- auth = { :username => request.username, :password => request.password }
147
- auth[:method] = request.auth_method if request.auth_method
148
- easy.auth = auth
149
- end
150
-
151
- if request.proxy
152
- proxy = { :server => request.proxy }
153
- proxy[:type] = request.proxy_type if request.proxy_type
154
- easy.proxy = proxy if request.proxy
155
- end
156
-
157
- if request.proxy_username || request.proxy_password
158
- auth = { :username => request.proxy_username, :password => request.proxy_password }
159
- auth[:method] = request.proxy_auth_method if request.proxy_auth_method
160
- easy.proxy_auth = auth
161
- end
162
-
163
- easy.url = request.url
164
- easy.method = request.method
165
- easy.params = request.params if [:post, :put].include?(request.method) && !request.params.nil?
166
- easy.headers = request.headers if request.headers
167
- easy.request_body = request.body if [:post, :put].include?(request.method) && !request.body.nil?
168
- easy.timeout = request.timeout if request.timeout
169
- easy.connect_timeout = request.connect_timeout if request.connect_timeout
170
- easy.interface = request.interface if request.interface
171
- easy.follow_location = request.follow_location if request.follow_location
172
- easy.max_redirects = request.max_redirects if request.max_redirects
173
- easy.disable_ssl_peer_verification if request.disable_ssl_peer_verification
174
- easy.disable_ssl_host_verification if request.disable_ssl_host_verification
175
- easy.ssl_cert = request.ssl_cert
176
- easy.ssl_cert_type = request.ssl_cert_type
177
- easy.ssl_key = request.ssl_key
178
- easy.ssl_key_type = request.ssl_key_type
179
- easy.ssl_key_password = request.ssl_key_password
180
- easy.ssl_cacert = request.ssl_cacert
181
- easy.ssl_capath = request.ssl_capath
182
- easy.ssl_version = request.ssl_version || :default
183
- easy.verbose = request.verbose
184
-
185
- easy.on_success do |easy|
186
- queue_next
187
- handle_request(request, response_from_easy(easy, request))
188
- release_easy_object(easy)
189
- end
190
- easy.on_failure do |easy|
191
- queue_next
192
- handle_request(request, response_from_easy(easy, request))
193
- release_easy_object(easy)
194
- end
195
- easy.set_headers
196
- easy
197
- end
198
-
199
- def queue_next
200
- @running_requests -= 1
201
- queue(@queued_requests.shift) unless @queued_requests.empty?
202
- end
203
-
204
- def release_easy_object(easy)
205
- easy.reset
206
- @easy_pool.push easy
207
- end
208
-
209
- def handle_request(request, response, live_request = true)
210
- request.response = response
211
-
212
- self.class.run_global_hooks_for(:after_request_before_on_complete,
213
- request)
214
-
215
- if live_request && request.cache_timeout && @cache_setter
216
- @cache_setter.call(request)
217
- end
218
- @on_complete.call(response) if @on_complete
219
-
220
- request.call_handlers
221
- if requests = @memoized_requests[request.url]
222
- requests.each do |r|
223
- r.response = response
224
- r.call_handlers
225
- end
226
- end
227
- end
228
-
229
- def response_from_easy(easy, request)
230
- Response.new(:code => easy.response_code,
231
- :headers => easy.response_header,
232
- :body => easy.response_body,
233
- :time => easy.total_time_taken,
234
- :start_transfer_time => easy.start_transfer_time,
235
- :app_connect_time => easy.app_connect_time,
236
- :pretransfer_time => easy.pretransfer_time,
237
- :connect_time => easy.connect_time,
238
- :name_lookup_time => easy.name_lookup_time,
239
- :effective_url => easy.effective_url,
240
- :primary_ip => easy.primary_ip,
241
- :curl_return_code => easy.curl_return_code,
242
- :curl_error_message => easy.curl_error_message,
243
- :redirect_count => easy.redirect_count,
244
- :request => request)
80
+ # @param [ Hash ] options The options hash.
81
+ #
82
+ # @option options :max_concurrency [ Integer ] Number
83
+ # of max concurrent connections to create. Default is
84
+ # 200.
85
+ #
86
+ # @see http://rubydoc.info/github/typhoeus/ethon/Ethon/Multi#initialize-instance_method
87
+ # Ethon::Multi#initialize
88
+ def initialize(options = {})
89
+ @options = options
90
+ @max_concurrency = @options.fetch(:max_concurrency, 200)
91
+ @multi = Ethon::Multi.new(options.reject{|k,_| k==:max_concurrency})
245
92
  end
246
93
  end
247
94
  end
@@ -0,0 +1,125 @@
1
+ module Typhoeus
2
+ class Request
3
+
4
+ # Module containing logic about shortcuts to
5
+ # http methods. Like
6
+ # Typhoeus.get("www.example.com")
7
+ module Actions
8
+
9
+ # Make a get request.
10
+ #
11
+ # @example Make get request.
12
+ # Typhoeus.get("www.example.com")
13
+ #
14
+ # @param (see Typhoeus::Request#initialize)
15
+ #
16
+ # @option (see Typhoeus::Request#initialize)
17
+ #
18
+ # @return (see Typhoeus::Request#initialize)
19
+ #
20
+ # @note (see Typhoeus::Request#initialize)
21
+ def get(url, options = {})
22
+ Request.run(url, options.merge(:method => :get))
23
+ end
24
+
25
+ # Make a post request.
26
+ #
27
+ # @example Make post request.
28
+ # Typhoeus.post("www.example.com")
29
+ #
30
+ # @param (see Typhoeus::Request#initialize)
31
+ #
32
+ # @option (see Typhoeus::Request#initialize)
33
+ #
34
+ # @return (see Typhoeus::Request#initialize)
35
+ #
36
+ # @note (see Typhoeus::Request#initialize)
37
+ def post(url, options = {})
38
+ Request.run(url, options.merge(:method => :post))
39
+ end
40
+
41
+ # Make a put request.
42
+ #
43
+ # @example Make put request.
44
+ # Typhoeus.put("www.example.com")
45
+ #
46
+ # @param (see Typhoeus::Request#initialize)
47
+ #
48
+ # @option options :params [ Hash ] Params hash which
49
+ # is attached to the url.
50
+ # @option options :body [ Hash ] Body hash which
51
+ # becomes a PUT request body.
52
+ #
53
+ # @return (see Typhoeus::Request#initialize)
54
+ #
55
+ # @note (see Typhoeus::Request#initialize)
56
+ def put(url, options = {})
57
+ Request.run(url, options.merge(:method => :put))
58
+ end
59
+
60
+ # Make a delete request.
61
+ #
62
+ # @example Make delete request.
63
+ # Typhoeus.delete("www.example.com")
64
+ #
65
+ # @param (see Typhoeus::Request#initialize)
66
+ #
67
+ # @option (see Typhoeus::Request#initialize)
68
+ #
69
+ # @return (see Typhoeus::Request#initialize)
70
+ #
71
+ # @note (see Typhoeus::Request#initialize)
72
+ def delete(url, options = {})
73
+ Request.run(url, options.merge(:method => :delete))
74
+ end
75
+
76
+ # Make a head request.
77
+ #
78
+ # @example Make head request.
79
+ # Typhoeus.head("www.example.com")
80
+ #
81
+ # @param (see Typhoeus::Request#initialize)
82
+ #
83
+ # @option (see Typhoeus::Request#initialize)
84
+ #
85
+ # @return (see Typhoeus::Request#initialize)
86
+ #
87
+ # @note (see Typhoeus::Request#initialize)
88
+ def head(url, options = {})
89
+ Request.run(url, options.merge(:method => :head))
90
+ end
91
+
92
+ # Make a patch request.
93
+ #
94
+ # @example Make patch request.
95
+ # Typhoeus.patch("www.example.com")
96
+ #
97
+ # @param (see Typhoeus::Request#initialize)
98
+ #
99
+ # @option (see Typhoeus::Request#initialize)
100
+ #
101
+ # @return (see Typhoeus::Request#initialize)
102
+ #
103
+ # @note (see Typhoeus::Request#initialize)
104
+ def patch(url, options = {})
105
+ Request.run(url, options.merge(:method => :patch))
106
+ end
107
+
108
+ # Make a options request.
109
+ #
110
+ # @example Make options request.
111
+ # Typhoeus.options("www.example.com")
112
+ #
113
+ # @param (see Typhoeus::Request#initialize)
114
+ #
115
+ # @option (see Typhoeus::Request#initialize)
116
+ #
117
+ # @return (see Typhoeus::Request#initialize)
118
+ #
119
+ # @note (see Typhoeus::Request#initialize)
120
+ def options(url, options = {})
121
+ Request.run(url, options.merge(:method => :options))
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,30 @@
1
+ module Typhoeus
2
+ class Request
3
+
4
+ # This module provides a way to hook into before
5
+ # a request runs. 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 run in order to execute callbacks in
13
+ # Typhoeus.before. Will break and return when a
14
+ # callback returns nil or false. Calls super
15
+ # otherwise.
16
+ #
17
+ # @example Run the request.
18
+ # request.run
19
+ def run
20
+ Typhoeus.before.each do |callback|
21
+ value = callback.call(self)
22
+ if value.nil? || value == false || value.is_a?(Response)
23
+ return value
24
+ end
25
+ end
26
+ super
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ module Typhoeus
2
+ class Request
3
+
4
+ # This module handles the blocked connection request mode on
5
+ # the request 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 run 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 Run request.
23
+ # request.run
24
+ #
25
+ # @raise [Typhoeus::Errors::NoStub] If connection is blocked
26
+ # and no stub defined.
27
+ def run
28
+ if blocked?
29
+ raise Typhoeus::Errors::NoStub.new(self)
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ # Returns wether a request is blocked or not. Takes
36
+ # request.block_connection and Typhoeus::Config.block_connection
37
+ # into consideration.
38
+ #
39
+ # @example Blocked?
40
+ # request.blocked?
41
+ #
42
+ # @return [ Boolean ] True if blocked, false else.
43
+ def blocked?
44
+ if block_connection.nil?
45
+ Typhoeus::Config.block_connection
46
+ else
47
+ block_connection
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,98 @@
1
+ module Typhoeus
2
+ class Request
3
+
4
+ # This module contains the logic for the response callbacks.
5
+ # The on_complete callback is the only one at the moment.
6
+ #
7
+ # You can set multiple callbacks, which are then executed
8
+ # in the same order.
9
+ #
10
+ # request.on_complete { |response| p 1 }
11
+ # request.on_complete { |response| p 2 }
12
+ # request.execute_callbacks
13
+ # #=> 1
14
+ # #=> 2
15
+ #
16
+ # You can clear the callbacks:
17
+ #
18
+ # request.on_complete { |response| p 1 }
19
+ # request.on_complete { |response| p 2 }
20
+ # request.on_complete.clear
21
+ # request.execute_callbacks
22
+ # #=> []
23
+ module Callbacks
24
+
25
+ module Types # :nodoc:
26
+ # Set on_complete callback.
27
+ #
28
+ # @example Set on_complete.
29
+ # request.on_complete { |response| p "yay" }
30
+ #
31
+ # @param [ Block ] block The block to execute.
32
+ #
33
+ # @yield [ Typhoeus::Response ]
34
+ #
35
+ # @return [ Array<Block> ] All on_complete blocks.
36
+ def on_complete(&block)
37
+ @on_complete ||= []
38
+ @on_complete << block if block_given?
39
+ @on_complete
40
+ end
41
+
42
+ # Set on_success callback.
43
+ #
44
+ # @example Set on_success.
45
+ # request.on_success { |response| p "yay" }
46
+ #
47
+ # @param [ Block ] block The block to execute.
48
+ #
49
+ # @yield [ Typhoeus::Response ]
50
+ #
51
+ # @return [ Array<Block> ] All on_success blocks.
52
+ def on_success(&block)
53
+ @on_success ||= []
54
+ @on_success << block if block_given?
55
+ @on_success
56
+ end
57
+
58
+ # Set on_failure callback.
59
+ #
60
+ # @example Set on_failure.
61
+ # request.on_failure { |response| p "yay" }
62
+ #
63
+ # @param [ Block ] block The block to execute.
64
+ #
65
+ # @yield [ Typhoeus::Response ]
66
+ #
67
+ # @return [ Array<Block> ] All on_failure blocks.
68
+ def on_failure(&block)
69
+ @on_failure ||= []
70
+ @on_failure << block if block_given?
71
+ @on_failure
72
+ end
73
+ end
74
+
75
+ # Execute nessecary callback and yields response. This
76
+ # include in every case on_complete, on_success if
77
+ # successful and on_failure if not.
78
+ #
79
+ # @example Execute callbacks.
80
+ # request.execute_callbacks
81
+ #
82
+ # @return [ void ]
83
+ #
84
+ # @api private
85
+ def execute_callbacks
86
+ callbacks = Typhoeus.on_complete + on_complete
87
+
88
+ if response && response.success?
89
+ callbacks += Typhoeus.on_success + on_success
90
+ elsif response
91
+ callbacks += Typhoeus.on_failure + on_failure
92
+ end
93
+
94
+ callbacks.map{ |callback| callback.call(self.response) }
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,21 @@
1
+ module Typhoeus
2
+ class Request
3
+
4
+ # This module contains custom serializer.
5
+ module Marshal
6
+
7
+ # Return the important data needed to serialize this Request, except the
8
+ # `on_complete` handler, since they cannot be marshalled.
9
+ def marshal_dump
10
+ (instance_variables - ['@on_complete', :@on_complete]).map do |name|
11
+ [name, instance_variable_get(name)]
12
+ end
13
+ end
14
+
15
+ # Load.
16
+ def marshal_load(attributes)
17
+ attributes.each { |name, value| instance_variable_set(name, value) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ module Typhoeus
2
+ class Request
3
+
4
+ # This module handles the GET request memoization
5
+ # on the request 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
+ # Override response setter and memoizes response
15
+ # if the request is memoizable.
16
+ #
17
+ # @param [ Response ] response The response to set.
18
+ #
19
+ # @example Set response.
20
+ # request.response = response
21
+ def response=(response)
22
+ hydra.memory[self] = response if memoizable?
23
+ super
24
+ end
25
+
26
+ # Return whether a request is memoizable.
27
+ #
28
+ # @example Is request memoizable?
29
+ # request.memoizable?
30
+ #
31
+ # @return [ Boolean ] Return true if memoizable, false else.
32
+ def memoizable?
33
+ Typhoeus::Config.memoize &&
34
+ (options[:method].nil? || options[:method] == :get)
35
+ end
36
+ end
37
+ end
38
+ end