ethon 0.3.0 → 0.4.0
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 +16 -1
- data/lib/ethon/curl.rb +24 -537
- data/lib/ethon/curls/auth_types.rb +25 -0
- data/lib/ethon/curls/classes.rb +42 -0
- data/lib/ethon/curls/codes.rb +122 -0
- data/lib/ethon/curls/constants.rb +48 -0
- data/lib/ethon/curls/form_options.rb +36 -0
- data/lib/ethon/curls/functions.rb +46 -0
- data/lib/ethon/curls/infos.rb +154 -0
- data/lib/ethon/curls/messages.rb +18 -0
- data/lib/ethon/curls/options.rb +174 -0
- data/lib/ethon/curls/proxy_types.rb +25 -0
- data/lib/ethon/curls/settings.rb +7 -0
- data/lib/ethon/curls/ssl_versions.rb +23 -0
- data/lib/ethon/easies/callbacks.rb +3 -1
- data/lib/ethon/easies/form.rb +3 -33
- data/lib/ethon/easies/operations.rb +1 -0
- data/lib/ethon/easies/params.rb +2 -31
- data/lib/ethon/easies/queryable.rb +100 -0
- data/lib/ethon/easies/util.rb +3 -49
- data/lib/ethon/easy.rb +24 -6
- data/lib/ethon/loggable.rb +58 -0
- data/lib/ethon/multies/operations.rb +4 -0
- data/lib/ethon/version.rb +1 -1
- data/lib/ethon.rb +2 -1
- metadata +17 -5
- data/lib/ethon/extensions/string.rb +0 -40
- data/lib/ethon/extensions.rb +0 -1
data/lib/ethon/easies/form.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ethon/easies/util'
|
2
|
+
require 'ethon/easies/queryable'
|
2
3
|
|
3
4
|
module Ethon
|
4
5
|
module Easies
|
@@ -8,7 +9,7 @@ module Ethon
|
|
8
9
|
# It handles multipart forms, too.
|
9
10
|
class Form
|
10
11
|
include Ethon::Easies::Util
|
11
|
-
|
12
|
+
include Ethon::Easies::Queryable
|
12
13
|
|
13
14
|
# Return a new Form.
|
14
15
|
#
|
@@ -61,38 +62,7 @@ module Ethon
|
|
61
62
|
#
|
62
63
|
# @return [ Boolean ] True if form is multipart, else false.
|
63
64
|
def multipart?
|
64
|
-
query_pairs.any?{|pair| pair.last.is_a?(Array)}
|
65
|
-
end
|
66
|
-
|
67
|
-
# Return the query pairs.
|
68
|
-
#
|
69
|
-
# @example Return the query pairs.
|
70
|
-
# form.query_pairs
|
71
|
-
#
|
72
|
-
# @return [ Array ] The query pairs.
|
73
|
-
def query_pairs
|
74
|
-
@query_pairs ||= build_query_pairs(@params)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Return the string representation of the form. This makes only
|
78
|
-
# sense when the form is not multipart.
|
79
|
-
#
|
80
|
-
# @example Return string representation.
|
81
|
-
# form.to_s
|
82
|
-
#
|
83
|
-
# @return [ String ] The string representation.
|
84
|
-
def to_s
|
85
|
-
query_pairs.map{|pair| pair.map{|e| escape ? CGI::escape(e.to_s) : e }.join("=")}.join('&')
|
86
|
-
end
|
87
|
-
|
88
|
-
# Return wether there are elements in the form or not.
|
89
|
-
#
|
90
|
-
# @example Return if form is empty.
|
91
|
-
# form.empty?
|
92
|
-
#
|
93
|
-
# @return [ Boolean ] True if form is empty, else false.
|
94
|
-
def empty?
|
95
|
-
@params.empty?
|
65
|
+
query_pairs.any?{|pair| pair.respond_to?(:last) && pair.last.is_a?(Array)}
|
96
66
|
end
|
97
67
|
|
98
68
|
# Add form elements to libcurl.
|
data/lib/ethon/easies/params.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ethon/easies/util'
|
2
|
+
require 'ethon/easies/queryable'
|
2
3
|
|
3
4
|
module Ethon
|
4
5
|
module Easies
|
@@ -6,7 +7,7 @@ module Ethon
|
|
6
7
|
# This class represents http request parameters.
|
7
8
|
class Params
|
8
9
|
include Ethon::Easies::Util
|
9
|
-
|
10
|
+
include Ethon::Easies::Queryable
|
10
11
|
|
11
12
|
# Create a new Params.
|
12
13
|
#
|
@@ -19,36 +20,6 @@ module Ethon
|
|
19
20
|
def initialize(params)
|
20
21
|
@params = params || {}
|
21
22
|
end
|
22
|
-
|
23
|
-
# Return the string representation of params.
|
24
|
-
#
|
25
|
-
# @example Return string representation.
|
26
|
-
# params.to_s
|
27
|
-
#
|
28
|
-
# @return [ String ] The string representation.
|
29
|
-
def to_s
|
30
|
-
query_pairs.map{|pair| pair.map{|e| escape ? CGI::escape(e.to_s) : e }.join("=")}.join('&')
|
31
|
-
end
|
32
|
-
|
33
|
-
# Return the query pairs.
|
34
|
-
#
|
35
|
-
# @example Return the query pairs.
|
36
|
-
# params.query_pairs
|
37
|
-
#
|
38
|
-
# @return [ Array ] The query pairs.
|
39
|
-
def query_pairs
|
40
|
-
@query_pairs ||= build_query_pairs(@params)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Return wether there are elements in the params or not.
|
44
|
-
#
|
45
|
-
# @example Return if params is empty.
|
46
|
-
# params.empty?
|
47
|
-
#
|
48
|
-
# @return [ Boolean ] True if params is empty, else false.
|
49
|
-
def empty?
|
50
|
-
@params.empty?
|
51
|
-
end
|
52
23
|
end
|
53
24
|
end
|
54
25
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
|
4
|
+
# This module contains logic about building
|
5
|
+
# query parameters for url or form.
|
6
|
+
module Queryable
|
7
|
+
|
8
|
+
# :nodoc:
|
9
|
+
def self.included(base)
|
10
|
+
base.send(:attr_accessor, :escape)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return wether there are elements in the form or not.
|
14
|
+
#
|
15
|
+
# @example Return if form is empty.
|
16
|
+
# form.empty?
|
17
|
+
#
|
18
|
+
# @return [ Boolean ] True if form is empty, else false.
|
19
|
+
def empty?
|
20
|
+
@params.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return the string representation of params.
|
24
|
+
#
|
25
|
+
# @example Return string representation.
|
26
|
+
# params.to_s
|
27
|
+
#
|
28
|
+
# @return [ String ] The string representation.
|
29
|
+
def to_s
|
30
|
+
query_pairs.map{ |pair|
|
31
|
+
return pair if pair.is_a?(String)
|
32
|
+
|
33
|
+
pair.map{ |e|
|
34
|
+
escape ? CGI::escape(e.to_s) : e
|
35
|
+
}.join("=")
|
36
|
+
}.join('&')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return the query pairs.
|
40
|
+
#
|
41
|
+
# @example Return the query pairs.
|
42
|
+
# params.query_pairs
|
43
|
+
#
|
44
|
+
# @return [ Array ] The query pairs.
|
45
|
+
def query_pairs
|
46
|
+
@query_pairs ||= build_query_pairs(@params)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return query pairs build from a hash.
|
50
|
+
#
|
51
|
+
# @example Build query pairs.
|
52
|
+
# action.build_query_pairs({:a => 1, :b => 2})
|
53
|
+
# #=> [[:a, 1], [:b, 2]]
|
54
|
+
#
|
55
|
+
# @param [ Hash ] hash The hash to go through.
|
56
|
+
#
|
57
|
+
# @return [ Array ] The array of query pairs.
|
58
|
+
def build_query_pairs(hash)
|
59
|
+
return [hash] if hash.is_a?(String)
|
60
|
+
|
61
|
+
pairs = []
|
62
|
+
recursive = Proc.new do |h, prefix|
|
63
|
+
h.each_pair do |k,v|
|
64
|
+
key = prefix == '' ? k : "#{prefix}[#{k}]"
|
65
|
+
case v
|
66
|
+
when Hash
|
67
|
+
recursive.call(v, key)
|
68
|
+
when Array
|
69
|
+
v.each { |x| pairs << [key, x] }
|
70
|
+
when File, Tempfile
|
71
|
+
pairs << [Util.escape_zero_byte(key), file_info(v)]
|
72
|
+
else
|
73
|
+
pairs << [Util.escape_zero_byte(key), Util.escape_zero_byte(v)]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
recursive.call(hash, '')
|
78
|
+
pairs
|
79
|
+
end
|
80
|
+
|
81
|
+
# Return file info for a file.
|
82
|
+
#
|
83
|
+
# @example Return file info.
|
84
|
+
# action.file_info(File.open('fubar', 'r'))
|
85
|
+
#
|
86
|
+
# @param [ File ] file The file to handle.
|
87
|
+
#
|
88
|
+
# @return [ Array ] Array of informations.
|
89
|
+
def file_info(file)
|
90
|
+
filename = File.basename(file.path)
|
91
|
+
types = MIME::Types.type_for(filename)
|
92
|
+
[
|
93
|
+
filename,
|
94
|
+
types.empty? ? 'application/octet-stream' : types[0].to_s,
|
95
|
+
File.expand_path(file.path)
|
96
|
+
]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/ethon/easies/util.rb
CHANGED
@@ -4,54 +4,6 @@ module Ethon
|
|
4
4
|
# This module contains small helpers.
|
5
5
|
module Util
|
6
6
|
|
7
|
-
# Return query pairs build from a hash.
|
8
|
-
#
|
9
|
-
# @example Build query pairs.
|
10
|
-
# action.build_query_pairs({:a => 1, :b => 2})
|
11
|
-
# #=> [[:a, 1], [:b, 2]]
|
12
|
-
#
|
13
|
-
# @param [ Hash ] hash The hash to go through.
|
14
|
-
#
|
15
|
-
# @return [ Array ] The array of query pairs.
|
16
|
-
def build_query_pairs(hash)
|
17
|
-
pairs = []
|
18
|
-
recursive = Proc.new do |h, prefix|
|
19
|
-
h.each_pair do |k,v|
|
20
|
-
key = prefix == '' ? k : "#{prefix}[#{k}]"
|
21
|
-
case v
|
22
|
-
when Hash
|
23
|
-
recursive.call(v, key)
|
24
|
-
when Array
|
25
|
-
v.each { |x| pairs << [key, x] }
|
26
|
-
when File, Tempfile
|
27
|
-
pairs << [Util.escape_zero_byte(key), file_info(v)]
|
28
|
-
else
|
29
|
-
pairs << [Util.escape_zero_byte(key), Util.escape_zero_byte(v)]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
recursive.call(hash, '')
|
34
|
-
pairs
|
35
|
-
end
|
36
|
-
|
37
|
-
# Return file info for a file.
|
38
|
-
#
|
39
|
-
# @example Return file info.
|
40
|
-
# action.file_info(File.open('fubar', 'r'))
|
41
|
-
#
|
42
|
-
# @param [ File ] file The file to handle.
|
43
|
-
#
|
44
|
-
# @return [ Array ] Array of informations.
|
45
|
-
def file_info(file)
|
46
|
-
filename = File.basename(file.path)
|
47
|
-
types = MIME::Types.type_for(filename)
|
48
|
-
[
|
49
|
-
filename,
|
50
|
-
types.empty? ? 'application/octet-stream' : types[0].to_s,
|
51
|
-
File.expand_path(file.path)
|
52
|
-
]
|
53
|
-
end
|
54
|
-
|
55
7
|
# Escapes zero bytes in strings.
|
56
8
|
#
|
57
9
|
# @example Escape zero bytes.
|
@@ -62,10 +14,12 @@ module Ethon
|
|
62
14
|
#
|
63
15
|
# @return [ String, Object ] Escaped String if
|
64
16
|
# zero byte found, original object if not.
|
65
|
-
def
|
17
|
+
def escape_zero_byte(value)
|
66
18
|
return value unless value.to_s.include?(0.chr)
|
67
19
|
value.to_s.gsub(0.chr, '\\\0')
|
68
20
|
end
|
21
|
+
|
22
|
+
extend self
|
69
23
|
end
|
70
24
|
end
|
71
25
|
end
|
data/lib/ethon/easy.rb
CHANGED
@@ -192,14 +192,32 @@ module Ethon
|
|
192
192
|
#
|
193
193
|
# @return [ Hash ] The informations hash.
|
194
194
|
def to_hash
|
195
|
-
hash
|
196
|
-
hash
|
197
|
-
|
198
|
-
|
195
|
+
return @hash if defined?(@hash) && @hash
|
196
|
+
@hash = {
|
197
|
+
:return_code => return_code,
|
198
|
+
:response_header => response_header,
|
199
|
+
:response_body => response_body
|
200
|
+
}
|
199
201
|
Easies::Informations::AVAILABLE_INFORMATIONS.keys.each do |info|
|
200
|
-
hash[info] = method(info).call
|
202
|
+
@hash[info] = method(info).call
|
201
203
|
end
|
202
|
-
hash
|
204
|
+
@hash
|
205
|
+
end
|
206
|
+
|
207
|
+
# Return pretty log out.
|
208
|
+
#
|
209
|
+
# @example Return log out.
|
210
|
+
# easy.log_inspect
|
211
|
+
#
|
212
|
+
# @return [ String ] The log out.
|
213
|
+
def log_inspect
|
214
|
+
hash = {
|
215
|
+
:url => url,
|
216
|
+
:response_code => response_code,
|
217
|
+
:return_code => return_code,
|
218
|
+
:total_time => total_time
|
219
|
+
}
|
220
|
+
"EASY #{hash.map{|k, v| "#{k}=#{v}"}.flatten.join(' ')}"
|
203
221
|
end
|
204
222
|
end
|
205
223
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Ethon
|
3
|
+
|
4
|
+
# Contains logging behaviour.
|
5
|
+
module Loggable
|
6
|
+
|
7
|
+
# Get the logger.
|
8
|
+
#
|
9
|
+
# @note Will try to grab Rails' logger first before creating a new logger
|
10
|
+
# with stdout.
|
11
|
+
#
|
12
|
+
# @example Get the logger.
|
13
|
+
# Loggable.logger
|
14
|
+
#
|
15
|
+
# @return [ Logger ] The logger.
|
16
|
+
def logger
|
17
|
+
return @logger if defined?(@logger)
|
18
|
+
@logger = rails_logger || default_logger
|
19
|
+
end
|
20
|
+
|
21
|
+
# Set the logger.
|
22
|
+
#
|
23
|
+
# @example Set the logger.
|
24
|
+
# Loggable.logger = Logger.new($stdout)
|
25
|
+
#
|
26
|
+
# @param [ Logger ] logger The logger to set.
|
27
|
+
#
|
28
|
+
# @return [ Logger ] The new logger.
|
29
|
+
def logger=(logger)
|
30
|
+
@logger = logger
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Gets the default Ethon logger - stdout.
|
36
|
+
#
|
37
|
+
# @example Get the default logger.
|
38
|
+
# Loggable.default_logger
|
39
|
+
#
|
40
|
+
# @return [ Logger ] The default logger.
|
41
|
+
def default_logger
|
42
|
+
logger = Logger.new($stdout)
|
43
|
+
logger.level = Logger::INFO
|
44
|
+
logger
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get the Rails logger if it's defined.
|
48
|
+
#
|
49
|
+
# @example Get Rails' logger.
|
50
|
+
# Loggable.rails_logger
|
51
|
+
#
|
52
|
+
# @return [ Logger ] The Rails logger.
|
53
|
+
def rails_logger
|
54
|
+
defined?(::Rails) && ::Rails.respond_to?(:logger) && ::Rails.logger
|
55
|
+
end
|
56
|
+
end
|
57
|
+
extend Loggable
|
58
|
+
end
|
@@ -32,6 +32,7 @@ module Ethon
|
|
32
32
|
# @example Perform multi.
|
33
33
|
# multi.perform
|
34
34
|
def perform
|
35
|
+
Ethon.logger.debug("ETHON: started MULTI") if Ethon.logger
|
35
36
|
while ongoing?
|
36
37
|
run
|
37
38
|
timeout = get_timeout
|
@@ -39,6 +40,8 @@ module Ethon
|
|
39
40
|
reset_fds
|
40
41
|
set_fds(timeout)
|
41
42
|
end
|
43
|
+
Ethon.logger.debug("ETHON: performed MULTI") if Ethon.logger
|
44
|
+
nil
|
42
45
|
end
|
43
46
|
|
44
47
|
# Get timeout.
|
@@ -100,6 +103,7 @@ module Ethon
|
|
100
103
|
easy.return_code = msg[:data][:code]
|
101
104
|
delete(easy)
|
102
105
|
easy.complete
|
106
|
+
Ethon.logger.debug("ETHON: performed #{easy.log_inspect}") if Ethon.logger
|
103
107
|
end
|
104
108
|
end
|
105
109
|
|
data/lib/ethon/version.rb
CHANGED
data/lib/ethon.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'logger'
|
1
2
|
require 'ffi'
|
2
3
|
require 'rbconfig'
|
3
4
|
require 'thread'
|
@@ -5,11 +6,11 @@ require 'mime/types'
|
|
5
6
|
require 'cgi'
|
6
7
|
require 'tempfile'
|
7
8
|
|
8
|
-
require 'ethon/extensions'
|
9
9
|
require 'ethon/curl'
|
10
10
|
require 'ethon/errors'
|
11
11
|
require 'ethon/easy'
|
12
12
|
require 'ethon/multi'
|
13
|
+
require 'ethon/loggable'
|
13
14
|
require 'ethon/version'
|
14
15
|
|
15
16
|
# Ethon is a very simple libcurl.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ethon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -195,6 +195,18 @@ extensions: []
|
|
195
195
|
extra_rdoc_files: []
|
196
196
|
files:
|
197
197
|
- lib/ethon/curl.rb
|
198
|
+
- lib/ethon/curls/auth_types.rb
|
199
|
+
- lib/ethon/curls/classes.rb
|
200
|
+
- lib/ethon/curls/codes.rb
|
201
|
+
- lib/ethon/curls/constants.rb
|
202
|
+
- lib/ethon/curls/form_options.rb
|
203
|
+
- lib/ethon/curls/functions.rb
|
204
|
+
- lib/ethon/curls/infos.rb
|
205
|
+
- lib/ethon/curls/messages.rb
|
206
|
+
- lib/ethon/curls/options.rb
|
207
|
+
- lib/ethon/curls/proxy_types.rb
|
208
|
+
- lib/ethon/curls/settings.rb
|
209
|
+
- lib/ethon/curls/ssl_versions.rb
|
198
210
|
- lib/ethon/easies/callbacks.rb
|
199
211
|
- lib/ethon/easies/form.rb
|
200
212
|
- lib/ethon/easies/header.rb
|
@@ -213,6 +225,7 @@ files:
|
|
213
225
|
- lib/ethon/easies/operations.rb
|
214
226
|
- lib/ethon/easies/options.rb
|
215
227
|
- lib/ethon/easies/params.rb
|
228
|
+
- lib/ethon/easies/queryable.rb
|
216
229
|
- lib/ethon/easies/response_callbacks.rb
|
217
230
|
- lib/ethon/easies/util.rb
|
218
231
|
- lib/ethon/easy.rb
|
@@ -226,8 +239,7 @@ files:
|
|
226
239
|
- lib/ethon/errors/multi_timeout.rb
|
227
240
|
- lib/ethon/errors/select.rb
|
228
241
|
- lib/ethon/errors.rb
|
229
|
-
- lib/ethon/
|
230
|
-
- lib/ethon/extensions.rb
|
242
|
+
- lib/ethon/loggable.rb
|
231
243
|
- lib/ethon/multi.rb
|
232
244
|
- lib/ethon/multies/operations.rb
|
233
245
|
- lib/ethon/multies/stack.rb
|
@@ -252,7 +264,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
252
264
|
version: '0'
|
253
265
|
segments:
|
254
266
|
- 0
|
255
|
-
hash:
|
267
|
+
hash: 2336974979301889597
|
256
268
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
257
269
|
none: false
|
258
270
|
requirements:
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module Ethon
|
2
|
-
|
3
|
-
# This module contains all core extensions ethon
|
4
|
-
# needs.
|
5
|
-
module Extensions
|
6
|
-
module String # :nodoc:
|
7
|
-
|
8
|
-
unless ''.respond_to?(:byteslice)
|
9
|
-
# Return part of the string.
|
10
|
-
#
|
11
|
-
# @return [ String ] Part of the string.
|
12
|
-
def byteslice(*args)
|
13
|
-
self[*args]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Convert string to underscore. Taken from
|
18
|
-
# activesupport, renamed in order to no collide
|
19
|
-
# with it.
|
20
|
-
#
|
21
|
-
# @example Underscore.
|
22
|
-
# "ClassName".underscr
|
23
|
-
# #=> "class_name"
|
24
|
-
#
|
25
|
-
# @return [ String ] Underscore string.
|
26
|
-
def underscr
|
27
|
-
word = self.dup
|
28
|
-
word.gsub!('::', '_')
|
29
|
-
word.gsub!(/(?:([A-Za-z\d])|^)(#{/(?=a)b/})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
|
30
|
-
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
31
|
-
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
32
|
-
word.tr!("-", "_")
|
33
|
-
word.downcase!
|
34
|
-
word
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
::String.__send__(:include, Ethon::Extensions::String)
|
data/lib/ethon/extensions.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'ethon/extensions/string.rb'
|