typhoeus 0.5.0.pre → 0.5.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/CHANGELOG.md +12 -0
  2. data/Gemfile +17 -1
  3. data/README.md +2 -2
  4. data/lib/typhoeus.rb +78 -16
  5. data/lib/typhoeus/config.rb +40 -4
  6. data/lib/typhoeus/errors.rb +9 -0
  7. data/lib/typhoeus/errors/no_stub.rb +12 -0
  8. data/lib/typhoeus/errors/typhoeus_error.rb +8 -0
  9. data/lib/typhoeus/expectation.rb +174 -0
  10. data/lib/typhoeus/hydra.rb +71 -14
  11. data/lib/typhoeus/hydra/before.rb +30 -0
  12. data/lib/typhoeus/hydra/block_connection.rb +35 -0
  13. data/lib/typhoeus/{hydras → hydra}/easy_factory.rb +17 -5
  14. data/lib/typhoeus/{hydras → hydra}/easy_pool.rb +4 -2
  15. data/lib/typhoeus/{hydras → hydra}/memoizable.rb +7 -5
  16. data/lib/typhoeus/{hydras → hydra}/queueable.rb +5 -3
  17. data/lib/typhoeus/{hydras → hydra}/runnable.rb +4 -1
  18. data/lib/typhoeus/hydra/stubbable.rb +26 -0
  19. data/lib/typhoeus/request.rb +117 -29
  20. data/lib/typhoeus/request/actions.rb +125 -0
  21. data/lib/typhoeus/request/before.rb +30 -0
  22. data/lib/typhoeus/request/block_connection.rb +52 -0
  23. data/lib/typhoeus/request/callbacks.rb +98 -0
  24. data/lib/typhoeus/{requests → request}/marshal.rb +1 -1
  25. data/lib/typhoeus/{requests → request}/memoizable.rb +4 -2
  26. data/lib/typhoeus/{requests → request}/operations.rb +25 -5
  27. data/lib/typhoeus/{requests → request}/responseable.rb +1 -1
  28. data/lib/typhoeus/request/stubbable.rb +28 -0
  29. data/lib/typhoeus/response.rb +30 -8
  30. data/lib/typhoeus/{responses → response}/header.rb +15 -11
  31. data/lib/typhoeus/response/informations.rb +205 -0
  32. data/lib/typhoeus/{responses → response}/status.rb +10 -7
  33. data/lib/typhoeus/version.rb +1 -1
  34. metadata +32 -135
  35. data/lib/typhoeus/requests/actions.rb +0 -17
  36. data/lib/typhoeus/requests/callbacks.rb +0 -48
  37. data/lib/typhoeus/responses/informations.rb +0 -43
  38. data/lib/typhoeus/responses/legacy.rb +0 -26
@@ -0,0 +1,30 @@
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 queue 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 Queue the request.
18
+ # hydra.queue(request)
19
+ def queue(request)
20
+ Typhoeus.before.each do |callback|
21
+ value = callback.call(request)
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,35 @@
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 queue 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 Queue the request.
23
+ # hydra.queue(request)
24
+ #
25
+ # @param [ Request ] request The request to enqueue.
26
+ def queue(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,17 +1,28 @@
1
1
  module Typhoeus
2
- module Hydras
2
+ class Hydra
3
3
 
4
4
  # This is a Factory for easies to be used in the hydra.
5
5
  # Before an easy is ready to be added to a multi, it needs
6
6
  # to be prepared and the on_complete callback to be set.
7
7
  # This is done by this class.
8
+ #
9
+ # @api private
8
10
  class EasyFactory
9
- attr_reader :request, :hydra
11
+
12
+ # Returns the request provided.
13
+ #
14
+ # @return [ Typhoeus::Request ]
15
+ attr_reader :request
16
+
17
+ # Returns the hydra provided.
18
+ #
19
+ # @return [ Typhoeus::Hydra ]
20
+ attr_reader :hydra
10
21
 
11
22
  # Create an easy factory.
12
23
  #
13
24
  # @example Create easy factory.
14
- # Typhoeus::Hydras::EasyFactory.new(request, hydra)
25
+ # Typhoeus::Hydra::EasyFactory.new(request, hydra)
15
26
  #
16
27
  # @param [ Request ] request The request to build an easy for.
17
28
  # @param [ Hydra ] hydra The hydra to build an easy for.
@@ -47,6 +58,8 @@ module Typhoeus
47
58
  easy
48
59
  end
49
60
 
61
+ private
62
+
50
63
  # Sets on_complete callback on easy in order to be able to
51
64
  # track progress.
52
65
  #
@@ -56,10 +69,9 @@ module Typhoeus
56
69
  # @return [ Ethon::Easy ] The easy.
57
70
  def set_callback
58
71
  easy.on_complete do |easy|
59
- request.response = Response.new(easy.to_hash)
72
+ request.finish(Response.new(easy.to_hash))
60
73
  hydra.release_easy(easy)
61
74
  hydra.queue(hydra.queued_requests.shift) unless hydra.queued_requests.empty?
62
- request.complete
63
75
  end
64
76
  end
65
77
  end
@@ -1,9 +1,11 @@
1
1
  module Typhoeus
2
- module Hydras
2
+ class Hydra
3
3
 
4
4
  # The easy pool stores already initialized
5
5
  # easy handles for future use. This is useful
6
6
  # because creating them is quite expensive.
7
+ #
8
+ # @api private
7
9
  module EasyPool
8
10
 
9
11
  # Return the easy pool.
@@ -11,7 +13,7 @@ module Typhoeus
11
13
  # @example Return easy pool.
12
14
  # hydra.easy_pool
13
15
  #
14
- # @return [ Array ] The easy pool.
16
+ # @return [ Array<Ethon::Easy> ] The easy pool.
15
17
  def easy_pool
16
18
  @easy_pool ||= []
17
19
  end
@@ -1,12 +1,14 @@
1
1
  module Typhoeus
2
- module Hydras
2
+ class Hydra
3
3
 
4
4
  # This module handles the GET request memoization
5
5
  # on the hydra side. Memoization needs to be turned
6
6
  # on:
7
- # Typhoeus.configre do |config|
7
+ # Typhoeus.configure do |config|
8
8
  # config.memoize = true
9
9
  # end
10
+ #
11
+ # @api private
10
12
  module Memoizable
11
13
 
12
14
  # Return the memory.
@@ -32,14 +34,14 @@ module Typhoeus
32
34
  # @return [ Request ] The queued request.
33
35
  def queue(request)
34
36
  if request.memoizable? && memory.has_key?(request)
35
- request.instance_variable_set(:@response, memory[request])
36
- request.complete
37
+ response = memory[request]
38
+ request.finish(response, true)
37
39
  else
38
40
  super
39
41
  end
40
42
  end
41
43
 
42
- # Overrides run to clear the memory is cleared after
44
+ # Overrides run to make sure the memory is cleared after
43
45
  # each run.
44
46
  #
45
47
  # @example Run hydra.
@@ -1,8 +1,10 @@
1
1
  module Typhoeus
2
- module Hydras # :nodoc:
2
+ class Hydra
3
3
 
4
4
  # This module handles the request queueing on
5
5
  # hydra.
6
+ #
7
+ # @api private
6
8
  module Queueable
7
9
 
8
10
  # Return the queued requests.
@@ -10,7 +12,7 @@ module Typhoeus
10
12
  # @example Return queued requests.
11
13
  # hydra.queued_requests
12
14
  #
13
- # @return [ Array ] The queued requests.
15
+ # @return [ Array<Typhoeus::Request> ] The queued requests.
14
16
  def queued_requests
15
17
  @queued_requests ||= []
16
18
  end
@@ -36,7 +38,7 @@ module Typhoeus
36
38
  def queue(request)
37
39
  request.hydra = self
38
40
  if multi.easy_handles.size < max_concurrency
39
- multi.add(Hydras::EasyFactory.new(request, self).get)
41
+ multi.add(Hydra::EasyFactory.new(request, self).get)
40
42
  else
41
43
  queued_requests << request
42
44
  end
@@ -1,7 +1,9 @@
1
1
  module Typhoeus
2
- module Hydras
2
+ class Hydra
3
3
 
4
4
  # This module contains logic to run a hydra.
5
+ #
6
+ # @api private
5
7
  module Runnable
6
8
 
7
9
  # Start the hydra run.
@@ -11,6 +13,7 @@ module Typhoeus
11
13
  #
12
14
  # @return [ Symbol ] Return value from multi.perform.
13
15
  def run
16
+ multi.prepare
14
17
  multi.perform
15
18
  end
16
19
  end
@@ -0,0 +1,26 @@
1
+ module Typhoeus
2
+ class Hydra
3
+
4
+ # This module handles stubbing on the hydra side.
5
+ # It plays well with the block_connection configuration,
6
+ # which raises when you make a request which is not stubbed.
7
+ #
8
+ # @api private
9
+ module Stubbable
10
+
11
+ # Override queue in order to check for matching expecations.
12
+ # When an expecation is found, super is not called. Instead a
13
+ # canned response is assigned to the request.
14
+ #
15
+ # @example Queue the request.
16
+ # hydra.queue(request)
17
+ def queue(request)
18
+ if expectation = Expectation.find_by(request)
19
+ request.finish(expectation.response)
20
+ else
21
+ super
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,42 +1,115 @@
1
- require 'typhoeus/requests/callbacks'
2
- require 'typhoeus/requests/actions'
3
- require 'typhoeus/requests/operations'
4
- require 'typhoeus/requests/marshal'
5
- require 'typhoeus/requests/responseable'
6
- require 'typhoeus/requests/memoizable'
1
+ require 'typhoeus/request/actions'
2
+ require 'typhoeus/request/before'
3
+ require 'typhoeus/request/block_connection'
4
+ require 'typhoeus/request/callbacks'
5
+ require 'typhoeus/request/marshal'
6
+ require 'typhoeus/request/memoizable'
7
+ require 'typhoeus/request/operations'
8
+ require 'typhoeus/request/responseable'
9
+ require 'typhoeus/request/stubbable'
7
10
 
8
11
  module Typhoeus
9
12
 
10
13
  # This class represents a request.
14
+ #
15
+ # @example (see #initialize)
16
+ #
17
+ # @example Make a request with the shortcut.
18
+ # response = Typhoeus.get("www.example.com")
19
+ #
20
+ # @see (see #initialize)
11
21
  class Request
12
- include Requests::Callbacks
13
- include Requests::Marshal
14
- include Requests::Operations
15
- extend Requests::Actions
16
- include Requests::Responseable
17
- include Requests::Memoizable
22
+ extend Request::Actions
23
+ include Request::Callbacks::Types
24
+ include Request::Callbacks
25
+ include Request::Marshal
26
+ include Request::Operations
27
+ include Request::Responseable
28
+ include Request::Memoizable
29
+ include Request::BlockConnection
30
+ include Request::Stubbable
31
+ include Request::Before
18
32
 
19
- attr_accessor :options, :url, :hydra
33
+ # Returns the provided url.
34
+ #
35
+ # @return [ String ]
36
+ attr_accessor :url
37
+
38
+ # Returns options, which includes default parameters.
39
+ #
40
+ # @return [ Hash ]
41
+ attr_accessor :options
42
+
43
+ # Returns the hydra the request ran into if any.
44
+ #
45
+ # @return [ Typhoeus::Hydra ]
46
+ #
47
+ # @api private
48
+ attr_accessor :hydra
49
+
50
+ # Returns the original options provided.
51
+ #
52
+ # @return [ Hash ]
53
+ #
54
+ # @api private
55
+ attr_accessor :original_options
56
+
57
+ # @return [ Boolean ]
58
+ #
59
+ # @api private
60
+ attr_accessor :block_connection
20
61
 
21
62
  # Create a new request.
22
63
  #
23
- # @example Create a request.
24
- # Request.new("www.example.com")
64
+ # @example Simplest request.
65
+ # response = Typhoeus::Request.new("www.example.com").run
66
+ #
67
+ # @example Request with url parameters.
68
+ # response = Typhoeus::Request.new(
69
+ # "www.example.com",
70
+ # :params => {:a => 1}
71
+ # ).run
72
+ #
73
+ # @example Request with a body.
74
+ # response = Typhoeus::Request.new(
75
+ # "www.example.com",
76
+ # :body => {:b => 2}
77
+ # ).run
78
+ #
79
+ # @example Request with parameters and body.
80
+ # response = Typhoeus::Request.new(
81
+ # "www.example.com",
82
+ # :params => {:a => 1},
83
+ # :body => {:b => 2}
84
+ # ).run
85
+ #
86
+ # @example Create a request and allow follow redirections.
87
+ # response = Typhoeus::Request.new(
88
+ # "www.example.com",
89
+ # :followlocation => true
90
+ # ).run
25
91
  #
26
92
  # @param [ String ] url The url to request.
27
- # @param [ Hash ] options The options.
93
+ # @param [ options ] options The options.
94
+ #
95
+ # @option options [ Hash ] :params Translated
96
+ # into url parameters.
97
+ # @option options [ Hash ] :body Translated
98
+ # into HTTP POST request body.
28
99
  #
29
- # #return [ Request ] The new request.
100
+ # @return [ Typhoeus::Request ] The request.
101
+ #
102
+ # @note See {Ethon::Easy#initialize} for more options.
103
+ #
104
+ # @see Typhoeus::Hydra
105
+ # @see Typhoeus::Response
106
+ # @see Typhoeus::Request::Actions
30
107
  def initialize(url, options = {})
31
108
  @url = url
109
+ @original_options = options
32
110
  @options = options.dup
33
111
 
34
- if @options[:headers]
35
- @options[:headers] = {'User-Agent' => Typhoeus::USER_AGENT}.merge(options[:headers])
36
- else
37
- @options[:headers] = {'User-Agent' => Typhoeus::USER_AGENT}
38
- end
39
- @options[:verbose] = Typhoeus::Config.verbose unless @options[:verbose]
112
+ set_defaults
40
113
  end
41
114
 
42
115
  # Returns wether other is equal to self.
@@ -47,6 +120,8 @@ module Typhoeus
47
120
  # @param [ Object ] other The object to check.
48
121
  #
49
122
  # @return [ Boolean ] Returns true if equals, else false.
123
+ #
124
+ # @api private
50
125
  def eql?(other)
51
126
  self.class == other.class &&
52
127
  self.url == other.url &&
@@ -56,19 +131,23 @@ module Typhoeus
56
131
  # Overrides Object#hash.
57
132
  #
58
133
  # @return [ Integer ] The integer representing the request.
134
+ #
135
+ # @api private
59
136
  def hash
60
137
  [ self.class, self.url, self.options ].hash
61
138
  end
62
139
 
63
- protected
140
+ private
64
141
 
65
- # Checks if two hashes are equal or not, discarding first-level hash order
142
+ # Checks if two hashes are equal or not, discarding
143
+ # first-level hash order.
66
144
  #
67
- # @param [ Hash ] hash
68
- # @param [ Hash ] other hash to check for equality
145
+ # @param [ Hash ] left
146
+ # @param [ Hash ] right hash to check for equality
69
147
  #
70
- # @return [ Boolean ] Returns true if hashes have same values for same keys and same length,
71
- # even if the keys are given in a different order.
148
+ # @return [ Boolean ] Returns true if hashes have
149
+ # same values for same keys and same length,
150
+ # even if the keys are given in a different order.
72
151
  def fuzzy_hash_eql?(left, right)
73
152
  return true if (left == right)
74
153
 
@@ -77,5 +156,14 @@ module Typhoeus
77
156
  end
78
157
  end
79
158
 
159
+ # Sets default header and verbose when turned on.
160
+ def set_defaults
161
+ if @options[:headers]
162
+ @options[:headers] = {'User-Agent' => Typhoeus::USER_AGENT}.merge(options[:headers])
163
+ else
164
+ @options[:headers] = {'User-Agent' => Typhoeus::USER_AGENT}
165
+ end
166
+ @options[:verbose] = Typhoeus::Config.verbose if @options[:verbose].nil? && !Typhoeus::Config.verbose.nil?
167
+ end
80
168
  end
81
169
  end