ethon 0.0.1

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