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.
- 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
|