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.
- data/CHANGELOG.md +14 -0
- data/README.md +36 -26
- data/lib/ethon.rb +2 -0
- data/lib/ethon/curl.rb +4 -0
- data/lib/ethon/curls/auth_types.rb +1 -1
- data/lib/ethon/curls/functions.rb +2 -0
- data/lib/ethon/easy.rb +12 -2
- data/lib/ethon/easy/callbacks.rb +2 -0
- data/lib/ethon/easy/form.rb +2 -0
- data/lib/ethon/easy/header.rb +2 -0
- data/lib/ethon/easy/http/actionable.rb +1 -0
- data/lib/ethon/easy/operations.rb +4 -0
- data/lib/ethon/easy/options.rb +8 -0
- data/lib/ethon/easy/params.rb +2 -0
- data/lib/ethon/easy/queryable.rb +1 -1
- data/lib/ethon/easy/response_callbacks.rb +2 -0
- data/lib/ethon/easy/util.rb +2 -0
- data/lib/ethon/errors/multi_fdset.rb +0 -1
- data/lib/ethon/multi.rb +4 -0
- data/lib/ethon/multi/operations.rb +26 -4
- data/lib/ethon/multi/stack.rb +2 -2
- data/lib/ethon/version.rb +3 -1
- metadata +3 -3
data/CHANGELOG.md
CHANGED
@@ -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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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.
|
data/lib/ethon.rb
CHANGED
data/lib/ethon/curl.rb
CHANGED
@@ -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
|
@@ -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
|
data/lib/ethon/easy.rb
CHANGED
@@ -201,12 +201,16 @@ module Ethon
|
|
201
201
|
|
202
202
|
class << self
|
203
203
|
|
204
|
-
#
|
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(:
|
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
|
data/lib/ethon/easy/callbacks.rb
CHANGED
data/lib/ethon/easy/form.rb
CHANGED
data/lib/ethon/easy/header.rb
CHANGED
@@ -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
|
data/lib/ethon/easy/options.rb
CHANGED
@@ -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?
|
data/lib/ethon/easy/params.rb
CHANGED
data/lib/ethon/easy/queryable.rb
CHANGED
@@ -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({:
|
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.
|
data/lib/ethon/easy/util.rb
CHANGED
data/lib/ethon/multi.rb
CHANGED
@@ -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 [
|
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
|
-
# @
|
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
|
-
# @
|
96
|
-
#
|
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)
|
data/lib/ethon/multi/stack.rb
CHANGED
@@ -21,7 +21,7 @@ module Ethon
|
|
21
21
|
#
|
22
22
|
# @param [ Easy ] easy The easy to add.
|
23
23
|
#
|
24
|
-
# @raise [Ethon::Errors::MultiAdd]
|
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]
|
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)
|
data/lib/ethon/version.rb
CHANGED
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.
|
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-
|
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:
|
124
|
+
hash: 2761547586556677808
|
125
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
126
|
none: false
|
127
127
|
requirements:
|