ethon 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|