dcu-typhoeus 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +93 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +455 -0
- data/Rakefile +23 -0
- data/lib/typhoeus/curl.rb +453 -0
- data/lib/typhoeus/easy/auth.rb +14 -0
- data/lib/typhoeus/easy/callbacks.rb +33 -0
- data/lib/typhoeus/easy/ffi_helper.rb +61 -0
- data/lib/typhoeus/easy/infos.rb +86 -0
- data/lib/typhoeus/easy/options.rb +115 -0
- data/lib/typhoeus/easy/proxy.rb +20 -0
- data/lib/typhoeus/easy/ssl.rb +82 -0
- data/lib/typhoeus/easy.rb +115 -0
- data/lib/typhoeus/filter.rb +28 -0
- data/lib/typhoeus/form.rb +61 -0
- data/lib/typhoeus/header.rb +54 -0
- data/lib/typhoeus/hydra/callbacks.rb +24 -0
- data/lib/typhoeus/hydra/connect_options.rb +61 -0
- data/lib/typhoeus/hydra/stubbing.rb +68 -0
- data/lib/typhoeus/hydra.rb +246 -0
- data/lib/typhoeus/hydra_mock.rb +131 -0
- data/lib/typhoeus/multi.rb +146 -0
- data/lib/typhoeus/param_processor.rb +43 -0
- data/lib/typhoeus/remote.rb +310 -0
- data/lib/typhoeus/remote_method.rb +108 -0
- data/lib/typhoeus/remote_proxy_object.rb +50 -0
- data/lib/typhoeus/request.rb +278 -0
- data/lib/typhoeus/response.rb +122 -0
- data/lib/typhoeus/utils.rb +58 -0
- data/lib/typhoeus/version.rb +3 -0
- data/lib/typhoeus.rb +57 -0
- metadata +179 -0
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Typhoeus
|
4
|
+
class Request
|
5
|
+
ACCESSOR_OPTIONS = [
|
6
|
+
:method,
|
7
|
+
:params,
|
8
|
+
:body,
|
9
|
+
:headers,
|
10
|
+
:cache_key_basis,
|
11
|
+
:connect_timeout,
|
12
|
+
:timeout,
|
13
|
+
:user_agent,
|
14
|
+
:response,
|
15
|
+
:cache_timeout,
|
16
|
+
:follow_location,
|
17
|
+
:max_redirects,
|
18
|
+
:proxy,
|
19
|
+
:proxy_username,
|
20
|
+
:proxy_password,
|
21
|
+
:disable_ssl_peer_verification,
|
22
|
+
:disable_ssl_host_verification,
|
23
|
+
:interface,
|
24
|
+
:ssl_cert,
|
25
|
+
:ssl_cert_type,
|
26
|
+
:ssl_key,
|
27
|
+
:ssl_key_type,
|
28
|
+
:ssl_key_password,
|
29
|
+
:ssl_cacert,
|
30
|
+
:ssl_capath,
|
31
|
+
:ssl_version,
|
32
|
+
:verbose,
|
33
|
+
:username,
|
34
|
+
:password,
|
35
|
+
:auth_method,
|
36
|
+
:user_agent,
|
37
|
+
:proxy_auth_method,
|
38
|
+
:proxy_type
|
39
|
+
]
|
40
|
+
|
41
|
+
attr_accessor *ACCESSOR_OPTIONS
|
42
|
+
|
43
|
+
# Initialize a new Request
|
44
|
+
#
|
45
|
+
# Options:
|
46
|
+
# * +url+ : Endpoint (URL) of the request
|
47
|
+
# * +options+ : A hash containing options among :
|
48
|
+
# ** +:method+ : :get (default) / :post / :put
|
49
|
+
# ** +:params+ : params as a Hash
|
50
|
+
# ** +:body+
|
51
|
+
# ** +:timeout+ : timeout (ms)
|
52
|
+
# ** +:interface+ : interface or ip address (string)
|
53
|
+
# ** +:connect_timeout+ : connect timeout (ms)
|
54
|
+
# ** +:headers+ : headers as Hash
|
55
|
+
# ** +:cache_timeout+ : cache timeout (ms)
|
56
|
+
# ** +:follow_location
|
57
|
+
# ** +:max_redirects
|
58
|
+
# ** +:proxy
|
59
|
+
# ** +:disable_ssl_peer_verification
|
60
|
+
# ** +:disable_ssl_host_verification
|
61
|
+
# ** +:ssl_cert
|
62
|
+
# ** +:ssl_cert_type
|
63
|
+
# ** +:ssl_key
|
64
|
+
# ** +:ssl_key_type
|
65
|
+
# ** +:ssl_key_password
|
66
|
+
# ** +:ssl_cacert
|
67
|
+
# ** +:ssl_capath
|
68
|
+
# ** +:verbose
|
69
|
+
# ** +:username
|
70
|
+
# ** +:password
|
71
|
+
# ** +:auth_method
|
72
|
+
#
|
73
|
+
def initialize(url, options = {})
|
74
|
+
@url = url
|
75
|
+
@method = options[:method] || :get
|
76
|
+
@params = options[:params]
|
77
|
+
@body = options[:body]
|
78
|
+
@timeout = safe_to_i(options[:timeout])
|
79
|
+
@connect_timeout = safe_to_i(options[:connect_timeout])
|
80
|
+
@interface = options[:interface]
|
81
|
+
@headers = options[:headers] || {}
|
82
|
+
|
83
|
+
if options.key?(:user_agent)
|
84
|
+
@headers['User-Agent'] = options[:user_agent]
|
85
|
+
end
|
86
|
+
|
87
|
+
@cache_timeout = safe_to_i(options[:cache_timeout])
|
88
|
+
@follow_location = options[:follow_location]
|
89
|
+
@max_redirects = options[:max_redirects]
|
90
|
+
@proxy = options[:proxy]
|
91
|
+
@proxy_type = options[:proxy_type]
|
92
|
+
@proxy_username = options[:proxy_username]
|
93
|
+
@proxy_password = options[:proxy_password]
|
94
|
+
@proxy_auth_method = options[:proxy_auth_method]
|
95
|
+
@disable_ssl_peer_verification = options[:disable_ssl_peer_verification]
|
96
|
+
@disable_ssl_host_verification = options[:disable_ssl_host_verification]
|
97
|
+
@ssl_cert = options[:ssl_cert]
|
98
|
+
@ssl_cert_type = options[:ssl_cert_type]
|
99
|
+
@ssl_key = options[:ssl_key]
|
100
|
+
@ssl_key_type = options[:ssl_key_type]
|
101
|
+
@ssl_key_password = options[:ssl_key_password]
|
102
|
+
@ssl_cacert = options[:ssl_cacert]
|
103
|
+
@ssl_capath = options[:ssl_capath]
|
104
|
+
@ssl_version = options[:ssl_version]
|
105
|
+
@verbose = options[:verbose]
|
106
|
+
@username = options[:username]
|
107
|
+
@password = options[:password]
|
108
|
+
@auth_method = options[:auth_method]
|
109
|
+
|
110
|
+
if @method == :post
|
111
|
+
@params = @params ? Typhoeus::Utils.escape_params(@params) : nil
|
112
|
+
@url = url
|
113
|
+
end
|
114
|
+
|
115
|
+
@parsed_uri = URI.parse(@url)
|
116
|
+
|
117
|
+
@on_complete = nil
|
118
|
+
@after_complete = nil
|
119
|
+
@handled_response = nil
|
120
|
+
end
|
121
|
+
|
122
|
+
LOCALHOST_ALIASES = %w[ localhost 127.0.0.1 0.0.0.0 ]
|
123
|
+
|
124
|
+
def localhost?
|
125
|
+
LOCALHOST_ALIASES.include?(parsed_uri.host)
|
126
|
+
end
|
127
|
+
|
128
|
+
def user_agent
|
129
|
+
headers['User-Agent']
|
130
|
+
end
|
131
|
+
|
132
|
+
def url
|
133
|
+
if @method == :post
|
134
|
+
@url
|
135
|
+
else
|
136
|
+
url = "#{@url}?#{params_string}"
|
137
|
+
url += "&#{URI.escape(@body)}" if @body
|
138
|
+
url.gsub("?&", "?").gsub(/\?$/, '')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def parsed_uri
|
143
|
+
@parsed_uri ||= URI.parse(@url)
|
144
|
+
end
|
145
|
+
|
146
|
+
def host
|
147
|
+
slash_location = @url.index('/', 8)
|
148
|
+
if slash_location
|
149
|
+
@url.slice(0, slash_location)
|
150
|
+
else
|
151
|
+
query_string_location = @url.index('?')
|
152
|
+
return query_string_location ? @url.slice(0, query_string_location) : @url
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def host_domain
|
157
|
+
parsed_uri.host
|
158
|
+
end
|
159
|
+
|
160
|
+
def params_string
|
161
|
+
return nil unless params
|
162
|
+
traversal = Typhoeus::Utils.traverse_params_hash(params)
|
163
|
+
Typhoeus::Utils.traversal_to_param_string(traversal)
|
164
|
+
end
|
165
|
+
|
166
|
+
def on_complete(&block)
|
167
|
+
@on_complete = block
|
168
|
+
end
|
169
|
+
|
170
|
+
def on_complete=(proc)
|
171
|
+
@on_complete = proc
|
172
|
+
end
|
173
|
+
|
174
|
+
def after_complete(&block)
|
175
|
+
@after_complete = block
|
176
|
+
end
|
177
|
+
|
178
|
+
def after_complete=(proc)
|
179
|
+
@after_complete = proc
|
180
|
+
end
|
181
|
+
|
182
|
+
def call_handlers
|
183
|
+
if @on_complete
|
184
|
+
@handled_response = @on_complete.call(response)
|
185
|
+
call_after_complete
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def call_after_complete
|
190
|
+
@after_complete.call(@handled_response) if @after_complete
|
191
|
+
end
|
192
|
+
|
193
|
+
def handled_response=(val)
|
194
|
+
@handled_response = val
|
195
|
+
end
|
196
|
+
|
197
|
+
def handled_response
|
198
|
+
@handled_response || response
|
199
|
+
end
|
200
|
+
|
201
|
+
def inspect
|
202
|
+
result = ":method => #{self.method.inspect},\n" <<
|
203
|
+
"\t:url => #{URI.parse(self.url).to_s}"
|
204
|
+
if self.body and !self.body.empty?
|
205
|
+
result << ",\n\t:body => #{self.body.inspect}"
|
206
|
+
end
|
207
|
+
|
208
|
+
if self.params and !self.params.empty?
|
209
|
+
result << ",\n\t:params => #{self.params.inspect}"
|
210
|
+
end
|
211
|
+
|
212
|
+
if self.headers and !self.headers.empty?
|
213
|
+
result << ",\n\t:headers => #{self.headers.inspect}"
|
214
|
+
end
|
215
|
+
|
216
|
+
result
|
217
|
+
end
|
218
|
+
|
219
|
+
def cache_key
|
220
|
+
Digest::SHA1.hexdigest(cache_key_basis || url)
|
221
|
+
end
|
222
|
+
|
223
|
+
def self.run(url, params)
|
224
|
+
r = new(url, params)
|
225
|
+
Typhoeus::Hydra.hydra.queue r
|
226
|
+
Typhoeus::Hydra.hydra.run
|
227
|
+
r.response
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.get(url, params = {})
|
231
|
+
run(url, params.merge(:method => :get))
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.post(url, params = {})
|
235
|
+
run(url, params.merge(:method => :post))
|
236
|
+
end
|
237
|
+
|
238
|
+
def self.put(url, params = {})
|
239
|
+
run(url, params.merge(:method => :put))
|
240
|
+
end
|
241
|
+
|
242
|
+
def self.delete(url, params = {})
|
243
|
+
run(url, params.merge(:method => :delete))
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.head(url, params = {})
|
247
|
+
run(url, params.merge(:method => :head))
|
248
|
+
end
|
249
|
+
|
250
|
+
protected
|
251
|
+
|
252
|
+
# Return the important data needed to serialize this Request, except the
|
253
|
+
# `on_complete` and `after_complete` handlers, since they cannot be
|
254
|
+
# marshalled.
|
255
|
+
def marshal_dump
|
256
|
+
(instance_variables - ['@on_complete', '@after_complete', :@on_complete, :@after_complete]).map do |name|
|
257
|
+
[name, instance_variable_get(name)]
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def marshal_load(attributes)
|
262
|
+
attributes.each { |name, value| instance_variable_set(name, value) }
|
263
|
+
end
|
264
|
+
|
265
|
+
def self.options
|
266
|
+
ACCESSOR_OPTIONS
|
267
|
+
end
|
268
|
+
|
269
|
+
private
|
270
|
+
|
271
|
+
def safe_to_i(value)
|
272
|
+
return value if value.is_a?(Fixnum)
|
273
|
+
return nil if value.nil?
|
274
|
+
return nil if value.respond_to?(:empty?) && value.empty?
|
275
|
+
value.to_i
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Typhoeus
|
2
|
+
class Response
|
3
|
+
attr_accessor :request, :mock
|
4
|
+
attr_reader :code, :headers, :body, :time,
|
5
|
+
:requested_url, :requested_remote_method,
|
6
|
+
:requested_http_method, :start_time,
|
7
|
+
:effective_url, :start_transfer_time,
|
8
|
+
:app_connect_time, :pretransfer_time,
|
9
|
+
:connect_time, :name_lookup_time,
|
10
|
+
:curl_return_code, :curl_error_message,
|
11
|
+
:primary_ip
|
12
|
+
|
13
|
+
attr_writer :headers_hash
|
14
|
+
|
15
|
+
def initialize(params = {})
|
16
|
+
@code = params[:code]
|
17
|
+
@curl_return_code = params[:curl_return_code]
|
18
|
+
@curl_error_message = params[:curl_error_message]
|
19
|
+
@status_message = params[:status_message]
|
20
|
+
@http_version = params[:http_version]
|
21
|
+
@headers = params[:headers]
|
22
|
+
@body = params[:body]
|
23
|
+
@time = params[:time]
|
24
|
+
@requested_url = params[:requested_url]
|
25
|
+
@requested_http_method = params[:requested_http_method]
|
26
|
+
@start_time = params[:start_time]
|
27
|
+
@start_transfer_time = params[:start_transfer_time]
|
28
|
+
@app_connect_time = params[:app_connect_time]
|
29
|
+
@pretransfer_time = params[:pretransfer_time]
|
30
|
+
@connect_time = params[:connect_time]
|
31
|
+
@name_lookup_time = params[:name_lookup_time]
|
32
|
+
@request = params[:request]
|
33
|
+
@effective_url = params[:effective_url]
|
34
|
+
@primary_ip = params[:primary_ip]
|
35
|
+
@mock = params[:mock] || false # default
|
36
|
+
@headers_hash = Header.new(params[:headers_hash]) if params[:headers_hash]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns true if this is a mock response.
|
40
|
+
def mock?
|
41
|
+
@mock
|
42
|
+
end
|
43
|
+
|
44
|
+
def headers
|
45
|
+
@headers ||= @headers_hash ? construct_header_string : ''
|
46
|
+
end
|
47
|
+
|
48
|
+
def headers_hash
|
49
|
+
@headers_hash ||= begin
|
50
|
+
headers.split("\n").map {|o| o.strip}.inject(Typhoeus::Header.new) do |hash, o|
|
51
|
+
if o.empty? || o =~ /^HTTP\/[\d\.]+/
|
52
|
+
hash
|
53
|
+
else
|
54
|
+
i = o.index(":") || o.size
|
55
|
+
key = o.slice(0, i)
|
56
|
+
value = o.slice(i + 1, o.size)
|
57
|
+
value = value.strip unless value.nil?
|
58
|
+
if hash.key? key
|
59
|
+
hash[key] = [hash[key], value].flatten
|
60
|
+
else
|
61
|
+
hash[key] = value
|
62
|
+
end
|
63
|
+
|
64
|
+
hash
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def status_message
|
71
|
+
return @status_message if @status_message != nil
|
72
|
+
|
73
|
+
# HTTP servers can choose not to include the explanation to HTTP codes. The RFC
|
74
|
+
# states this (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4):
|
75
|
+
# Except when responding to a HEAD request, the server SHOULD include an entity containing
|
76
|
+
# an explanation of the error situation [...]
|
77
|
+
# This means 'HTTP/1.1 404' is as valid as 'HTTP/1.1 404 Not Found' and we have to handle it.
|
78
|
+
|
79
|
+
# Regexp doc: http://rubular.com/r/eAr1oVYsVa
|
80
|
+
if first_header_line != nil and first_header_line[/\d{3} (.*)$/, 1] != nil
|
81
|
+
@status_message = first_header_line[/\d{3} (.*)$/, 1].chomp
|
82
|
+
else
|
83
|
+
@status_message = nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def http_version
|
88
|
+
@http_version ||= first_header_line ? first_header_line[/HTTP\/(\S+)/, 1] : nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def success?
|
92
|
+
@code >= 200 && @code < 300
|
93
|
+
end
|
94
|
+
|
95
|
+
def modified?
|
96
|
+
@code != 304
|
97
|
+
end
|
98
|
+
|
99
|
+
def timed_out?
|
100
|
+
curl_return_code == 28
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def first_header_line
|
106
|
+
@first_header_line ||= @headers.to_s.split("\n").first
|
107
|
+
end
|
108
|
+
|
109
|
+
def construct_header_string
|
110
|
+
lines = ["HTTP/#{http_version} #{code} #{status_message}"]
|
111
|
+
|
112
|
+
@headers_hash.each do |key, values|
|
113
|
+
[values].flatten.each do |value|
|
114
|
+
lines << "#{key}: #{value}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
lines << '' << ''
|
119
|
+
lines.join("\r\n")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Typhoeus
|
2
|
+
module Utils
|
3
|
+
# Taken from Rack::Utils, 1.2.1 to remove Rack dependency.
|
4
|
+
def escape(s)
|
5
|
+
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/u) {
|
6
|
+
'%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
|
7
|
+
}.tr(' ', '+')
|
8
|
+
end
|
9
|
+
module_function :escape
|
10
|
+
|
11
|
+
def escape_params(params)
|
12
|
+
traverse_params_hash(params)[:params].inject({}) do |memo, (k, v)|
|
13
|
+
memo[escape(k)] = escape(v)
|
14
|
+
memo
|
15
|
+
end
|
16
|
+
end
|
17
|
+
module_function :escape_params
|
18
|
+
|
19
|
+
# Params are NOT escaped.
|
20
|
+
def traverse_params_hash(hash, result = nil, current_key = nil)
|
21
|
+
result = ParamProcessor.traverse_params_hash hash, result, current_key
|
22
|
+
end
|
23
|
+
module_function :traverse_params_hash
|
24
|
+
|
25
|
+
def traversal_to_param_string(traversal, escape = true)
|
26
|
+
traversal[:params].collect { |param|
|
27
|
+
escape ? "#{Typhoeus::Utils.escape(param[0])}=#{Typhoeus::Utils.escape(param[1])}" : "#{param[0]}=#{param[1]}"
|
28
|
+
}.join('&')
|
29
|
+
end
|
30
|
+
module_function :traversal_to_param_string
|
31
|
+
|
32
|
+
# Return the bytesize of String; uses String#size under Ruby 1.8 and
|
33
|
+
# String#bytesize under 1.9.
|
34
|
+
if ''.respond_to?(:bytesize)
|
35
|
+
def bytesize(string)
|
36
|
+
string.bytesize
|
37
|
+
end
|
38
|
+
else
|
39
|
+
def bytesize(string)
|
40
|
+
string.size
|
41
|
+
end
|
42
|
+
end
|
43
|
+
module_function :bytesize
|
44
|
+
|
45
|
+
# Return a byteslice from a string; uses String#[] under Ruby 1.8 and
|
46
|
+
# String#byteslice under 1.9.
|
47
|
+
if ''.respond_to?(:byteslice)
|
48
|
+
def byteslice(string, *args)
|
49
|
+
string.byteslice(*args)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
def byteslice(string, *args)
|
53
|
+
string[*args]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
module_function :byteslice
|
57
|
+
end
|
58
|
+
end
|
data/lib/typhoeus.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'digest/sha2'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
require 'typhoeus/utils'
|
5
|
+
require 'typhoeus/header'
|
6
|
+
require 'typhoeus/curl'
|
7
|
+
require 'typhoeus/easy'
|
8
|
+
require 'typhoeus/form'
|
9
|
+
require 'typhoeus/multi'
|
10
|
+
require 'typhoeus/filter'
|
11
|
+
require 'typhoeus/param_processor'
|
12
|
+
require 'typhoeus/remote'
|
13
|
+
require 'typhoeus/remote_proxy_object'
|
14
|
+
require 'typhoeus/response'
|
15
|
+
require 'typhoeus/request'
|
16
|
+
require 'typhoeus/hydra'
|
17
|
+
require 'typhoeus/hydra_mock'
|
18
|
+
require 'typhoeus/version'
|
19
|
+
|
20
|
+
module Typhoeus
|
21
|
+
def self.easy_object_pool
|
22
|
+
@easy_objects ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.init_easy_object_pool
|
26
|
+
20.times do
|
27
|
+
easy_object_pool << Typhoeus::Easy.new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.release_easy_object(easy)
|
32
|
+
easy.reset
|
33
|
+
easy_object_pool << easy
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.get_easy_object
|
37
|
+
if easy_object_pool.empty?
|
38
|
+
Typhoeus::Easy.new
|
39
|
+
else
|
40
|
+
easy_object_pool.pop
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.add_easy_request(easy_object)
|
45
|
+
Thread.current[:curl_multi] ||= Typhoeus::Multi.new
|
46
|
+
Thread.current[:curl_multi].add(easy_object)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.perform_easy_requests
|
50
|
+
multi = Thread.current[:curl_multi]
|
51
|
+
start_time = Time.now
|
52
|
+
multi.easy_handles.each do |easy|
|
53
|
+
easy.start_time = start_time
|
54
|
+
end
|
55
|
+
multi.perform
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dcu-typhoeus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Balatero
|
9
|
+
- Paul Dix
|
10
|
+
- Hans Hasselberg
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-05-26 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: ffi
|
18
|
+
requirement: &70327899192580 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '1.0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *70327899192580
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mime-types
|
29
|
+
requirement: &70327899192100 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.18'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *70327899192100
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: activesupport
|
40
|
+
requirement: &70327899223600 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.2'
|
46
|
+
type: :runtime
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *70327899223600
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: sinatra
|
51
|
+
requirement: &70327899223120 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ~>
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '1.3'
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *70327899223120
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: json
|
62
|
+
requirement: &70327899222640 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '1.7'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: *70327899222640
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: rake
|
73
|
+
requirement: &70327899222160 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0.9'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: *70327899222160
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: mocha
|
84
|
+
requirement: &70327899221680 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.10'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: *70327899221680
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: rspec
|
95
|
+
requirement: &70327899221200 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '2.10'
|
101
|
+
type: :development
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: *70327899221200
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: guard-rspec
|
106
|
+
requirement: &70327899220720 !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0.6'
|
112
|
+
type: :development
|
113
|
+
prerelease: false
|
114
|
+
version_requirements: *70327899220720
|
115
|
+
description: Like a modern code version of the mythical beast with 100 serpent heads,
|
116
|
+
Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic.
|
117
|
+
email: hans.hasselberg@gmail.com
|
118
|
+
executables: []
|
119
|
+
extensions: []
|
120
|
+
extra_rdoc_files: []
|
121
|
+
files:
|
122
|
+
- lib/typhoeus/curl.rb
|
123
|
+
- lib/typhoeus/easy/auth.rb
|
124
|
+
- lib/typhoeus/easy/callbacks.rb
|
125
|
+
- lib/typhoeus/easy/ffi_helper.rb
|
126
|
+
- lib/typhoeus/easy/infos.rb
|
127
|
+
- lib/typhoeus/easy/options.rb
|
128
|
+
- lib/typhoeus/easy/proxy.rb
|
129
|
+
- lib/typhoeus/easy/ssl.rb
|
130
|
+
- lib/typhoeus/easy.rb
|
131
|
+
- lib/typhoeus/filter.rb
|
132
|
+
- lib/typhoeus/form.rb
|
133
|
+
- lib/typhoeus/header.rb
|
134
|
+
- lib/typhoeus/hydra/callbacks.rb
|
135
|
+
- lib/typhoeus/hydra/connect_options.rb
|
136
|
+
- lib/typhoeus/hydra/stubbing.rb
|
137
|
+
- lib/typhoeus/hydra.rb
|
138
|
+
- lib/typhoeus/hydra_mock.rb
|
139
|
+
- lib/typhoeus/multi.rb
|
140
|
+
- lib/typhoeus/param_processor.rb
|
141
|
+
- lib/typhoeus/remote.rb
|
142
|
+
- lib/typhoeus/remote_method.rb
|
143
|
+
- lib/typhoeus/remote_proxy_object.rb
|
144
|
+
- lib/typhoeus/request.rb
|
145
|
+
- lib/typhoeus/response.rb
|
146
|
+
- lib/typhoeus/utils.rb
|
147
|
+
- lib/typhoeus/version.rb
|
148
|
+
- lib/typhoeus.rb
|
149
|
+
- CHANGELOG.md
|
150
|
+
- Gemfile
|
151
|
+
- LICENSE
|
152
|
+
- README.md
|
153
|
+
- Rakefile
|
154
|
+
homepage: https://github.com/dbalatero/typhoeus
|
155
|
+
licenses: []
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- /Users/krawek/Projects/OpenSource/typhoeus/lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ! '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 1.3.6
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project: ! '[none]'
|
174
|
+
rubygems_version: 1.8.11
|
175
|
+
signing_key:
|
176
|
+
specification_version: 3
|
177
|
+
summary: Parallel HTTP library on top of libcurl multi.
|
178
|
+
test_files: []
|
179
|
+
has_rdoc:
|