typhoeus 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/{CHANGELOG.markdown → CHANGELOG.md} +21 -12
  2. data/LICENSE +2 -0
  3. data/README.md +455 -0
  4. data/Rakefile +6 -26
  5. data/lib/typhoeus.rb +4 -6
  6. data/lib/typhoeus/curl.rb +453 -0
  7. data/lib/typhoeus/easy.rb +60 -358
  8. data/lib/typhoeus/easy/auth.rb +14 -0
  9. data/lib/typhoeus/easy/callbacks.rb +33 -0
  10. data/lib/typhoeus/easy/ffi_helper.rb +61 -0
  11. data/lib/typhoeus/easy/infos.rb +90 -0
  12. data/lib/typhoeus/easy/options.rb +115 -0
  13. data/lib/typhoeus/easy/proxy.rb +20 -0
  14. data/lib/typhoeus/easy/ssl.rb +82 -0
  15. data/lib/typhoeus/form.rb +30 -1
  16. data/lib/typhoeus/{normalized_header_hash.rb → header.rb} +2 -6
  17. data/lib/typhoeus/hydra.rb +9 -12
  18. data/lib/typhoeus/hydra_mock.rb +2 -2
  19. data/lib/typhoeus/multi.rb +118 -9
  20. data/lib/typhoeus/param_processor.rb +43 -0
  21. data/lib/typhoeus/request.rb +18 -21
  22. data/lib/typhoeus/response.rb +5 -4
  23. data/lib/typhoeus/utils.rb +14 -27
  24. data/lib/typhoeus/version.rb +1 -1
  25. metadata +155 -152
  26. data/Gemfile.lock +0 -37
  27. data/ext/typhoeus/.gitignore +0 -7
  28. data/ext/typhoeus/extconf.rb +0 -65
  29. data/ext/typhoeus/native.c +0 -12
  30. data/ext/typhoeus/native.h +0 -22
  31. data/ext/typhoeus/typhoeus_easy.c +0 -232
  32. data/ext/typhoeus/typhoeus_easy.h +0 -20
  33. data/ext/typhoeus/typhoeus_form.c +0 -59
  34. data/ext/typhoeus/typhoeus_form.h +0 -13
  35. data/ext/typhoeus/typhoeus_multi.c +0 -217
  36. data/ext/typhoeus/typhoeus_multi.h +0 -16
  37. data/lib/typhoeus/.gitignore +0 -1
  38. data/lib/typhoeus/service.rb +0 -20
  39. data/spec/fixtures/placeholder.gif +0 -0
  40. data/spec/fixtures/placeholder.txt +0 -1
  41. data/spec/fixtures/placeholder.ukn +0 -0
  42. data/spec/fixtures/result_set.xml +0 -60
  43. data/spec/servers/app.rb +0 -97
  44. data/spec/spec_helper.rb +0 -19
  45. data/spec/support/typhoeus_localhost_server.rb +0 -58
  46. data/spec/typhoeus/easy_spec.rb +0 -391
  47. data/spec/typhoeus/filter_spec.rb +0 -35
  48. data/spec/typhoeus/form_spec.rb +0 -117
  49. data/spec/typhoeus/hydra_mock_spec.rb +0 -300
  50. data/spec/typhoeus/hydra_spec.rb +0 -602
  51. data/spec/typhoeus/multi_spec.rb +0 -74
  52. data/spec/typhoeus/normalized_header_hash_spec.rb +0 -41
  53. data/spec/typhoeus/remote_method_spec.rb +0 -141
  54. data/spec/typhoeus/remote_proxy_object_spec.rb +0 -65
  55. data/spec/typhoeus/remote_spec.rb +0 -695
  56. data/spec/typhoeus/request_spec.rb +0 -387
  57. data/spec/typhoeus/response_spec.rb +0 -192
  58. data/spec/typhoeus/utils_spec.rb +0 -22
  59. data/typhoeus.gemspec +0 -33
data/lib/typhoeus/easy.rb CHANGED
@@ -1,264 +1,61 @@
1
+ require 'typhoeus/easy/ffi_helper'
2
+ require 'typhoeus/easy/options'
3
+ require 'typhoeus/easy/ssl'
4
+ require 'typhoeus/easy/auth'
5
+ require 'typhoeus/easy/proxy'
6
+ require 'typhoeus/easy/callbacks'
7
+ require 'typhoeus/easy/infos'
8
+
1
9
  module Typhoeus
2
10
  class Easy
3
- attr_reader :response_body, :response_header, :method, :headers, :url, :params, :curl_return_code, :ssl_version
11
+ include Typhoeus::EasyFu::FFIHelper
12
+ include Typhoeus::EasyFu::Options
13
+ include Typhoeus::EasyFu::SSL
14
+ include Typhoeus::EasyFu::Auth
15
+ include Typhoeus::EasyFu::Proxy
16
+ include Typhoeus::EasyFu::Callbacks
17
+ include Typhoeus::EasyFu::Infos
18
+
19
+ OPTION_VALUES = Curl::Option.to_hash.dup
20
+ Curl::Option.to_hash.each {|key, value| OPTION_VALUES["CURLOPT_#{key.to_s.upcase}".to_sym] = value }
21
+ INFO_VALUES = Curl::Info.to_hash.dup
22
+ Curl::Info.to_hash.each {|key, value| INFO_VALUES["CURLINFO_#{key.to_s.upcase}".to_sym] = value }
23
+ AUTH_TYPES = Curl::Auth.to_hash.dup
24
+ Curl::Auth.to_hash.each {|key, value| AUTH_TYPES["CURLAUTH_#{key.to_s.upcase}".to_sym] = value }
25
+ PROXY_TYPES = Curl::Proxy.to_hash.dup
26
+ Curl::Proxy.to_hash.each {|key, value| PROXY_TYPES["CURLPROXY_#{key.to_s.upcase}".to_sym] = value }
27
+ SSL_VERSIONS = Curl::SSLVersion.to_hash.dup
28
+ Curl::SSLVersion.to_hash.each {|key, value| SSL_VERSIONS["CURL_SSLVERSION_#{key.to_s.upcase}".to_sym] = value }
29
+
30
+ attr_reader :url, :header_list
4
31
  attr_accessor :start_time
5
32
 
6
- # These integer codes are available in curl/curl.h
7
- CURLINFO_STRING = 1048576
8
- OPTION_VALUES = {
9
- :CURLOPT_URL => 10002,
10
- :CURLOPT_HTTPGET => 80,
11
- :CURLOPT_HTTPPOST => 10024,
12
- :CURLOPT_UPLOAD => 46,
13
- :CURLOPT_CUSTOMREQUEST => 10036,
14
- :CURLOPT_POSTFIELDS => 10015,
15
- :CURLOPT_COPYPOSTFIELDS => 10165,
16
- :CURLOPT_POSTFIELDSIZE => 60,
17
- :CURLOPT_USERAGENT => 10018,
18
- :CURLOPT_TIMEOUT_MS => 155,
19
- # Time-out connect operations after this amount of milliseconds.
20
- # [Only works on unix-style/SIGALRM operating systems. IOW, does
21
- # not work on Windows.
22
- :CURLOPT_CONNECTTIMEOUT_MS => 156,
23
- :CURLOPT_INTERFACE => 10000 + 62,
24
- :CURLOPT_NOSIGNAL => 99,
25
- :CURLOPT_HTTPHEADER => 10023,
26
- :CURLOPT_FOLLOWLOCATION => 52,
27
- :CURLOPT_MAXREDIRS => 68,
28
- :CURLOPT_HTTPAUTH => 107,
29
- :CURLOPT_USERPWD => 10000 + 5,
30
- :CURLOPT_VERBOSE => 41,
31
- :CURLOPT_PROXY => 10004,
32
- :CURLOPT_PROXYUSERPWD => 10000 + 6,
33
- :CURLOPT_PROXYTYPE => 101,
34
- :CURLOPT_PROXYAUTH => 111,
35
- :CURLOPT_VERIFYPEER => 64,
36
- :CURLOPT_VERIFYHOST => 81,
37
- :CURLOPT_NOBODY => 44,
38
- :CURLOPT_ENCODING => 10000 + 102,
39
- :CURLOPT_SSLCERT => 10025,
40
- :CURLOPT_SSLCERTTYPE => 10086,
41
- :CURLOPT_SSLKEY => 10087,
42
- :CURLOPT_SSLKEYTYPE => 10088,
43
- :CURLOPT_SSLVERSION => 32,
44
- :CURLOPT_KEYPASSWD => 10026,
45
- :CURLOPT_CAINFO => 10065,
46
- :CURLOPT_CAPATH => 10097,
47
- }
48
- INFO_VALUES = {
49
- :CURLINFO_RESPONSE_CODE => 2097154,
50
- :CURLINFO_TOTAL_TIME => 3145731,
51
- :CURLINFO_HTTPAUTH_AVAIL => 0x200000 + 23,
52
- :CURLINFO_EFFECTIVE_URL => 0x100000 + 1,
53
- :CURLINFO_PRIMARY_IP => 0x100000 + 32,
54
- :CURLINFO_NAMELOOKUP_TIME => 0x300000 + 4,
55
- :CURLINFO_CONNECT_TIME => 0x300000 + 5,
56
- :CURLINFO_PRETRANSFER_TIME => 0x300000 + 6,
57
- :CURLINFO_STARTTRANSFER_TIME => 0x300000 + 17,
58
- :CURLINFO_APPCONNECT_TIME => 0x300000 + 33,
59
-
60
- }
61
- AUTH_TYPES = {
62
- :CURLAUTH_BASIC => 1,
63
- :CURLAUTH_DIGEST => 2,
64
- :CURLAUTH_GSSNEGOTIATE => 4,
65
- :CURLAUTH_NTLM => 8,
66
- :CURLAUTH_DIGEST_IE => 16,
67
- :CURLAUTH_AUTO => 16 | 8 | 4 | 2 | 1
68
- }
69
- PROXY_TYPES = {
70
- :CURLPROXY_HTTP => 0,
71
- :CURLPROXY_HTTP_1_0 => 1,
72
- :CURLPROXY_SOCKS4 => 4,
73
- :CURLPROXY_SOCKS5 => 5,
74
- :CURLPROXY_SOCKS4A => 6,
75
- }
76
-
77
- SSL_VERSIONS = {
78
- :CURL_SSLVERSION_DEFAULT => 0,
79
- :CURL_SSLVERSION_TLSv1 => 1,
80
- :CURL_SSLVERSION_SSLv2 => 2,
81
- :CURL_SSLVERSION_SSLv3 => 3,
82
- :default => 0,
83
- :tlsv1 => 1,
84
- :sslv2 => 2,
85
- :sslv3 => 3
86
- }
87
-
88
33
  def initialize
89
- @method = :get
90
- @headers = {}
91
-
92
- set_defaults
34
+ Curl.init
35
+ reset(true)
36
+ ObjectSpace.define_finalizer(self, self.class.finalizer(self))
93
37
  end
94
38
 
95
- def set_defaults
96
- # Enable encoding/compression support
97
- self.encoding = ''
98
- self.ssl_version = :default
39
+ def method
40
+ @method ||= :get
99
41
  end
100
42
 
101
- def encoding=(encoding)
102
- # Enable encoding/compression support
103
- set_option(OPTION_VALUES[:CURLOPT_ENCODING], encoding)
43
+ def headers
44
+ @header ||= {}
104
45
  end
105
46
 
106
- def ssl_version=(version)
107
- raise "Invalid SSL version: '#{version}' supplied! Please supply one as listed in Typhoeus::Easy::SSL_VERSIONS" unless SSL_VERSIONS.has_key?(version)
108
- @ssl_version = version
47
+ def response_body
48
+ @response_body ||= ""
49
+ end
109
50
 
110
- set_option(OPTION_VALUES[:CURLOPT_SSLVERSION], SSL_VERSIONS[version])
51
+ def response_header
52
+ @response_header ||= ""
111
53
  end
112
54
 
113
55
  def headers=(hash)
114
56
  @headers = hash
115
57
  end
116
58
 
117
- def interface=(interface)
118
- @interface = interface
119
- set_option(OPTION_VALUES[:CURLOPT_INTERFACE], interface)
120
- end
121
-
122
- def proxy=(proxy)
123
- set_option(OPTION_VALUES[:CURLOPT_PROXY], proxy[:server])
124
- set_option(OPTION_VALUES[:CURLOPT_PROXYTYPE], proxy[:type]) if proxy[:type]
125
- end
126
-
127
- def proxy_auth=(authinfo)
128
- set_option(OPTION_VALUES[:CURLOPT_PROXYUSERPWD], "#{authinfo[:username]}:#{authinfo[:password]}")
129
- set_option(OPTION_VALUES[:CURLOPT_PROXYAUTH], authinfo[:method]) if authinfo[:method]
130
- end
131
-
132
- def auth=(authinfo)
133
- set_option(OPTION_VALUES[:CURLOPT_USERPWD], "#{authinfo[:username]}:#{authinfo[:password]}")
134
- set_option(OPTION_VALUES[:CURLOPT_HTTPAUTH], authinfo[:method]) if authinfo[:method]
135
- end
136
-
137
- def auth_methods
138
- get_info_long(INFO_VALUES[:CURLINFO_HTTPAUTH_AVAIL])
139
- end
140
-
141
- def verbose=(boolean)
142
- set_option(OPTION_VALUES[:CURLOPT_VERBOSE], !!boolean ? 1 : 0)
143
- end
144
-
145
- def total_time_taken
146
- get_info_double(INFO_VALUES[:CURLINFO_TOTAL_TIME])
147
- end
148
-
149
- def start_transfer_time
150
- get_info_double(INFO_VALUES[:CURLINFO_STARTTRANSFER_TIME])
151
- end
152
-
153
- def app_connect_time
154
- get_info_double(INFO_VALUES[:CURLINFO_APPCONNECT_TIME])
155
- end
156
-
157
- def pretransfer_time
158
- get_info_double(INFO_VALUES[:CURLINFO_PRETRANSFER_TIME])
159
- end
160
-
161
- def connect_time
162
- get_info_double(INFO_VALUES[:CURLINFO_CONNECT_TIME])
163
- end
164
-
165
- def name_lookup_time
166
- get_info_double(INFO_VALUES[:CURLINFO_NAMELOOKUP_TIME])
167
- end
168
-
169
- def effective_url
170
- get_info_string(INFO_VALUES[:CURLINFO_EFFECTIVE_URL])
171
- end
172
-
173
- def primary_ip
174
- get_info_string(INFO_VALUES[:CURLINFO_PRIMARY_IP])
175
- end
176
-
177
- def response_code
178
- get_info_long(INFO_VALUES[:CURLINFO_RESPONSE_CODE])
179
- end
180
-
181
- def follow_location=(boolean)
182
- if boolean
183
- set_option(OPTION_VALUES[:CURLOPT_FOLLOWLOCATION], 1)
184
- else
185
- set_option(OPTION_VALUES[:CURLOPT_FOLLOWLOCATION], 0)
186
- end
187
- end
188
-
189
- def max_redirects=(redirects)
190
- set_option(OPTION_VALUES[:CURLOPT_MAXREDIRS], redirects)
191
- end
192
-
193
- def connect_timeout=(milliseconds)
194
- @connect_timeout = milliseconds
195
- set_option(OPTION_VALUES[:CURLOPT_NOSIGNAL], 1)
196
- set_option(OPTION_VALUES[:CURLOPT_CONNECTTIMEOUT_MS], milliseconds)
197
- end
198
-
199
- def timeout=(milliseconds)
200
- @timeout = milliseconds
201
- set_option(OPTION_VALUES[:CURLOPT_NOSIGNAL], 1)
202
- set_option(OPTION_VALUES[:CURLOPT_TIMEOUT_MS], milliseconds)
203
- end
204
-
205
- def timed_out?
206
- curl_return_code == 28
207
- end
208
-
209
- def supports_zlib?
210
- !!(curl_version.match(/zlib/))
211
- end
212
-
213
- def request_body=(request_body)
214
- @request_body = request_body
215
- if @method == :put
216
- easy_set_request_body(@request_body.to_s)
217
- else
218
- self.post_data = request_body
219
- end
220
- end
221
-
222
- def user_agent=(user_agent)
223
- set_option(OPTION_VALUES[:CURLOPT_USERAGENT], user_agent)
224
- end
225
-
226
- def url=(url)
227
- @url = url
228
- set_option(OPTION_VALUES[:CURLOPT_URL], url)
229
- end
230
-
231
- def disable_ssl_peer_verification
232
- set_option(OPTION_VALUES[:CURLOPT_VERIFYPEER], 0)
233
- end
234
-
235
- def disable_ssl_host_verification
236
- set_option(OPTION_VALUES[:CURLOPT_VERIFYHOST], 0)
237
- end
238
-
239
- def method=(method)
240
- @method = method
241
- if method == :get
242
- set_option(OPTION_VALUES[:CURLOPT_HTTPGET], 1)
243
- elsif method == :post
244
- set_option(OPTION_VALUES[:CURLOPT_HTTPPOST], 1)
245
- self.post_data = ""
246
- elsif method == :put
247
- set_option(OPTION_VALUES[:CURLOPT_UPLOAD], 1)
248
- self.request_body = @request_body.to_s
249
- elsif method == :head
250
- set_option(OPTION_VALUES[:CURLOPT_NOBODY], 1)
251
- else
252
- set_option(OPTION_VALUES[:CURLOPT_CUSTOMREQUEST], method.to_s.upcase)
253
- end
254
- end
255
-
256
- def post_data=(data)
257
- @post_data_set = true
258
- set_option(OPTION_VALUES[:CURLOPT_POSTFIELDSIZE], data.bytesize)
259
- set_option(OPTION_VALUES[:CURLOPT_COPYPOSTFIELDS], data)
260
- end
261
-
262
59
  def params
263
60
  @form.nil? ? {} : @form.params
264
61
  end
@@ -269,7 +66,7 @@ module Typhoeus
269
66
  if method == :post
270
67
  @form.process!
271
68
  if @form.multipart?
272
- set_option(OPTION_VALUES[:CURLOPT_HTTPPOST], @form)
69
+ set_option(:httppost, @form)
273
70
  else
274
71
  self.post_data = @form.to_s
275
72
  end
@@ -278,68 +75,9 @@ module Typhoeus
278
75
  end
279
76
  end
280
77
 
281
- # Set SSL certificate
282
- # " The string should be the file name of your certificate. "
283
- # The default format is "PEM" and can be changed with ssl_cert_type=
284
- def ssl_cert=(cert)
285
- set_option(OPTION_VALUES[:CURLOPT_SSLCERT], cert)
286
- end
287
-
288
- # Set SSL certificate type
289
- # " The string should be the format of your certificate. Supported formats are "PEM" and "DER" "
290
- def ssl_cert_type=(cert_type)
291
- raise "Invalid ssl cert type : '#{cert_type}'..." if cert_type and !%w(PEM DER p12).include?(cert_type)
292
- set_option(OPTION_VALUES[:CURLOPT_SSLCERTTYPE], cert_type)
293
- end
294
-
295
- # Set SSL Key file
296
- # " The string should be the file name of your private key. "
297
- # The default format is "PEM" and can be changed with ssl_key_type=
298
- #
299
- def ssl_key=(key)
300
- set_option(OPTION_VALUES[:CURLOPT_SSLKEY], key)
301
- end
302
-
303
- # Set SSL Key type
304
- # " The string should be the format of your private key. Supported formats are "PEM", "DER" and "ENG". "
305
- #
306
- def ssl_key_type=(key_type)
307
- raise "Invalid ssl key type : '#{key_type}'..." if key_type and !%w(PEM DER ENG).include?(key_type)
308
- set_option(OPTION_VALUES[:CURLOPT_SSLKEYTYPE], key_type)
309
- end
310
-
311
- def ssl_key_password=(key_password)
312
- set_option(OPTION_VALUES[:CURLOPT_KEYPASSWD], key_password)
313
- end
314
-
315
- # Set SSL CACERT
316
- # " File holding one or more certificates to verify the peer with. "
317
- #
318
- def ssl_cacert=(cacert)
319
- set_option(OPTION_VALUES[:CURLOPT_CAINFO], cacert)
320
- end
321
-
322
- # Set CAPATH
323
- # " directory holding multiple CA certificates to verify the peer with. The certificate directory must be prepared using the openssl c_rehash utility. "
324
- #
325
- def ssl_capath=(capath)
326
- set_option(OPTION_VALUES[:CURLOPT_CAPATH], capath)
327
- end
328
-
329
- def set_option(option, value)
330
- case value
331
- when String
332
- easy_setopt_string(option, value)
333
- when Typhoeus::Form
334
- easy_setopt_form(option, value)
335
- else
336
- easy_setopt_long(option, value) if value
337
- end
338
- end
339
-
340
78
  def perform
341
79
  set_headers()
342
- easy_perform()
80
+ @curl_return_code = Curl.easy_perform(handle)
343
81
  resp_code = response_code()
344
82
  if resp_code >= 200 && resp_code <= 299
345
83
  success
@@ -349,65 +87,29 @@ module Typhoeus
349
87
  resp_code
350
88
  end
351
89
 
352
- def set_headers
353
- headers.each_pair do |key, value|
354
- easy_add_header("#{key}: #{value}")
355
- end
356
- easy_set_headers() unless headers.empty?
357
- end
358
-
359
- # gets called when finished and response code is not 2xx,
360
- # or curl returns an error code.
361
- def success
362
- @success.call(self) if @success
363
- end
364
-
365
- def on_success(&block)
366
- @success = block
367
- end
368
-
369
- def on_success=(block)
370
- @success = block
371
- end
372
-
373
- # gets called when finished and response code is 300-599
374
- # or curl returns an error code
375
- def failure
376
- @failure.call(self) if @failure
377
- end
90
+ def reset(fresh = nil)
91
+ unless fresh
92
+ @response_code = 0
93
+ @response_header = ""
94
+ @response_body = ""
95
+ @request_body = ""
378
96
 
379
- def on_failure(&block)
380
- @failure = block
381
- end
382
-
383
- def on_failure=(block)
384
- @failure = block
385
- end
386
-
387
- def reset
388
- @response_code = 0
389
- @response_header = ""
390
- @response_body = ""
391
- @request_body = ""
392
- easy_reset()
393
- set_defaults
394
- end
395
-
396
- def get_info_string(option)
397
- easy_getinfo_string(option)
398
- end
97
+ if @header_list
98
+ Curl.slist_free_all(@header_list)
99
+ @header_list = nil
100
+ end
399
101
 
400
- def get_info_long(option)
401
- easy_getinfo_long(option)
402
- end
102
+ Curl.easy_reset(handle)
103
+ end
403
104
 
404
- def get_info_double(option)
405
- easy_getinfo_double(option)
105
+ self.write_function = body_write_callback
106
+ self.header_function = header_write_callback
107
+ self.encoding = ''
108
+ self.ssl_version = :default
406
109
  end
407
110
 
408
- def curl_version
409
- version
111
+ def curl_return_code=(code)
112
+ @curl_return_code = (code.class == Symbol ? code : Curl::EasyCode[code])
410
113
  end
411
-
412
114
  end
413
115
  end