ethon 0.5.10 → 0.5.11

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 CHANGED
@@ -2,7 +2,26 @@
2
2
 
3
3
  ## Master
4
4
 
5
- [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.5.10...master)
5
+ [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.5.11...master)
6
+
7
+ ## 0.5.11
8
+
9
+ [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.5.10...v0.5.11)
10
+
11
+ Enhancements:
12
+
13
+ * Add support for postredirs, unrestricted_auth.
14
+ * Add support for cookie, cookiejar, cookiefile.
15
+ ([erwanlr](https://github.com/erwanlr), [\#46](https://github.com/typhoeus/ethon/pull/46))
16
+ * Relax ffi requirements.
17
+ ([voxik](https://github.com/voxik), [\#40](https://github.com/typhoeus/ethon/pull/40))
18
+ * Various documentation improvements.
19
+ ([craiglittle](https://github.com/craiglittle))
20
+
21
+ Bugfixes:
22
+
23
+ * Fix the memory leaks.
24
+ ([richievos](https://github.com/richievos), [\#45](https://github.com/typhoeus/ethon/pull/45))
6
25
 
7
26
  ## 0.5.10
8
27
 
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
4
  gem "rake"
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # Ethon [![Build Status](https://secure.travis-ci.org/typhoeus/ethon.png?branch=master)](http://travis-ci.org/typhoeus/ethon)
2
2
 
3
- In the greek mythology Ethon is a gigantic eagle the son of Typhoeus and Echidna. So much for the history.
4
- In the modern world Ethon is a very basic libcurl wrapper using ffi.
3
+ In Greek mythology, Ethon, the son of Typhoeus and Echidna, is a gigantic eagle. So much for the history.
4
+ In the modern world, Ethon is a very basic libcurl wrapper using ffi.
5
5
 
6
6
  * [Documentation](http://rubydoc.info/github/typhoeus/ethon/frames/Ethon)
7
7
  * [Website](http://typhoeus.github.com/)
8
- * [Mailinglist](http://groups.google.com/group/typhoeus)
8
+ * [Mailing list](http://groups.google.com/group/typhoeus)
9
9
 
10
10
  ## Installation
11
11
 
@@ -19,7 +19,7 @@ With rubygems:
19
19
 
20
20
  ## Usage
21
21
 
22
- Making the first request is realy simple:
22
+ Making the first request is simple:
23
23
 
24
24
  ```ruby
25
25
  easy = Ethon::Easy.new(url: "www.example.com")
@@ -27,7 +27,7 @@ easy.perform
27
27
  #=> :ok
28
28
  ```
29
29
 
30
- You have access to various options like following redirects:
30
+ You have access to various options, such as following redirects:
31
31
 
32
32
  ```ruby
33
33
  easy = Ethon::Easy.new(url: "www.example.com", followlocation: true)
@@ -35,7 +35,7 @@ easy.perform
35
35
  #=> :ok
36
36
  ```
37
37
 
38
- Once you're done you can look at the response code and body:
38
+ Once you're done you can inspect the response code and body:
39
39
 
40
40
  ```ruby
41
41
  easy = Ethon::Easy.new(url: "www.example.com", followlocation: true)
@@ -48,7 +48,7 @@ easy.response_body
48
48
 
49
49
  ## Http
50
50
 
51
- In order to make life easier there are some helpers for doing http requests:
51
+ In order to make life easier, there are some helpers for making HTTP requests:
52
52
 
53
53
  ```ruby
54
54
  easy = Ethon::Easy.new
@@ -64,14 +64,14 @@ easy.perform
64
64
  #=> :ok
65
65
  ```
66
66
 
67
- This really handy when doing requests since you don't have to care about setting
68
- everything up correct.
67
+ This is really handy when making requests since you don't have to care about setting
68
+ everything up correctly.
69
69
 
70
70
  ## LICENSE
71
71
 
72
72
  (The MIT License)
73
73
 
74
- Copyright © 2012 [Hans Hasselberg](http://www.hans.io)
74
+ Copyright © 2012-2013 [Hans Hasselberg](http://www.hans.io)
75
75
 
76
76
  Permission is hereby granted, free of charge, to any person obtaining a
77
77
  copy of this software and associated documentation files (the "Software"),
data/lib/ethon/curl.rb CHANGED
@@ -4,6 +4,7 @@ require 'ethon/curls/http_versions'
4
4
  require 'ethon/curls/infos'
5
5
  require 'ethon/curls/form_options'
6
6
  require 'ethon/curls/auth_types'
7
+ require 'ethon/curls/postredir'
7
8
  require 'ethon/curls/protocols'
8
9
  require 'ethon/curls/proxy_types'
9
10
  require 'ethon/curls/ssl_versions'
@@ -27,6 +28,7 @@ module Ethon
27
28
  extend Ethon::Curls::SslVersions
28
29
  extend Ethon::Curls::Messages
29
30
  extend Ethon::Curls::Protocols
31
+ extend Ethon::Curls::Postredir
30
32
 
31
33
  # :nodoc:
32
34
  def self.windows?
@@ -38,6 +38,9 @@ module Ethon
38
38
  # :nodoc:
39
39
  Auth = enum(auth_types.to_a.flatten)
40
40
 
41
+ # :nodoc:
42
+ Postredir = enum(postredir.to_a.flatten)
43
+
41
44
  # :nodoc:
42
45
  Protocols = enum(protocols.to_a.flatten)
43
46
 
@@ -23,10 +23,11 @@ module Ethon
23
23
  base.instance_variable_set(:@blocking, true)
24
24
  base.attach_function :easy_perform, :curl_easy_perform, [:pointer], :easy_code
25
25
  base.attach_function :easy_strerror, :curl_easy_strerror, [:int], :string
26
- base.attach_function :easy_escape, :curl_easy_escape, [:pointer, :pointer, :int], :string
26
+ base.attach_function :easy_escape, :curl_easy_escape, [:pointer, :pointer, :int], :pointer
27
27
  base.attach_function :easy_reset, :curl_easy_reset, [:pointer], :void
28
28
 
29
29
  base.attach_function :formadd, :curl_formadd, [:pointer, :pointer, :varargs], :int
30
+ base.attach_function :formfree, :curl_formfree, [:pointer], :void
30
31
 
31
32
  base.attach_function :multi_init, :curl_multi_init, [], :pointer
32
33
  base.attach_function :multi_cleanup, :curl_multi_cleanup, [:pointer], :void
@@ -178,6 +178,7 @@ module Ethon
178
178
  :connecttimeout_ms => option_types[:long] + 156,
179
179
  :http_transfer_decoding => option_types[:long] + 157,
180
180
  :http_content_decoding => option_types[:long] + 158,
181
+ :postredir => option_types[:long] + 161,
181
182
  :copypostfields => option_types[:object_point] + 165,
182
183
  :proxy_transfer_mode => option_types[:long] + 166,
183
184
  :seekfunction => option_types[:function_point] + 167,
@@ -0,0 +1,15 @@
1
+ module Ethon
2
+ module Curls
3
+ module Postredir
4
+ def postredir
5
+ {
6
+ :get_all => 0x00,
7
+ :post_301 => 0x01,
8
+ :post_302 => 0x02,
9
+ :post_303 => 0x04,
10
+ :post_all => 0x07
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/ethon/easy.rb CHANGED
@@ -196,26 +196,6 @@ module Ethon
196
196
  # @see http://curl.haxx.se/libcurl/c/libcurl-errors.html
197
197
  attr_accessor :return_code
198
198
 
199
- class << self
200
-
201
- # Frees libcurls easy represantation including its headers if any.
202
- #
203
- # @example Free easy handle.
204
- # Easy.finalizer(easy)
205
- #
206
- # @param [ Easy ] easy The easy to free.
207
- #
208
- # @see http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html
209
- #
210
- # @api private
211
- def finalizer(easy)
212
- proc {
213
- Curl.slist_free_all(easy.header_list) if easy.header_list
214
- Curl.easy_cleanup(easy.handle)
215
- }
216
- end
217
- end
218
-
219
199
  # Initialize a new Easy.
220
200
  # It initializes curl, if not already done and applies the provided options.
221
201
  # Look into {Ethon::Easy::Options Options} to see what you can provide in the
@@ -233,7 +213,6 @@ module Ethon
233
213
  # @see http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
234
214
  def initialize(options = {})
235
215
  Curl.init
236
- ObjectSpace.define_finalizer(self, self.class.finalizer(self))
237
216
  set_attributes(options)
238
217
  set_callbacks
239
218
  end
@@ -281,7 +260,10 @@ module Ethon
281
260
  #
282
261
  # @api private
283
262
  def escape(value)
284
- Curl.easy_escape(handle, value, 0)
263
+ string_pointer = Curl.easy_escape(handle, value, 0)
264
+ returned_string = string_pointer.read_string
265
+ Curl.free(string_pointer)
266
+ returned_string
285
267
  end
286
268
 
287
269
  # Returns the informations available through libcurl as
@@ -18,23 +18,12 @@ module Ethon
18
18
  # @example Return a new Form.
19
19
  # Form.new({})
20
20
  #
21
- # @param [ Hash ] params The parameter to initialize the form with.
21
+ # @param [ Hash ] params The parameter with which to initialize the form.
22
22
  #
23
23
  # @return [ Form ] A new Form.
24
24
  def initialize(easy, params)
25
25
  @easy = easy
26
26
  @params = params || {}
27
- ObjectSpace.define_finalizer(self, self.class.finalizer(self))
28
- end
29
-
30
- # Frees form in libcurl if necessary.
31
- #
32
- # @example Free the form
33
- # Form.finalizer(form)
34
- #
35
- # @param [ Form ] form The form to free.
36
- def self.finalizer(form)
37
- proc { Curl.formfree(form.first) if form.multipart? }
38
27
  end
39
28
 
40
29
  # Return a pointer to the first form element in libcurl.
@@ -57,7 +46,7 @@ module Ethon
57
46
  @last ||= FFI::MemoryPointer.new(:pointer)
58
47
  end
59
48
 
60
- # Return if form is multipart. The form is multipart,
49
+ # Return if form is multipart. The form is multipart
61
50
  # when it contains a file.
62
51
  #
63
52
  # @example Return if form is multipart.
@@ -98,6 +87,17 @@ module Ethon
98
87
  :form_option, :end
99
88
  )
100
89
  end
90
+
91
+ setup_garbage_collection
92
+ end
93
+
94
+ def setup_garbage_collection
95
+ # first is a pointer to a pointer. Since it's a MemoryPointer it will
96
+ # auto clean itself up, but we need to clean up the object it points
97
+ # to. So this results in (pseudo-c):
98
+ # form_data_cleanup_handler = *first
99
+ # curl_form_free(form_data_cleanup_handler)
100
+ @form_data_cleanup_handler ||= FFI::AutoPointer.new(@first.get_pointer(0), Curl.method(:formfree))
101
101
  end
102
102
  end
103
103
  end
@@ -1,11 +1,9 @@
1
1
  module Ethon
2
2
  class Easy
3
-
4
3
  # This module contains the logic around adding headers to libcurl.
5
4
  #
6
5
  # @api private
7
6
  module Header
8
-
9
7
  # Return headers, return empty hash if none.
10
8
  #
11
9
  # @example Return the headers.
@@ -24,9 +22,13 @@ module Ethon
24
22
  # @param [ Hash ] headers The headers.
25
23
  def headers=(headers)
26
24
  headers ||= {}
27
- @header_list = nil
28
- headers.each {|k, v| @header_list = Curl.slist_append(@header_list, compose_header(k,v)) }
29
- Curl.set_option(:httpheader, @header_list, handle)
25
+ header_list = nil
26
+ headers.each do |k, v|
27
+ header_list = Curl.slist_append(header_list, compose_header(k,v))
28
+ end
29
+ Curl.set_option(:httpheader, header_list, handle)
30
+
31
+ @header_list = header_list && FFI::AutoPointer.new(header_list, Curl.method(:slist_free_all))
30
32
  end
31
33
 
32
34
  # Return header_list.
@@ -36,11 +38,11 @@ module Ethon
36
38
  #
37
39
  # @return [ FFI::Pointer ] The header list.
38
40
  def header_list
39
- @header_list ||= nil
41
+ @header_list
40
42
  end
41
43
 
42
44
  # Compose libcurl header string from key and value.
43
- # Also replaces null bytes, because libcurl will complain about
45
+ # Also replaces null bytes, because libcurl will complain
44
46
  # otherwise.
45
47
  #
46
48
  # @example Compose header.
@@ -11,25 +11,25 @@ require 'ethon/easy/http/custom'
11
11
  module Ethon
12
12
  class Easy
13
13
 
14
- # This module contains logic about making valid http requests.
14
+ # This module contains logic about making valid HTTP requests.
15
15
  module Http
16
16
 
17
- # Set specified options in order to make a http request.
18
- # Look into {Ethon::Easy::Options Options} to see what you can
17
+ # Set specified options in order to make a HTTP request.
18
+ # Look at {Ethon::Easy::Options Options} to see what you can
19
19
  # provide in the options hash.
20
20
  #
21
- # @example Set options for http request.
21
+ # @example Set options for HTTP request.
22
22
  # easy.http_request("www.google.com", :get, {})
23
23
  #
24
24
  # @param [ String ] url The url.
25
- # @param [ String ] action_name The http action name.
25
+ # @param [ String ] action_name The HTTP action name.
26
26
  # @param [ Hash ] options The options hash.
27
27
  #
28
28
  # @option options :params [ Hash ] Params hash which
29
29
  # is attached to the url.
30
30
  # @option options :body [ Hash ] Body hash which
31
31
  # becomes the request body. It is a PUT body for
32
- # PUT requests and a POST from for everything else.
32
+ # PUT requests and a POST for everything else.
33
33
  # @option options :headers [ Hash ] Request headers.
34
34
  #
35
35
  # @return [ void ]
@@ -48,7 +48,7 @@ module Ethon
48
48
  # Action.fabricate(:smash)
49
49
  #
50
50
  # @param [ String ] url The url.
51
- # @param [ String ] action_name The http action name.
51
+ # @param [ String ] action_name The HTTP action name.
52
52
  # @param [ Hash ] options The option hash.
53
53
  #
54
54
  # @return [ Easy::Ethon::Actionable ] The request instance.
@@ -9,29 +9,29 @@ module Ethon
9
9
  # Holds available informations and their type, which is needed to
10
10
  # request the informations from libcurl.
11
11
  AVAILABLE_INFORMATIONS = {
12
- # Return the available http auth methods.
12
+ # Return the available HTTP auth methods.
13
13
  :httpauth_avail => :long,
14
14
 
15
15
  # Return the total time in seconds for the previous
16
- # transfer, including name resolving, TCP connect etc.
16
+ # transfer, including name resolution, TCP connection, etc.
17
17
  :total_time => :double,
18
18
 
19
19
  # Return the time, in seconds, it took from the start
20
- # until the first byte is received by libcurl. This
21
- # includes pretransfer time and also the time the
20
+ # until the first byte was received by libcurl. This
21
+ # includes pre-transfer time and also the time the
22
22
  # server needs to calculate the result.
23
23
  :starttransfer_time => :double,
24
24
 
25
25
  # Return the time, in seconds, it took from the start
26
26
  # until the SSL/SSH connect/handshake to the remote
27
27
  # host was completed. This time is most often very near
28
- # to the pre transfer time, except for cases such as HTTP
29
- # pippelining where the pretransfer time can be delayed
28
+ # to the pre-transfer time, except for cases such as HTTP
29
+ # pipelining where the pre-transfer time can be delayed
30
30
  # due to waits in line for the pipeline and more.
31
31
  :appconnect_time => :double,
32
32
 
33
33
  # Return the time, in seconds, it took from the start
34
- # until the file transfer is just about to begin. This
34
+ # until the file transfer was just about to begin. This
35
35
  # includes all pre-transfer commands and negotiations
36
36
  # that are specific to the particular protocol(s) involved.
37
37
  # It does not involve the sending of the protocol-
@@ -43,7 +43,7 @@ module Ethon
43
43
  :connect_time => :double,
44
44
 
45
45
  # Return the time, in seconds, it took from the
46
- # start until the name resolving was completed.
46
+ # start until the name resolution was completed.
47
47
  :namelookup_time => :double,
48
48
 
49
49
  # Return the last used effective url.
@@ -61,7 +61,7 @@ module Ethon
61
61
  :response_code => :long,
62
62
 
63
63
  # Return the total number of redirections that were
64
- # actually followed
64
+ # actually followed.
65
65
  :redirect_count => :long
66
66
  }
67
67
 
@@ -3,7 +3,6 @@ module Ethon
3
3
  # This module contains the logic to prepare and perform
4
4
  # an easy.
5
5
  module Operations
6
-
7
6
  # Returns a pointer to the curl easy handle.
8
7
  #
9
8
  # @example Return the handle.
@@ -11,7 +10,7 @@ module Ethon
11
10
  #
12
11
  # @return [ FFI::Pointer ] A pointer to the curl easy handle.
13
12
  def handle
14
- @handle ||= Curl.easy_init
13
+ @handle ||= FFI::AutoPointer.new(Curl.easy_init, Curl.method(:easy_cleanup))
15
14
  end
16
15
 
17
16
  # Perform the easy request.
@@ -36,8 +35,8 @@ module Ethon
36
35
  # @deprecated It is no longer necessary to call prepare.
37
36
  def prepare
38
37
  Ethon.logger.warn(
39
- "ETHON: It is no longer necessay to call "+
40
- "Easy#prepare. Its going to be removed "+
38
+ "ETHON: It is no longer necessary to call "+
39
+ "Easy#prepare. It's going to be removed "+
41
40
  "in future versions."
42
41
  )
43
42
  end
@@ -31,15 +31,14 @@ module Ethon
31
31
  Curl.set_option(:accept_encoding, value_for(value, :string), handle)
32
32
  end
33
33
 
34
- # Pass a string to a zero terminated
35
- # string naming a file holding one or more certificates to verify
36
- # the peer with. This makes sense only when used in combination with
37
- # the CURLOPT_SSL_VERIFYPEER option. If CURLOPT_SSL_VERIFYPEER is
38
- # zero, CURLOPT_CAINFO need not even indicate an accessible file.
39
- # This option is by default set to the system path where libcurl's
40
- # cacert bundle is assumed to be stored, as established at build time.
41
- # When built against NSS, this is the directory that the NSS certificate
42
- # database resides in.
34
+ # Pass a string to a zero-terminated string naming a file holding one
35
+ # or more certificates with which to verify the peer. This makes sense
36
+ # only when used in combination with the CURLOPT_SSL_VERIFYPEER option.
37
+ # If CURLOPT_SSL_VERIFYPEER is zero, CURLOPT_CAINFO need not even
38
+ # indicate an accessible file. This option is by default set to the
39
+ # system path where libcurl's cacert bundle is assumed to be stored,
40
+ # as established at build time. When built against NSS, this is the
41
+ # directory that the NSS certificate database resides in.
43
42
  #
44
43
  # @example Set cainfo option.
45
44
  # easy.cainfo = "/path/to/file"
@@ -51,10 +50,10 @@ module Ethon
51
50
  Curl.set_option(:cainfo, value_for(value, :string), handle)
52
51
  end
53
52
 
54
- # Pass a string to a zero terminated string naming a directory holding
55
- # multiple CA certificates to verify the peer with. If libcurl is built
56
- # against OpenSSL, the certificate directory must be prepared using the
57
- # openssl c_rehash utility. This makes sense only when used in
53
+ # Pass a string to a zero-terminated string naming a directory holding
54
+ # multiple CA certificates with which to verify the peer. If libcurl is
55
+ # built against OpenSSL, the certificate directory must be prepared using
56
+ # the openssl c_rehash utility. This makes sense only when used in
58
57
  # combination with the CURLOPT_SSL_VERIFYPEER option. If
59
58
  # CURLOPT_SSL_VERIFYPEER is zero, CURLOPT_CAPATH need not even indicate
60
59
  # an accessible path. The CURLOPT_CAPATH function apparently does not
@@ -78,7 +77,7 @@ module Ethon
78
77
  # connection phase, once it has connected, this option is of no more
79
78
  # use. Set to zero to switch to the default built-in connection timeout
80
79
  # \- 300 seconds. See also the CURLOPT_TIMEOUT option.
81
- # In unix-like systems, this might cause signals to be used unless
80
+ # In Unix-like systems, this might cause signals to be used unless
82
81
  # CURLOPT_NOSIGNAL is set.
83
82
  #
84
83
  # @example Set connecttimeout option.
@@ -107,6 +106,51 @@ module Ethon
107
106
  Curl.set_option(:connecttimeout_ms, value_for(value, :int), handle)
108
107
  end
109
108
 
109
+ # Sets the cookie value
110
+ #
111
+ # If you want to read/write the cookie from a file,
112
+ # see cookiefile= and cookiejar=
113
+ #
114
+ # @example Set the cookie option
115
+ # easy.cookie = "cookie-value"
116
+ #
117
+ # @param [ String ] value The cookie value
118
+ #
119
+ # @return [ void ]
120
+ def cookie=(value)
121
+ Curl.set_option(:cookie, value_for(value, :string), handle)
122
+ end
123
+
124
+ # Sets the cookie jar file
125
+ # The file will only be used to write the cookie value
126
+ # If you want to read the cookie from a file, see cookiefile=
127
+ #
128
+ # If the file does not exist, it will try to create it
129
+ #
130
+ # @example Set cookiejar option
131
+ # easy.cookiejar = "/path/to/file"
132
+ #
133
+ # @param [ String ] file The path to the file
134
+ #
135
+ # @return [ void ]
136
+ def cookiejar=(file)
137
+ Curl.set_option(:cookiejar, value_for(file, :string), handle)
138
+ end
139
+
140
+ # Sets the cookie file
141
+ # The file will only be used to read the cookie value
142
+ # If you want to set the cookie in a file, see cookiejar=
143
+ #
144
+ # @example Set cookiefile option
145
+ # easy.cookiefile = "/path/to/file"
146
+ #
147
+ # @param [ String ] file The path to the file
148
+ #
149
+ # @return [ void ]
150
+ def cookiefile=(file)
151
+ Curl.set_option(:cookiefile, value_for(file, :string), handle)
152
+ end
153
+
110
154
  # Pass a string as parameter, which should be the full data to post in
111
155
  # a HTTP POST operation. It behaves as the CURLOPT_POSTFIELDS option,
112
156
  # but the original data are copied by the library, allowing the
@@ -130,7 +174,7 @@ module Ethon
130
174
  Curl.set_option(:copypostfields, value_for(value, :string), handle)
131
175
  end
132
176
 
133
- # Pass a pointer to a zero terminated string as parameter. It can be
177
+ # Pass a pointer to a zero-terminated string as parameter. It can be
134
178
  # used to specify the request instead of GET or HEAD when performing
135
179
  # HTTP based requests, instead of LIST and NLST when performing FTP
136
180
  # directory listings and instead of LIST and RETR when issuing POP3
@@ -143,7 +187,7 @@ module Ethon
143
187
  # in regards to the particular request method, it will only change the
144
188
  # actual string sent in the request.
145
189
  # For example:
146
- # With the HTTP protocol when you tell libcurl to do a HEAD request,
190
+ # With the HTTP protocol, when you tell libcurl to do a HEAD request,
147
191
  # but then specify a GET though a custom request libcurl will still act
148
192
  # as if it sent a HEAD. To switch to a proper HEAD use CURLOPT_NOBODY,
149
193
  # to switch to a proper POST use CURLOPT_POST or CURLOPT_POSTFIELDS and
@@ -172,7 +216,7 @@ module Ethon
172
216
  Curl.set_option(:customrequest, value_for(value, :string), handle)
173
217
  end
174
218
 
175
- # Pass a long, this sets the timeout in seconds. Name resolves will be
219
+ # Pass a long, this sets the timeout in seconds. Name resolutions will be
176
220
  # kept in memory for this number of seconds. Set to zero to completely
177
221
  # disable caching, or set to -1 to make the cached entries remain
178
222
  # forever. By default, libcurl caches this info for 60 seconds.
@@ -478,6 +522,17 @@ module Ethon
478
522
  Curl.set_option(:postfieldsize, value_for(value, :int), handle)
479
523
  end
480
524
 
525
+ #
526
+ # @example Set protocols option.
527
+ # easy.protocols = :http
528
+ #
529
+ # @param [ Symbol ] value The value or array of values to set.
530
+ #
531
+ # @return [ void ]
532
+ def postredir=(value)
533
+ Curl.set_option(:postredir, value_for(value, :enum, :postredir), handle)
534
+ end
535
+
481
536
  # Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this
482
537
  # bitmask limits what protocols libcurl may use in the transfer. This
483
538
  # allows you to have a libcurl built to support a wide range of protocols
@@ -865,6 +920,21 @@ module Ethon
865
920
  Curl.set_option(:timeout_ms, value_for(value, :int), handle)
866
921
  end
867
922
 
923
+ # A parameter set to 1 tells the library it can continue to send
924
+ # authentication (user+password) when following locations, even
925
+ # when hostname changed. This option is meaningful only when setting
926
+ # CURLOPT_FOLLOWLOCATION.
927
+ #
928
+ # @example Set unrestricted auth.
929
+ # easy.unrestricted_auth = true
930
+ #
931
+ # @param [ Boolean ] value The value to set.
932
+ #
933
+ # @return [ void ]
934
+ def unrestricted_auth=(value)
935
+ Curl.set_option(:unrestricted_auth, value_for(value, :bool), handle)
936
+ end
937
+
868
938
  # A parameter set to 1 tells the library to prepare for an upload. The
869
939
  # CURLOPT_READDATA and CURLOPT_INFILESIZE or CURLOPT_INFILESIZE_LARGE
870
940
  # options are also interesting for uploads. If the protocol is HTTP,
@@ -1143,6 +1213,12 @@ module Ethon
1143
1213
  raise Errors::InvalidValue.new(option, v)
1144
1214
  end
1145
1215
  end.inject(:+)
1216
+ elsif type == :enum && option == :postredir
1217
+ Array(value).map do |v|
1218
+ Curl::Postredir.to_h.fetch(v) do
1219
+ raise Errors::InvalidValue.new(option, v)
1220
+ end
1221
+ end.inject(:+)
1146
1222
  elsif type == :enum && option == :proxytype
1147
1223
  Curl::Proxy.to_h.fetch(value) do
1148
1224
  raise Errors::InvalidValue.new(option, value)
@@ -4,7 +4,7 @@ require 'ethon/easy/queryable'
4
4
  module Ethon
5
5
  class Easy
6
6
 
7
- # This class represents http request parameters.
7
+ # This class represents HTTP request parameters.
8
8
  #
9
9
  # @api private
10
10
  class Params
data/lib/ethon/multi.rb CHANGED
@@ -11,23 +11,6 @@ module Ethon
11
11
  include Ethon::Multi::Operations
12
12
  include Ethon::Multi::Options
13
13
 
14
- class << self
15
-
16
- # Frees the libcurl multi handle.
17
- #
18
- # @example Free multi.
19
- # Multi.finalizer(multi)
20
- #
21
- # @param [ Multi ] multi The multi to free.
22
- #
23
- # @api private
24
- def finalizer(multi)
25
- proc {
26
- Curl.multi_cleanup(multi.handle)
27
- }
28
- end
29
- end
30
-
31
14
  # Create a new multi. Initialize curl in case
32
15
  # it didn't happen before.
33
16
  #
@@ -82,7 +65,6 @@ module Ethon
82
65
  # @return [ Multi ] The new multi.
83
66
  def initialize(options = {})
84
67
  Curl.init
85
- ObjectSpace.define_finalizer(self, self.class.finalizer(self))
86
68
  set_attributes(options)
87
69
  init_vars
88
70
  end
@@ -1,9 +1,7 @@
1
1
  module Ethon
2
2
  class Multi # :nodoc
3
-
4
3
  # This module contains logic to run a multi.
5
4
  module Operations
6
-
7
5
  # Return the multi handle. Inititialize multi handle,
8
6
  # in case it didn't happened already.
9
7
  #
@@ -12,7 +10,7 @@ module Ethon
12
10
  #
13
11
  # @return [ FFI::Pointer ] The multi handle.
14
12
  def handle
15
- @handle ||= Curl.multi_init
13
+ @handle ||= FFI::AutoPointer.new(Curl.multi_init, Curl.method(:multi_cleanup))
16
14
  end
17
15
 
18
16
  # Initialize variables.
data/lib/ethon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Ethon
2
2
 
3
3
  # Ethon version.
4
- VERSION = '0.5.10'
4
+ VERSION = '0.5.11'
5
5
  end
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.10
4
+ version: 0.5.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,14 +9,14 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-03 00:00:00.000000000 Z
12
+ date: 2013-04-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: 1.3.0
22
22
  type: :runtime
@@ -24,7 +24,7 @@ dependencies:
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: 1.3.0
30
30
  - !ruby/object:Gem::Dependency
@@ -61,6 +61,7 @@ files:
61
61
  - lib/ethon/curls/infos.rb
62
62
  - lib/ethon/curls/messages.rb
63
63
  - lib/ethon/curls/options.rb
64
+ - lib/ethon/curls/postredir.rb
64
65
  - lib/ethon/curls/protocols.rb
65
66
  - lib/ethon/curls/proxy_types.rb
66
67
  - lib/ethon/curls/settings.rb
@@ -125,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
126
  version: '0'
126
127
  segments:
127
128
  - 0
128
- hash: -82910396977477483
129
+ hash: 3434979125068377231
129
130
  required_rubygems_version: !ruby/object:Gem::Requirement
130
131
  none: false
131
132
  requirements: