typhoeus 0.5.0.pre → 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.
- data/CHANGELOG.md +12 -0
- data/Gemfile +17 -1
- data/README.md +2 -2
- data/lib/typhoeus.rb +78 -16
- data/lib/typhoeus/config.rb +40 -4
- data/lib/typhoeus/errors.rb +9 -0
- data/lib/typhoeus/errors/no_stub.rb +12 -0
- data/lib/typhoeus/errors/typhoeus_error.rb +8 -0
- data/lib/typhoeus/expectation.rb +174 -0
- data/lib/typhoeus/hydra.rb +71 -14
- data/lib/typhoeus/hydra/before.rb +30 -0
- data/lib/typhoeus/hydra/block_connection.rb +35 -0
- data/lib/typhoeus/{hydras → hydra}/easy_factory.rb +17 -5
- data/lib/typhoeus/{hydras → hydra}/easy_pool.rb +4 -2
- data/lib/typhoeus/{hydras → hydra}/memoizable.rb +7 -5
- data/lib/typhoeus/{hydras → hydra}/queueable.rb +5 -3
- data/lib/typhoeus/{hydras → hydra}/runnable.rb +4 -1
- data/lib/typhoeus/hydra/stubbable.rb +26 -0
- data/lib/typhoeus/request.rb +117 -29
- data/lib/typhoeus/request/actions.rb +125 -0
- data/lib/typhoeus/request/before.rb +30 -0
- data/lib/typhoeus/request/block_connection.rb +52 -0
- data/lib/typhoeus/request/callbacks.rb +98 -0
- data/lib/typhoeus/{requests → request}/marshal.rb +1 -1
- data/lib/typhoeus/{requests → request}/memoizable.rb +4 -2
- data/lib/typhoeus/{requests → request}/operations.rb +25 -5
- data/lib/typhoeus/{requests → request}/responseable.rb +1 -1
- data/lib/typhoeus/request/stubbable.rb +28 -0
- data/lib/typhoeus/response.rb +30 -8
- data/lib/typhoeus/{responses → response}/header.rb +15 -11
- data/lib/typhoeus/response/informations.rb +205 -0
- data/lib/typhoeus/{responses → response}/status.rb +10 -7
- data/lib/typhoeus/version.rb +1 -1
- metadata +32 -135
- data/lib/typhoeus/requests/actions.rb +0 -17
- data/lib/typhoeus/requests/callbacks.rb +0 -48
- data/lib/typhoeus/responses/informations.rb +0 -43
- 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
|
-
|
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
|
-
|
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::
|
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.
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
36
|
-
request.
|
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
|
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
|
-
|
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(
|
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
|
-
|
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
|
data/lib/typhoeus/request.rb
CHANGED
@@ -1,42 +1,115 @@
|
|
1
|
-
require 'typhoeus/
|
2
|
-
require 'typhoeus/
|
3
|
-
require 'typhoeus/
|
4
|
-
require 'typhoeus/
|
5
|
-
require 'typhoeus/
|
6
|
-
require 'typhoeus/
|
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
|
-
|
13
|
-
include
|
14
|
-
include
|
15
|
-
|
16
|
-
include
|
17
|
-
include
|
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
|
-
|
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
|
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 [
|
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
|
-
#
|
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
|
-
|
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
|
-
|
140
|
+
private
|
64
141
|
|
65
|
-
# Checks if two hashes are equal or not, discarding
|
142
|
+
# Checks if two hashes are equal or not, discarding
|
143
|
+
# first-level hash order.
|
66
144
|
#
|
67
|
-
# @param [ Hash ]
|
68
|
-
# @param [ Hash ]
|
145
|
+
# @param [ Hash ] left
|
146
|
+
# @param [ Hash ] right hash to check for equality
|
69
147
|
#
|
70
|
-
# @return [ Boolean ] Returns true if hashes have
|
71
|
-
#
|
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
|