ethon 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- attr_accessor :escape
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.
@@ -13,6 +13,7 @@ module Ethon
13
13
  def perform
14
14
  @return_code = Curl.easy_perform(handle)
15
15
  complete
16
+ Ethon.logger.debug("ETHON: performed #{self.log_inspect}") if Ethon.logger
16
17
  @return_code
17
18
  end
18
19
 
@@ -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
- attr_accessor :escape
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
@@ -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 self.escape_zero_byte(value)
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[:return_code] = return_code
197
- hash[:response_header] = response_header
198
- hash[:response_body] = response_body
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
@@ -1,5 +1,5 @@
1
1
  module Ethon
2
2
 
3
3
  # Ethon version.
4
- VERSION = '0.3.0'
4
+ VERSION = '0.4.0'
5
5
  end
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.3.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-02 00:00:00.000000000 Z
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/extensions/string.rb
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: 1054475577707452411
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)
@@ -1 +0,0 @@
1
- require 'ethon/extensions/string.rb'