ethon 0.5.0 → 0.5.1

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.
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## Master
4
4
 
5
+ ## 0.5.1
6
+
7
+ [Full Changelog](http://github.com/typhoeus/ethon/compare/v0.5.0...0.5.1)
8
+
9
+ Bugfixes:
10
+
11
+ * Mark Curl.select and Curl.easy_perform as blocking so that the GIL is
12
+ released by ffi.
13
+
5
14
  ## 0.5.0
6
15
 
7
16
  [Full Changelog](http://github.com/typhoeus/ethon/compare/v0.4.4...0.5.0)
@@ -11,6 +20,11 @@ Enhancements:
11
20
  * New libcurl option proxyuserpwd
12
21
  * Rename response_header to response_headers
13
22
 
23
+ Bugfixes:
24
+
25
+ * Mark Curl.select and Curl.easy_perform as blocking so that the GIL is
26
+ released by ffi.
27
+
14
28
  ## 0.4.4
15
29
 
16
30
  [Full Changelog](http://github.com/typhoeus/ethon/compare/v0.4.3...v0.4.4)
data/README.md CHANGED
@@ -21,43 +21,53 @@ With rubygems:
21
21
 
22
22
  Making the first request is realy simple:
23
23
 
24
- easy = Ethon::Easy.new(:url => "www.google.de")
25
- easy.prepare
26
- easy.perform
27
- #=> :ok
24
+ ```ruby
25
+ easy = Ethon::Easy.new(url: "www.example.com")
26
+ easy.prepare
27
+ easy.perform
28
+ #=> :ok
29
+ ```
28
30
 
29
31
  You have access to various options like following redirects:
30
32
 
31
- easy = Ethon::Easy.new(:url => "www.google.com", :follow_location => true)
32
- easy.prepare
33
- easy.perform
34
- #=> :ok
33
+ ```ruby
34
+ easy = Ethon::Easy.new(url: "www.example.com", followlocation: true)
35
+ easy.prepare
36
+ easy.perform
37
+ #=> :ok
38
+ ```
35
39
 
36
40
  Once you're done you can look at the response code and body:
37
41
 
38
- easy = Ethon::Easy.new(:url => "www.google.de")
39
- easy.prepare
40
- easy.perform
41
- easy.response_code
42
- #=> 200
43
- easy.response_body
44
- #=> "<!doctype html><html ..."
42
+ ```ruby
43
+ easy = Ethon::Easy.new(url: "www.example.com", followlocation: true)
44
+ easy.prepare
45
+ easy.perform
46
+ easy.response_code
47
+ #=> 200
48
+ easy.response_body
49
+ #=> "<!doctype html><html ..."
50
+ ```
45
51
 
46
52
  ## Http
47
53
 
48
54
  In order to make life easier there are some helpers for doing http requests:
49
55
 
50
- easy = Ethon::Easy.new
51
- easy.http_request("www.google.de", :get, { :params => {:a => 1} })
52
- easy.prepare
53
- easy.perform
54
- #=> :ok
55
-
56
- easy = Ethon::Easy.new
57
- easy.http_request("www.google.de", :post, { :params => { :a => 1 }, :body => { :b => 2 } })
58
- easy.prepare
59
- easy.perform
60
- #=> :ok
56
+ ```ruby
57
+ easy = Ethon::Easy.new
58
+ easy.http_request("www.example.com", :get, { params: {a: 1} })
59
+ easy.prepare
60
+ easy.perform
61
+ #=> :ok
62
+ ```
63
+
64
+ ```ruby
65
+ easy = Ethon::Easy.new
66
+ easy.http_request("www.example.com", :post, { params: { a: 1 }, body: { b: 2 } })
67
+ easy.prepare
68
+ easy.perform
69
+ #=> :ok
70
+ ```
61
71
 
62
72
  This really handy when doing requests since you don't have to care about setting
63
73
  everything up correct.
@@ -18,5 +18,7 @@ require 'ethon/version'
18
18
  #
19
19
  # Ethon was extracted from Typhoeus. If you want to
20
20
  # see how others use Ethon look at the Typhoeus code.
21
+ #
22
+ # @see https://www.github.com/typhoeus/typhoeus Typhoeus
21
23
  module Ethon
22
24
  end
@@ -11,6 +11,8 @@ require 'ethon/curls/functions'
11
11
  module Ethon
12
12
 
13
13
  # FFI Wrapper module for Curl. Holds constants and required initializers.
14
+ #
15
+ # @api private
14
16
  module Curl
15
17
  extend ::FFI::Library
16
18
  extend Ethon::Curls::Codes
@@ -58,6 +60,8 @@ module Ethon
58
60
  # mean no other thread that is using libcurl. Because curl_global_init() calls
59
61
  # functions of other libraries that are similarly thread unsafe, it could conflict with
60
62
  # any other thread that uses these other libraries.
63
+ #
64
+ # @raise [ Ethon::Errors::GlobalInit ] If Curl.global_init fails.
61
65
  def init
62
66
  @@init_mutex.synchronize {
63
67
  if not @@initialized
@@ -1,5 +1,5 @@
1
1
  module Ethon
2
- module Curls
2
+ module Curls # :nodoc:
3
3
 
4
4
  # This module contain available auth types.
5
5
  module AuthTypes
@@ -19,6 +19,7 @@ module Ethon
19
19
  base.attach_function :easy_setopt_fixnum, :curl_easy_setopt, [:pointer, :easy_option, :long], :easy_code
20
20
  base.attach_function :easy_setopt_callback, :curl_easy_setopt, [:pointer, :easy_option, :callback], :easy_code
21
21
  base.attach_function :easy_setopt_proc, :curl_easy_setopt, [:pointer, :easy_option, :callback], :easy_code
22
+ base.instance_variable_set(:@blocking, true)
22
23
  base.attach_function :easy_perform, :curl_easy_perform, [:pointer], :easy_code
23
24
  base.attach_function :easy_strerror, :curl_easy_strerror, [:int], :string
24
25
  base.attach_function :easy_escape, :curl_easy_escape, [:pointer, :pointer, :int], :string
@@ -46,6 +47,7 @@ module Ethon
46
47
  base.attach_function :version, :curl_version, [], :string
47
48
  base.attach_function :slist_append, :curl_slist_append, [:pointer, :string], :pointer
48
49
  base.attach_function :slist_free_all, :curl_slist_free_all, [:pointer], :void
50
+ base.instance_variable_set(:@blocking, true)
49
51
  base.attach_function :select, [:int, Curl::FDSet.ptr, Curl::FDSet.ptr, Curl::FDSet.ptr, Curl::Timeval.ptr], :int
50
52
  end
51
53
  end
@@ -201,12 +201,16 @@ module Ethon
201
201
 
202
202
  class << self
203
203
 
204
- # Free libcurl representation from an easy handle.
204
+ # Frees libcurls easy represantation including its headers if any.
205
205
  #
206
206
  # @example Free easy handle.
207
207
  # Easy.finalizer(easy)
208
208
  #
209
209
  # @param [ Easy ] easy The easy to free.
210
+ #
211
+ # @see http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html
212
+ #
213
+ # @api private
210
214
  def finalizer(easy)
211
215
  proc {
212
216
  Curl.slist_free_all(easy.header_list) if easy.header_list
@@ -219,7 +223,7 @@ module Ethon
219
223
  # It initializes curl, if not already done and applies the provided options.
220
224
  #
221
225
  # @example Create a new Easy.
222
- # Easy.new(:url => "www.google.de")
226
+ # Easy.new(url: "www.google.de")
223
227
  #
224
228
  # @param [ Hash ] options The options to set.
225
229
  #
@@ -793,6 +797,8 @@ module Ethon
793
797
  # @return [ Easy ] A new Easy.
794
798
  #
795
799
  # @see http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
800
+ #
801
+ # @api public
796
802
  def initialize(options = {})
797
803
  Curl.init
798
804
  ObjectSpace.define_finalizer(self, self.class.finalizer(self))
@@ -809,6 +815,8 @@ module Ethon
809
815
  # @raise InvalidOption
810
816
  #
811
817
  # @see initialize
818
+ #
819
+ # @api private
812
820
  def set_attributes(options)
813
821
  options.each_pair do |key, value|
814
822
  unless respond_to?("#{key}=")
@@ -838,6 +846,8 @@ module Ethon
838
846
  # @param [ String ] value The value to escape.
839
847
  #
840
848
  # @return [ String ] The escaped value.
849
+ #
850
+ # @api private
841
851
  def escape(value)
842
852
  Curl.easy_escape(handle, value, 0)
843
853
  end
@@ -3,6 +3,8 @@ module Ethon
3
3
 
4
4
  # This module contains all the logic around the callbacks,
5
5
  # which are needed to interact with libcurl.
6
+ #
7
+ # @api private
6
8
  module Callbacks
7
9
 
8
10
  # :nodoc:
@@ -7,6 +7,8 @@ module Ethon
7
7
  # This class represents a form and is used to send a payload in the
8
8
  # request body via POST/PUT.
9
9
  # It handles multipart forms, too.
10
+ #
11
+ # @api private
10
12
  class Form
11
13
  include Ethon::Easy::Util
12
14
  include Ethon::Easy::Queryable
@@ -2,6 +2,8 @@ module Ethon
2
2
  class Easy
3
3
 
4
4
  # This module contains the logic around adding headers to libcurl.
5
+ #
6
+ # @api private
5
7
  module Header
6
8
 
7
9
  # Return headers, return empty hash if none.
@@ -70,6 +70,7 @@ module Ethon
70
70
  # @param [ easy ] easy the easy to setup.
71
71
  def setup(easy)
72
72
  @easy = easy
73
+ easy.url = url
73
74
  set_nothing(easy) if params.empty? && form.empty?
74
75
  set_params(easy) unless params.empty?
75
76
  set_form(easy) unless form.empty?
@@ -20,6 +20,8 @@ module Ethon
20
20
  # easy.perform
21
21
  #
22
22
  # @return [ Integer ] The return code.
23
+ #
24
+ # @api public
23
25
  def perform
24
26
  @return_code = Curl.easy_perform(handle)
25
27
  complete
@@ -32,6 +34,8 @@ module Ethon
32
34
  #
33
35
  # @example Prepare easy.
34
36
  # easy.prepare
37
+ #
38
+ # @api public
35
39
  def prepare
36
40
  set_options
37
41
  set_headers
@@ -3,6 +3,8 @@ module Ethon
3
3
 
4
4
  # This module contains the logic and knowledge about the
5
5
  # available options on easy.
6
+ #
7
+ # @api private
6
8
  module Options
7
9
 
8
10
  # :nodoc:
@@ -86,7 +88,13 @@ module Ethon
86
88
  # @example Return casted the value.
87
89
  # easy.value_for(:verbose)
88
90
  #
91
+ # @param [ Symbol ] option The option to get the value from.
92
+ #
89
93
  # @return [ Object ] The casted value.
94
+ #
95
+ # @raise [ Ethon::Errors::InvalidValue ] If specified option
96
+ # points to an enum and the value doen't correspond to
97
+ # the valid values.
90
98
  def value_for(option)
91
99
  value = method(option).call
92
100
  return nil if value.nil?
@@ -5,6 +5,8 @@ module Ethon
5
5
  class Easy
6
6
 
7
7
  # This class represents http request parameters.
8
+ #
9
+ # @api private
8
10
  class Params
9
11
  include Ethon::Easy::Util
10
12
  include Ethon::Easy::Queryable
@@ -49,7 +49,7 @@ module Ethon
49
49
  # Return query pairs build from a hash.
50
50
  #
51
51
  # @example Build query pairs.
52
- # action.build_query_pairs({:a => 1, :b => 2})
52
+ # action.build_query_pairs({a: 1, b: 2})
53
53
  # #=> [[:a, 1], [:b, 2]]
54
54
  #
55
55
  # @param [ Hash ] hash The hash to go through.
@@ -28,6 +28,8 @@ module Ethon
28
28
  # request.on_complete { p "yay" }
29
29
  #
30
30
  # @param [ Block ] block The block to execute.
31
+ #
32
+ # @api public
31
33
  def on_complete(&block)
32
34
  @on_complete ||= []
33
35
  @on_complete << block if block_given?
@@ -2,6 +2,8 @@ module Ethon
2
2
  class Easy # :nodoc:
3
3
 
4
4
  # This module contains small helpers.
5
+ #
6
+ # @api private
5
7
  module Util
6
8
 
7
9
  # Escapes zero bytes in strings.
@@ -5,7 +5,6 @@ module Ethon
5
5
  class MultiFdset < EthonError
6
6
  def initialize(code)
7
7
  super("An error occured getting the fdset: #{code}")
8
- # "an error occured getting the fdset: #{code}: #{Curl.multi_strerror(code)}"
9
8
  end
10
9
  end
11
10
  end
@@ -18,6 +18,8 @@ module Ethon
18
18
  # Multi.finalizer(multi)
19
19
  #
20
20
  # @param [ Multi ] multi The multi to free.
21
+ #
22
+ # @api private
21
23
  def finalizer(multi)
22
24
  proc {
23
25
  Curl.multi_cleanup(multi.handle)
@@ -92,6 +94,8 @@ module Ethon
92
94
  # @raise InvalidOption
93
95
  #
94
96
  # @see initialize
97
+ #
98
+ # @api private
95
99
  def set_attributes(options)
96
100
  options.each_pair do |key, value|
97
101
  unless respond_to?("#{key}=")
@@ -10,7 +10,7 @@ module Ethon
10
10
  # @example Return multi handle.
11
11
  # multi.handle
12
12
  #
13
- # @return [ ::FFI::Pointer ] The multi handle.
13
+ # @return [ FFI::Pointer ] The multi handle.
14
14
  def handle
15
15
  @handle ||= Curl.multi_init
16
16
  end
@@ -19,6 +19,8 @@ module Ethon
19
19
  #
20
20
  # @example Initialize variables.
21
21
  # multi.init_vars
22
+ #
23
+ # @return [ void ]
22
24
  def init_vars
23
25
  @timeout = ::FFI::MemoryPointer.new(:long)
24
26
  @timeval = Curl::Timeval.new
@@ -40,8 +42,12 @@ module Ethon
40
42
 
41
43
  # Perform multi.
42
44
  #
45
+ # @return [ nil ]
46
+ #
43
47
  # @example Perform multi.
44
48
  # multi.perform
49
+ #
50
+ # @api public
45
51
  def perform
46
52
  Ethon.logger.debug("ETHON: started MULTI")
47
53
  while ongoing?
@@ -57,8 +63,12 @@ module Ethon
57
63
 
58
64
  # Prepare multi.
59
65
  #
66
+ # @return [ nil ]
67
+ #
60
68
  # @example Prepare multi.
61
69
  # multi.prepare
70
+ #
71
+ # @api public
62
72
  def prepare
63
73
  set_options
64
74
  end
@@ -68,7 +78,9 @@ module Ethon
68
78
  # @example Get timeout.
69
79
  # multi.get_timeout
70
80
  #
71
- # @raise [Ethon::Errors::MultiTimeout] when getting the timeout failed.
81
+ # @return [ Integer ] The timeout.
82
+ #
83
+ # @raise [ Ethon::Errors::MultiTimeout ] If getting the timeout fails.
72
84
  def get_timeout
73
85
  code = Curl.multi_timeout(handle, @timeout)
74
86
  raise Errors::MultiTimeout.new(code) unless code == :ok
@@ -81,6 +93,8 @@ module Ethon
81
93
  #
82
94
  # @example Reset fds.
83
95
  # multi.reset_fds
96
+ #
97
+ # @return [ void ]
84
98
  def reset_fds
85
99
  @fd_read.clear
86
100
  @fd_write.clear
@@ -92,8 +106,10 @@ module Ethon
92
106
  # @example Set fds.
93
107
  # multi.set_fds
94
108
  #
95
- # @raise [Ethon::Errors::MultiFdset] when setting the file descriptors failed.
96
- # @raise [Ethon::Errors::Select] when select failed.
109
+ # @return [ void ]
110
+ #
111
+ # @raise [ Ethon::Errors::MultiFdset ] If setting the file descriptors fails.
112
+ # @raise [ Ethon::Errors::Select ] If select fails.
97
113
  def set_fds(timeout)
98
114
  code = Curl.multi_fdset(handle, @fd_read, @fd_write, @fd_excep, @max_fd)
99
115
  raise Errors::MultiFdset.new(code) unless code == :ok
@@ -112,6 +128,8 @@ module Ethon
112
128
  #
113
129
  # @example Check.
114
130
  # multi.check
131
+ #
132
+ # @return [ void ]
115
133
  def check
116
134
  msgs_left = ::FFI::MemoryPointer.new(:int)
117
135
  while true
@@ -130,6 +148,8 @@ module Ethon
130
148
  #
131
149
  # @example Run
132
150
  # multi.run
151
+ #
152
+ # @return [ void ]
133
153
  def run
134
154
  begin code = trigger end while code == :call_multi_perform
135
155
  check
@@ -139,6 +159,8 @@ module Ethon
139
159
  #
140
160
  # @example Trigger.
141
161
  # multi.trigger
162
+ #
163
+ # @return [ Symbol ] The Curl.multi_perform return code.
142
164
  def trigger
143
165
  running_count = FFI::MemoryPointer.new(:int)
144
166
  code = Curl.multi_perform(handle, running_count)
@@ -21,7 +21,7 @@ module Ethon
21
21
  #
22
22
  # @param [ Easy ] easy The easy to add.
23
23
  #
24
- # @raise [Ethon::Errors::MultiAdd] when adding an easy failed.
24
+ # @raise [ Ethon::Errors::MultiAdd ] If adding an easy failed.
25
25
  def add(easy)
26
26
  return nil if easy_handles.include?(easy)
27
27
 
@@ -36,7 +36,7 @@ module Ethon
36
36
  #
37
37
  # @param [ Easy ] easy The easy to delete.
38
38
  #
39
- # @raise [Ethon::Errors::MultiRemove] when removing an easy failed.
39
+ # @raise [ Ethon::Errors::MultiRemove ] If removing an easy failed.
40
40
  def delete(easy)
41
41
  if easy_handles.delete(easy)
42
42
  code = Curl.multi_remove_handle(handle, easy.handle)
@@ -1,5 +1,7 @@
1
1
  module Ethon
2
2
 
3
3
  # Ethon version.
4
- VERSION = '0.5.0'
4
+ #
5
+ # @api public
6
+ VERSION = '0.5.1'
5
7
  end
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.5.0
4
+ version: 0.5.1
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-09-25 00:00:00.000000000 Z
12
+ date: 2012-10-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
@@ -121,7 +121,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
121
  version: '0'
122
122
  segments:
123
123
  - 0
124
- hash: 3228494030236225352
124
+ hash: 2761547586556677808
125
125
  required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  none: false
127
127
  requirements: