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
@@ -0,0 +1,14 @@
1
+ module Typhoeus
2
+ module EasyFu
3
+ module Auth
4
+ def auth=(authinfo)
5
+ set_option(:userpwd, auth_credentials(authinfo))
6
+ set_option(:httpauth, Typhoeus::Easy::AUTH_TYPES[authinfo[:method]]) if authinfo[:method]
7
+ end
8
+
9
+ def auth_credentials(authinfo)
10
+ "#{authinfo[:username]}:#{authinfo[:password]}"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ module Typhoeus
2
+ module EasyFu
3
+ module Callbacks
4
+ # gets called when finished and response code is not 2xx,
5
+ # or curl returns an error code.
6
+ def success
7
+ @success.call(self) if @success
8
+ end
9
+
10
+ def on_success(&block)
11
+ @success = block
12
+ end
13
+
14
+ def on_success=(block)
15
+ @success = block
16
+ end
17
+
18
+ # gets called when finished and response code is 300-599
19
+ # or curl returns an error code
20
+ def failure
21
+ @failure.call(self) if @failure
22
+ end
23
+
24
+ def on_failure(&block)
25
+ @failure = block
26
+ end
27
+
28
+ def on_failure=(block)
29
+ @failure = block
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,61 @@
1
+ module Typhoeus
2
+ module EasyFu
3
+ module FFIHelper
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def finalizer(easy)
10
+ proc {
11
+ Curl.slist_free_all(easy.header_list) if easy.header_list
12
+ Curl.easy_cleanup(easy.handle)
13
+ }
14
+ end
15
+ end
16
+
17
+ def handle
18
+ @handle ||= Curl.easy_init
19
+ end
20
+
21
+ def body_write_callback
22
+ @body_write_callback ||= proc {|stream, size, num, object|
23
+ response_body << stream.read_string(size * num)
24
+ size * num
25
+ }
26
+ end
27
+
28
+ def header_write_callback
29
+ @header_write_callback ||= proc {|stream, size, num, object|
30
+ response_header << stream.read_string(size * num)
31
+ size * num
32
+ }
33
+ end
34
+
35
+ def read_callback
36
+ @read_callback ||= proc {|stream, size, num, object|
37
+ size = size * num
38
+ left = Utils.bytesize(@request_body) - @request_body_read
39
+ size = left if size > left
40
+ if size > 0
41
+ stream.write_string(Utils.byteslice(@request_body, @request_body_read, size), size)
42
+ @request_body_read += size
43
+ end
44
+ size
45
+ }
46
+ end
47
+
48
+ def string_ptr
49
+ @string_ptr ||= ::FFI::MemoryPointer.new(:pointer)
50
+ end
51
+
52
+ def long_ptr
53
+ @long_ptr ||= ::FFI::MemoryPointer.new(:long)
54
+ end
55
+
56
+ def double_ptr
57
+ @double_ptr ||= ::FFI::MemoryPointer.new(:double)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,90 @@
1
+ module Typhoeus
2
+ module EasyFu
3
+ module Infos
4
+ def get_info_string(option)
5
+ if Curl.easy_getinfo(@handle, option, string_ptr) == :ok
6
+ string_ptr.read_pointer.read_string
7
+ else nil
8
+ end
9
+ end
10
+
11
+ def get_info_long(option)
12
+ if Curl.easy_getinfo(@handle, option, long_ptr) == :ok
13
+ long_ptr.read_long
14
+ else nil
15
+ end
16
+ end
17
+
18
+ def get_info_double(option)
19
+ if Curl.easy_getinfo(@handle, option, double_ptr) == :ok
20
+ double_ptr.read_double
21
+ else nil
22
+ end
23
+ end
24
+
25
+ def auth_methods
26
+ get_info_long(:httpauth_avail)
27
+ end
28
+
29
+ def total_time_taken
30
+ get_info_double(:total_time)
31
+ end
32
+
33
+ def start_transfer_time
34
+ get_info_double(:starttransfer_time)
35
+ end
36
+
37
+ def app_connect_time
38
+ get_info_double(:appconnect_time)
39
+ end
40
+
41
+ def pretransfer_time
42
+ get_info_double(:pretransfer_time)
43
+ end
44
+
45
+ def connect_time
46
+ get_info_double(:connect_time)
47
+ end
48
+
49
+ def name_lookup_time
50
+ get_info_double(:namelookup_time)
51
+ end
52
+
53
+ def effective_url
54
+ get_info_string(:effective_url)
55
+ end
56
+
57
+ def primary_ip
58
+ get_info_string(:primary_ip)
59
+ end
60
+
61
+ def response_code
62
+ get_info_long(:response_code)
63
+ end
64
+
65
+ def timed_out?
66
+ @curl_return_code == :operation_timedout
67
+ end
68
+
69
+ def redirect_count
70
+ get_info_long(:redirect_count)
71
+ end
72
+
73
+ def curl_return_code
74
+ Curl::EasyCode[@curl_return_code]
75
+ end
76
+
77
+ def curl_error_message(code = @curl_return_code)
78
+ code ? Curl.easy_strerror(code) : nil
79
+ end
80
+
81
+ def curl_version
82
+ Curl.version
83
+ end
84
+
85
+ def supports_zlib?
86
+ !!(curl_version.match(/zlib/))
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,115 @@
1
+ module Typhoeus
2
+ module EasyFu
3
+ module Options
4
+ def write_function=(callback)
5
+ set_option(:writefunction, body_write_callback)
6
+ end
7
+
8
+ def header_function=(callback)
9
+ set_option(:headerfunction, header_write_callback)
10
+ end
11
+
12
+ def encoding=(encoding)
13
+ # Enable encoding/compression support
14
+ set_option(:encoding, encoding)
15
+ end
16
+
17
+ def interface=(interface)
18
+ @interface = interface
19
+ set_option(:interface, interface)
20
+ end
21
+
22
+ def verbose=(boolean)
23
+ set_option(:verbose, !!boolean ? 1 : 0)
24
+ end
25
+
26
+ def follow_location=(boolean)
27
+ if boolean
28
+ set_option(:followlocation, 1)
29
+ else
30
+ set_option(:followlocation, 0)
31
+ end
32
+ end
33
+
34
+ def max_redirects=(redirects)
35
+ set_option(:maxredirs, redirects)
36
+ end
37
+
38
+ def connect_timeout=(milliseconds)
39
+ @connect_timeout = milliseconds
40
+ set_option(:nosignal, 1)
41
+ set_option(:connecttimeout_ms, milliseconds)
42
+ end
43
+
44
+ def timeout=(milliseconds)
45
+ @timeout = milliseconds
46
+ set_option(:nosignal, 1)
47
+ set_option(:timeout_ms, milliseconds)
48
+ end
49
+
50
+ def request_body=(request_body)
51
+ @request_body = request_body
52
+ if method == :put
53
+ @request_body_read = 0
54
+ set_option(:infilesize, Utils.bytesize(@request_body))
55
+ set_option(:readfunction, read_callback)
56
+ else
57
+ self.post_data = request_body
58
+ end
59
+ end
60
+
61
+ def user_agent=(user_agent)
62
+ set_option(:useragent, user_agent)
63
+ end
64
+
65
+ def url=(url)
66
+ @url = url
67
+ set_option(:url, url)
68
+ end
69
+
70
+ def method=(method)
71
+ @method = method
72
+ if method == :get
73
+ set_option(:httpget, 1)
74
+ elsif method == :post
75
+ set_option(:httppost, 1)
76
+ self.post_data = ""
77
+ elsif method == :put
78
+ set_option(:upload, 1)
79
+ self.request_body = @request_body.to_s
80
+ elsif method == :head
81
+ set_option(:nobody, 1)
82
+ else
83
+ set_option(:customrequest, method.to_s.upcase)
84
+ end
85
+ end
86
+
87
+ def post_data=(data)
88
+ @post_data_set = true
89
+ set_option(:postfieldsize, Utils.bytesize(data))
90
+ set_option(:copypostfields, data)
91
+ end
92
+
93
+ def set_option(option, value)
94
+ case value
95
+ when String
96
+ Curl.easy_setopt_string(handle, option, value.to_s)
97
+ when Integer
98
+ Curl.easy_setopt_long(handle, option, value)
99
+ when Proc, ::FFI::Function
100
+ Curl.easy_setopt_callback(handle, option, value)
101
+ when Typhoeus::Form
102
+ Curl.easy_setopt(handle, option, value.first.read_pointer)
103
+ else
104
+ Curl.easy_setopt(handle, option, value) if value
105
+ end
106
+ end
107
+
108
+ def set_headers
109
+ @header_list = nil
110
+ headers.each {|key, value| @header_list = Curl.slist_append(@header_list, "#{key}: #{value}") }
111
+ set_option(:httpheader, @header_list) unless headers.empty?
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,20 @@
1
+ module Typhoeus
2
+ module EasyFu
3
+ module Proxy
4
+ def proxy=(proxy)
5
+ set_option(:proxy, proxy[:server])
6
+ set_option(:proxytype, Typhoeus::Easy::PROXY_TYPES[proxy[:type]]) if proxy[:type]
7
+ end
8
+
9
+ def proxy_auth=(authinfo)
10
+ set_option(:proxyuserpwd, proxy_credentials(authinfo))
11
+ set_option(:proxyauth, Typhoeus::Easy::PROXY_TYPES[proxy[:type]]) if authinfo[:method]
12
+ end
13
+
14
+ def proxy_credentials(authinfo)
15
+ "#{authinfo[:username]}:#{authinfo[:password]}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,82 @@
1
+ module Typhoeus
2
+ module EasyFu
3
+ module SSL
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def valid_ssl_version(version)
10
+ Typhoeus::Easy::SSL_VERSIONS.key?(version.to_sym)
11
+ end
12
+ end
13
+
14
+ def ssl_version
15
+ @ssl_version
16
+ end
17
+
18
+ def ssl_version=(version)
19
+ raise "Invalid SSL version: '#{version}' supplied! Please supply one as listed in Typhoeus::Easy::SSL_VERSIONS" unless self.class.valid_ssl_version(version)
20
+ @ssl_version = version
21
+
22
+ set_option(:sslversion, Typhoeus::Easy::SSL_VERSIONS[version])
23
+ end
24
+
25
+ def disable_ssl_peer_verification
26
+ set_option(:verifypeer, 0)
27
+ end
28
+
29
+ def disable_ssl_host_verification
30
+ set_option(:verifyhost, 0)
31
+ end
32
+
33
+ # Set SSL certificate
34
+ # " The string should be the file name of your certificate. "
35
+ # The default format is "PEM" and can be changed with ssl_cert_type=
36
+ def ssl_cert=(cert)
37
+ set_option(:sslcert, cert)
38
+ end
39
+
40
+ # Set SSL certificate type
41
+ # " The string should be the format of your certificate. Supported formats are "PEM" and "DER" "
42
+ def ssl_cert_type=(cert_type)
43
+ raise "Invalid ssl cert type : '#{cert_type}'..." if cert_type and !%w(PEM DER p12).include?(cert_type)
44
+ set_option(:sslcerttype, cert_type)
45
+ end
46
+
47
+ # Set SSL Key file
48
+ # " The string should be the file name of your private key. "
49
+ # The default format is "PEM" and can be changed with ssl_key_type=
50
+ #
51
+ def ssl_key=(key)
52
+ set_option(:sslkey, key)
53
+ end
54
+
55
+ # Set SSL Key type
56
+ # " The string should be the format of your private key. Supported formats are "PEM", "DER" and "ENG". "
57
+ #
58
+ def ssl_key_type=(key_type)
59
+ raise "Invalid ssl key type : '#{key_type}'..." if key_type and !%w(PEM DER ENG).include?(key_type)
60
+ set_option(:sslkeytype, key_type)
61
+ end
62
+
63
+ def ssl_key_password=(key_password)
64
+ set_option(:keypasswd, key_password)
65
+ end
66
+
67
+ # Set SSL CACERT
68
+ # " File holding one or more certificates to verify the peer with. "
69
+ #
70
+ def ssl_cacert=(cacert)
71
+ set_option(:cainfo, cacert)
72
+ end
73
+
74
+ # Set CAPATH
75
+ # " directory holding multiple CA certificates to verify the peer with. The certificate directory must be prepared using the openssl c_rehash utility. "
76
+ #
77
+ def ssl_capath=(capath)
78
+ set_option(:capath, capath)
79
+ end
80
+ end
81
+ end
82
+ end
data/lib/typhoeus/form.rb CHANGED
@@ -3,16 +3,45 @@ require 'mime/types'
3
3
  module Typhoeus
4
4
  class Form
5
5
  attr_accessor :params
6
- attr_reader :traversal
6
+ attr_reader :first, :traversal
7
7
 
8
8
  def initialize(params = {})
9
9
  @params = params
10
+ @first = ::FFI::MemoryPointer.new(:pointer)
11
+ @last = ::FFI::MemoryPointer.new(:pointer)
12
+
13
+ ObjectSpace.define_finalizer(self, self.class.finalizer(self))
14
+ end
15
+
16
+ def self.finalizer(form)
17
+ proc { Curl.formfree(form.first) }
10
18
  end
11
19
 
12
20
  def traversal
13
21
  @traversal ||= Typhoeus::Utils.traverse_params_hash(params)
14
22
  end
15
23
 
24
+ def formadd_param(name, contents)
25
+ Curl.formadd(@first, @last,
26
+ :form_option, :copyname, :pointer, name,
27
+ :form_option, :namelength, :long, Utils.bytesize(name),
28
+ :form_option, :copycontents, :pointer, contents,
29
+ :form_option, :contentslength, :long, Utils.bytesize(contents),
30
+ :form_option, :end)
31
+ end
32
+ private :formadd_param
33
+
34
+ def formadd_file(name, filename, contenttype, file)
35
+ Curl.formadd(@first, @last,
36
+ :form_option, :copyname, :pointer, name,
37
+ :form_option, :namelength, :long, Utils.bytesize(name),
38
+ :form_option, :file, :string, file,
39
+ :form_option, :filename, :string, filename,
40
+ :form_option, :contenttype, :string, contenttype,
41
+ :form_option, :end)
42
+ end
43
+ private :formadd_file
44
+
16
45
  def process!
17
46
  # add params
18
47
  traversal[:params].each { |p| formadd_param(p[0], p[1]) }