ethon 0.0.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 +0 -0
- data/Gemfile +6 -0
- data/LICENSE +20 -0
- data/README.md +85 -0
- data/Rakefile +39 -0
- data/lib/ethon.rb +18 -0
- data/lib/ethon/curl.rb +586 -0
- data/lib/ethon/easies/callbacks.rb +80 -0
- data/lib/ethon/easies/form.rb +131 -0
- data/lib/ethon/easies/header.rb +65 -0
- data/lib/ethon/easies/http.rb +43 -0
- data/lib/ethon/easies/http/actionable.rb +99 -0
- data/lib/ethon/easies/http/delete.rb +23 -0
- data/lib/ethon/easies/http/get.rb +22 -0
- data/lib/ethon/easies/http/head.rb +22 -0
- data/lib/ethon/easies/http/options.rb +22 -0
- data/lib/ethon/easies/http/patch.rb +22 -0
- data/lib/ethon/easies/http/post.rb +18 -0
- data/lib/ethon/easies/http/postable.rb +27 -0
- data/lib/ethon/easies/http/put.rb +19 -0
- data/lib/ethon/easies/http/putable.rb +22 -0
- data/lib/ethon/easies/informations.rb +83 -0
- data/lib/ethon/easies/operations.rb +31 -0
- data/lib/ethon/easies/options.rb +105 -0
- data/lib/ethon/easies/params.rb +54 -0
- data/lib/ethon/easies/response_callbacks.rb +25 -0
- data/lib/ethon/easies/util.rb +41 -0
- data/lib/ethon/easy.rb +104 -0
- data/lib/ethon/errors.rb +13 -0
- data/lib/ethon/errors/ethon_error.rb +8 -0
- data/lib/ethon/errors/multi_add.rb +12 -0
- data/lib/ethon/errors/multi_fdset.rb +12 -0
- data/lib/ethon/errors/multi_remove.rb +11 -0
- data/lib/ethon/errors/multi_timeout.rb +12 -0
- data/lib/ethon/errors/select.rb +12 -0
- data/lib/ethon/extensions.rb +1 -0
- data/lib/ethon/extensions/string.rb +11 -0
- data/lib/ethon/multi.rb +47 -0
- data/lib/ethon/multies/operations.rb +132 -0
- data/lib/ethon/multies/stack.rb +43 -0
- data/lib/ethon/version.rb +5 -0
- metadata +217 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
module Http
|
4
|
+
|
5
|
+
# This class knows everything about making HEAD requests.
|
6
|
+
class Head
|
7
|
+
include Ethon::Easies::Http::Actionable
|
8
|
+
include Ethon::Easies::Http::Postable
|
9
|
+
|
10
|
+
# Setup url with escaped params and nobody.
|
11
|
+
#
|
12
|
+
# @example Setup.
|
13
|
+
# get.set_params(easy)
|
14
|
+
#
|
15
|
+
# @param [ Easy ] easy The easy to setup.
|
16
|
+
def set_customs(easy)
|
17
|
+
easy.nobody = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
module Http
|
4
|
+
|
5
|
+
# This class knows everything about making GET requests.
|
6
|
+
class Options
|
7
|
+
include Ethon::Easies::Http::Actionable
|
8
|
+
include Ethon::Easies::Http::Postable
|
9
|
+
|
10
|
+
# Setup url with escaped params and httpget.
|
11
|
+
#
|
12
|
+
# @example Setup.
|
13
|
+
# get.set_params(easy)
|
14
|
+
#
|
15
|
+
# @param [ Easy ] easy The easy to setup.
|
16
|
+
def set_customs(easy)
|
17
|
+
easy.customrequest = "OPTIONS"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
module Http
|
4
|
+
|
5
|
+
# This class knows everything about making PATCH requests.
|
6
|
+
class Patch
|
7
|
+
include Ethon::Easies::Http::Actionable
|
8
|
+
include Ethon::Easies::Http::Postable
|
9
|
+
|
10
|
+
# Setup url with escaped params and httpget.
|
11
|
+
#
|
12
|
+
# @example Setup.
|
13
|
+
# get.set_params(easy)
|
14
|
+
#
|
15
|
+
# @param [ Easy ] easy The easy to setup.
|
16
|
+
def set_customs(easy)
|
17
|
+
easy.customrequest = "PATCH"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
module Http
|
4
|
+
# This class knows everything about making POST requests.
|
5
|
+
class Post
|
6
|
+
include Ethon::Easies::Http::Actionable
|
7
|
+
include Ethon::Easies::Http::Postable
|
8
|
+
|
9
|
+
def set_customs(easy)
|
10
|
+
if form.empty?
|
11
|
+
easy.postfieldsize = 0
|
12
|
+
easy.copypostfields = ""
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
module Http
|
4
|
+
module Postable
|
5
|
+
# Set things up when form is provided.
|
6
|
+
# Deals with multipart forms.
|
7
|
+
#
|
8
|
+
# @example Setup.
|
9
|
+
# post.set_form(easy)
|
10
|
+
#
|
11
|
+
# @param [ Easy ] easy The easy to setup.
|
12
|
+
def set_form(easy)
|
13
|
+
easy.url ||= url
|
14
|
+
if form.multipart?
|
15
|
+
form.escape = false
|
16
|
+
form.materialize
|
17
|
+
easy.httppost = form.first.read_pointer
|
18
|
+
else
|
19
|
+
form.escape = true
|
20
|
+
easy.copypostfields = form.to_s
|
21
|
+
easy.postfieldsize = easy.copypostfields.bytesize
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
module Http
|
4
|
+
|
5
|
+
# This class knows everything about making PUT requests.
|
6
|
+
class Put
|
7
|
+
include Ethon::Easies::Http::Actionable
|
8
|
+
include Ethon::Easies::Http::Putable
|
9
|
+
|
10
|
+
def set_customs(easy)
|
11
|
+
if form.empty?
|
12
|
+
easy.upload = true
|
13
|
+
easy.infilesize = 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
module Http
|
4
|
+
module Putable
|
5
|
+
# Set things up when form is provided.
|
6
|
+
# Deals with multipart forms.
|
7
|
+
#
|
8
|
+
# @example Setup.
|
9
|
+
# put.set_form(easy)
|
10
|
+
#
|
11
|
+
# @param [ Easy ] easy The easy to setup.
|
12
|
+
def set_form(easy)
|
13
|
+
easy.url ||= url
|
14
|
+
easy.upload = true
|
15
|
+
form.escape = true
|
16
|
+
easy.infilesize = form.to_s.bytesize
|
17
|
+
easy.set_read_callback(form.to_s)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
|
4
|
+
# This module contains the methods to return informations
|
5
|
+
# from the easy handle. See http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html
|
6
|
+
# for more information.
|
7
|
+
module Informations
|
8
|
+
|
9
|
+
AVAILABLE_INFORMATIONS = {
|
10
|
+
# Return the available http auth methods.
|
11
|
+
:httpauth_avail => :long,
|
12
|
+
|
13
|
+
# Return the total time in seconds for the previous
|
14
|
+
# transfer, including name resolving, TCP connect etc.
|
15
|
+
:total_time => :double,
|
16
|
+
|
17
|
+
# Return the time, in seconds, it took from the start
|
18
|
+
# until the first byte is received by libcurl. This
|
19
|
+
# includes pretransfer time and also the time the
|
20
|
+
# server needs to calculate the result.
|
21
|
+
:starttransfer_time => :double,
|
22
|
+
|
23
|
+
# Return the time, in seconds, it took from the start
|
24
|
+
# until the SSL/SSH connect/handshake to the remote
|
25
|
+
# host was completed. This time is most often very near
|
26
|
+
# to the pre transfer time, except for cases such as HTTP
|
27
|
+
# pippelining where the pretransfer time can be delayed
|
28
|
+
# due to waits in line for the pipeline and more.
|
29
|
+
:appconnect_time => :double,
|
30
|
+
|
31
|
+
# Return the time, in seconds, it took from the start
|
32
|
+
# until the file transfer is just about to begin. This
|
33
|
+
# includes all pre-transfer commands and negotiations
|
34
|
+
# that are specific to the particular protocol(s) involved.
|
35
|
+
# It does not involve the sending of the protocol-
|
36
|
+
# specific request that triggers a transfer.
|
37
|
+
:pretransfer_time => :double,
|
38
|
+
|
39
|
+
# Return the time, in seconds, it took from the start
|
40
|
+
# until the connect to the remote host (or proxy) was completed.
|
41
|
+
:connect_time => :double,
|
42
|
+
|
43
|
+
# Return the time, in seconds, it took from the
|
44
|
+
# start until the name resolving was completed.
|
45
|
+
:namelookup_time => :double,
|
46
|
+
|
47
|
+
# Return the last used effective url.
|
48
|
+
:effective_url => :string,
|
49
|
+
|
50
|
+
# Return the string holding the IP address of the most recent
|
51
|
+
# connection done with this curl handle. This string
|
52
|
+
# may be IPv6 if that's enabled.
|
53
|
+
:primary_ip => :string,
|
54
|
+
|
55
|
+
# Return the last received HTTP, FTP or SMTP response code.
|
56
|
+
# The value will be zero if no server response code has
|
57
|
+
# been received. Note that a proxy's CONNECT response should
|
58
|
+
# be read with http_connect_code and not this.
|
59
|
+
:response_code => :long,
|
60
|
+
|
61
|
+
# Return the total number of redirections that were
|
62
|
+
# actually followed
|
63
|
+
:redirect_count => :long
|
64
|
+
}
|
65
|
+
|
66
|
+
AVAILABLE_INFORMATIONS.each do |name, type|
|
67
|
+
define_method(name) do
|
68
|
+
Curl.method("get_info_#{type}").call(name, handle)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns this curl version supports zlib.
|
73
|
+
#
|
74
|
+
# @example Return wether zlib is supported.
|
75
|
+
# easy.supports_zlib?
|
76
|
+
#
|
77
|
+
# @return [ Boolean ] True if supported, else false.
|
78
|
+
def supports_zlib?
|
79
|
+
!!(Curl.version.match(/zlib/))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
# This module contains the logic to prepare and perform
|
4
|
+
# an easy.
|
5
|
+
module Operations
|
6
|
+
|
7
|
+
# Perform the easy request.
|
8
|
+
#
|
9
|
+
# @example Perform the request.
|
10
|
+
# easy.perform
|
11
|
+
#
|
12
|
+
# @return [ Integer ] The return code.
|
13
|
+
def perform
|
14
|
+
@return_code = Curl.easy_perform(handle)
|
15
|
+
complete
|
16
|
+
@return_code
|
17
|
+
end
|
18
|
+
|
19
|
+
# Prepare the easy. Options, headers and callbacks
|
20
|
+
# were set.
|
21
|
+
#
|
22
|
+
# @example Prepare easy.
|
23
|
+
# easy.prepare
|
24
|
+
def prepare
|
25
|
+
set_options
|
26
|
+
set_headers
|
27
|
+
set_callbacks
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
|
4
|
+
# This module contains the logic and knowledge about the
|
5
|
+
# available options on easy.
|
6
|
+
module Options
|
7
|
+
|
8
|
+
# :nodoc:
|
9
|
+
def self.included(base)
|
10
|
+
base.extend ClassMethods
|
11
|
+
base.const_set(:AVAILABLE_OPTIONS, [
|
12
|
+
:httppost, :put, :httpget, :nobody, :upload, :customrequest,
|
13
|
+
:cainfo, :capath, :connecttimeout,
|
14
|
+
:followlocation, :httpauth, :infilesize, :interface,
|
15
|
+
:maxredirs, :nosignal, :postfieldsize, :copypostfields, :proxy,
|
16
|
+
:proxyauth, :proxytype, :timeout, :readdata, :sslcert, :ssl_verifypeer, :ssl_verifyhost,
|
17
|
+
:sslcerttype, :sslkey, :sslkeytype, :sslversion,
|
18
|
+
:url, :useragent, :userpwd, :verbose, :readfunction
|
19
|
+
])
|
20
|
+
base.send(:attr_accessor, *Ethon::Easy::AVAILABLE_OPTIONS)
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods # :nodoc:
|
24
|
+
|
25
|
+
# Return the available options.
|
26
|
+
#
|
27
|
+
# @example Return the available options.
|
28
|
+
# easy.available_options
|
29
|
+
#
|
30
|
+
# @return [ Array ] The available options.
|
31
|
+
def available_options
|
32
|
+
Ethon::Easy::AVAILABLE_OPTIONS
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return the options which need to set as 0 or 1 for easy.
|
36
|
+
#
|
37
|
+
# @example Return the bool options.
|
38
|
+
# easy.bool_options
|
39
|
+
#
|
40
|
+
# @return [ Array ] The bool options.
|
41
|
+
def bool_options
|
42
|
+
[
|
43
|
+
:followlocation, :nosignal, :ssl_verifypeer, :ssl_verifyhost,
|
44
|
+
:verbose, :httpget, :nobody, :upload
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return the options which are an enum for easy.
|
49
|
+
#
|
50
|
+
# @example Return the enum options.
|
51
|
+
# easy.enum_options
|
52
|
+
#
|
53
|
+
# @return [ Hash ] The enum options.
|
54
|
+
def enum_options
|
55
|
+
{ :httpauth => Curl::Auth }
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return the options which need to set as an integer for easy.
|
59
|
+
#
|
60
|
+
# @example Return the int options.
|
61
|
+
# easy.int_options
|
62
|
+
#
|
63
|
+
# @return [ Array ] The int options.
|
64
|
+
def int_options
|
65
|
+
[ :connecttimeout, :infilesize, :maxredirs, :postfieldsize, :timeout ]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Set specified options on easy handle.
|
70
|
+
#
|
71
|
+
# @example Set options.
|
72
|
+
# easy.set_options
|
73
|
+
def set_options
|
74
|
+
self.class.available_options.each do |option|
|
75
|
+
value = value_for(option)
|
76
|
+
next if value.nil?
|
77
|
+
|
78
|
+
Curl.set_option(option, value, handle)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return the value to set to easy handle. It is converted with the help
|
83
|
+
# of bool_options, enum_options and int_options.
|
84
|
+
#
|
85
|
+
# @example Return casted the value.
|
86
|
+
# easy.value_for(:verbose)
|
87
|
+
#
|
88
|
+
# @return [ Object ] The casted value.
|
89
|
+
def value_for(option)
|
90
|
+
value = method(option).call
|
91
|
+
return nil if value.nil?
|
92
|
+
|
93
|
+
if self.class.bool_options.include?(option)
|
94
|
+
value ? 1 : 0
|
95
|
+
elsif self.class.enum_options.key?(option)
|
96
|
+
self.class.enum_options[option][value]
|
97
|
+
elsif self.class.int_options.include?(option)
|
98
|
+
value.to_i
|
99
|
+
else
|
100
|
+
value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'ethon/easies/util'
|
2
|
+
|
3
|
+
module Ethon
|
4
|
+
module Easies
|
5
|
+
|
6
|
+
# This class represents http request parameters.
|
7
|
+
class Params
|
8
|
+
include Ethon::Easies::Util
|
9
|
+
attr_accessor :escape
|
10
|
+
|
11
|
+
# Create a new Params.
|
12
|
+
#
|
13
|
+
# @example Create a new Params.
|
14
|
+
# Params.new({})
|
15
|
+
#
|
16
|
+
# @param [ Hash ] params The params to use.
|
17
|
+
#
|
18
|
+
# @return [ Params ] A new Params.
|
19
|
+
def initialize(params)
|
20
|
+
@params = params || {}
|
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| 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_from_hash(@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
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Ethon
|
2
|
+
module Easies
|
3
|
+
|
4
|
+
# This module contains the logic for the response callbacks.
|
5
|
+
# The on_complete callback is the only one at the moment.
|
6
|
+
module ResponseCallbacks
|
7
|
+
# Execute preset complete callback.
|
8
|
+
#
|
9
|
+
# @example Execute complete callback.
|
10
|
+
# easy.complete
|
11
|
+
def complete
|
12
|
+
return if !defined?(@complete) || @complete.nil?
|
13
|
+
@complete.call(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Set complete callback.
|
17
|
+
#
|
18
|
+
# @example Set complete callback.
|
19
|
+
# easy.on_complete = block
|
20
|
+
def on_complete(&block)
|
21
|
+
@complete = block
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|