ethon 0.5.10 → 0.5.11

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