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.
Files changed (42) hide show
  1. data/CHANGELOG.md +0 -0
  2. data/Gemfile +6 -0
  3. data/LICENSE +20 -0
  4. data/README.md +85 -0
  5. data/Rakefile +39 -0
  6. data/lib/ethon.rb +18 -0
  7. data/lib/ethon/curl.rb +586 -0
  8. data/lib/ethon/easies/callbacks.rb +80 -0
  9. data/lib/ethon/easies/form.rb +131 -0
  10. data/lib/ethon/easies/header.rb +65 -0
  11. data/lib/ethon/easies/http.rb +43 -0
  12. data/lib/ethon/easies/http/actionable.rb +99 -0
  13. data/lib/ethon/easies/http/delete.rb +23 -0
  14. data/lib/ethon/easies/http/get.rb +22 -0
  15. data/lib/ethon/easies/http/head.rb +22 -0
  16. data/lib/ethon/easies/http/options.rb +22 -0
  17. data/lib/ethon/easies/http/patch.rb +22 -0
  18. data/lib/ethon/easies/http/post.rb +18 -0
  19. data/lib/ethon/easies/http/postable.rb +27 -0
  20. data/lib/ethon/easies/http/put.rb +19 -0
  21. data/lib/ethon/easies/http/putable.rb +22 -0
  22. data/lib/ethon/easies/informations.rb +83 -0
  23. data/lib/ethon/easies/operations.rb +31 -0
  24. data/lib/ethon/easies/options.rb +105 -0
  25. data/lib/ethon/easies/params.rb +54 -0
  26. data/lib/ethon/easies/response_callbacks.rb +25 -0
  27. data/lib/ethon/easies/util.rb +41 -0
  28. data/lib/ethon/easy.rb +104 -0
  29. data/lib/ethon/errors.rb +13 -0
  30. data/lib/ethon/errors/ethon_error.rb +8 -0
  31. data/lib/ethon/errors/multi_add.rb +12 -0
  32. data/lib/ethon/errors/multi_fdset.rb +12 -0
  33. data/lib/ethon/errors/multi_remove.rb +11 -0
  34. data/lib/ethon/errors/multi_timeout.rb +12 -0
  35. data/lib/ethon/errors/select.rb +12 -0
  36. data/lib/ethon/extensions.rb +1 -0
  37. data/lib/ethon/extensions/string.rb +11 -0
  38. data/lib/ethon/multi.rb +47 -0
  39. data/lib/ethon/multies/operations.rb +132 -0
  40. data/lib/ethon/multies/stack.rb +43 -0
  41. data/lib/ethon/version.rb +5 -0
  42. 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