hhry-typhoeus 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,115 @@
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
+
9
+ module Typhoeus
10
+ class Easy
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
31
+ attr_accessor :start_time
32
+
33
+ def initialize
34
+ Curl.init
35
+ reset(true)
36
+ ObjectSpace.define_finalizer(self, self.class.finalizer(self))
37
+ end
38
+
39
+ def method
40
+ @method ||= :get
41
+ end
42
+
43
+ def headers
44
+ @header ||= {}
45
+ end
46
+
47
+ def response_body
48
+ @response_body ||= ""
49
+ end
50
+
51
+ def response_header
52
+ @response_header ||= ""
53
+ end
54
+
55
+ def headers=(hash)
56
+ @headers = hash
57
+ end
58
+
59
+ def params
60
+ @form.nil? ? {} : @form.params
61
+ end
62
+
63
+ def params=(params)
64
+ @form = Typhoeus::Form.new(params)
65
+
66
+ if method == :post
67
+ @form.process!
68
+ if @form.multipart?
69
+ set_option(:httppost, @form)
70
+ else
71
+ self.post_data = @form.to_s
72
+ end
73
+ else
74
+ self.url = "#{url}?#{@form.to_s}"
75
+ end
76
+ end
77
+
78
+ def perform
79
+ set_headers()
80
+ @curl_return_code = Curl.easy_perform(handle)
81
+ resp_code = response_code()
82
+ if resp_code >= 200 && resp_code <= 299
83
+ success
84
+ else
85
+ failure
86
+ end
87
+ resp_code
88
+ end
89
+
90
+ def reset(fresh = nil)
91
+ unless fresh
92
+ @response_code = 0
93
+ @response_header = ""
94
+ @response_body = ""
95
+ @request_body = ""
96
+
97
+ if @header_list
98
+ Curl.slist_free_all(@header_list)
99
+ @header_list = nil
100
+ end
101
+
102
+ Curl.easy_reset(handle)
103
+ end
104
+
105
+ self.write_function = body_write_callback
106
+ self.header_function = header_write_callback
107
+ self.encoding = ''
108
+ self.ssl_version = :default
109
+ end
110
+
111
+ def curl_return_code=(code)
112
+ @curl_return_code = (code.class == Symbol ? code : Curl::EasyCode[code])
113
+ end
114
+ end
115
+ end
@@ -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,86 @@
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 curl_return_code
70
+ Curl::EasyCode[@curl_return_code]
71
+ end
72
+
73
+ def curl_error_message(code = @curl_return_code)
74
+ code ? Curl.easy_strerror(code) : nil
75
+ end
76
+
77
+ def curl_version
78
+ Curl.version
79
+ end
80
+
81
+ def supports_zlib?
82
+ !!(curl_version.match(/zlib/))
83
+ end
84
+ end
85
+ end
86
+ 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
+