typhoeus 0.4.2 → 0.5.0.alpha

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.
Files changed (56) hide show
  1. data/CHANGELOG.md +86 -28
  2. data/Gemfile +17 -1
  3. data/README.md +20 -422
  4. data/Rakefile +21 -12
  5. data/lib/typhoeus.rb +58 -41
  6. data/lib/typhoeus/config.rb +14 -0
  7. data/lib/typhoeus/errors.rb +9 -0
  8. data/lib/typhoeus/errors/no_stub.rb +12 -0
  9. data/lib/typhoeus/errors/typhoeus_error.rb +8 -0
  10. data/lib/typhoeus/expectation.rb +126 -0
  11. data/lib/typhoeus/hydra.rb +31 -236
  12. data/lib/typhoeus/hydras/block_connection.rb +33 -0
  13. data/lib/typhoeus/hydras/easy_factory.rb +67 -0
  14. data/lib/typhoeus/hydras/easy_pool.rb +40 -0
  15. data/lib/typhoeus/hydras/memoizable.rb +53 -0
  16. data/lib/typhoeus/hydras/queueable.rb +46 -0
  17. data/lib/typhoeus/hydras/runnable.rb +18 -0
  18. data/lib/typhoeus/hydras/stubbable.rb +27 -0
  19. data/lib/typhoeus/request.rb +68 -243
  20. data/lib/typhoeus/requests/actions.rb +101 -0
  21. data/lib/typhoeus/requests/block_connection.rb +31 -0
  22. data/lib/typhoeus/requests/callbacks.rb +82 -0
  23. data/lib/typhoeus/requests/marshal.rb +21 -0
  24. data/lib/typhoeus/requests/memoizable.rb +36 -0
  25. data/lib/typhoeus/requests/operations.rb +52 -0
  26. data/lib/typhoeus/requests/responseable.rb +29 -0
  27. data/lib/typhoeus/requests/stubbable.rb +29 -0
  28. data/lib/typhoeus/response.rb +24 -118
  29. data/lib/typhoeus/responses/header.rb +50 -0
  30. data/lib/typhoeus/responses/informations.rb +43 -0
  31. data/lib/typhoeus/responses/legacy.rb +27 -0
  32. data/lib/typhoeus/responses/status.rb +78 -0
  33. data/lib/typhoeus/version.rb +3 -1
  34. metadata +34 -141
  35. data/lib/typhoeus/curl.rb +0 -453
  36. data/lib/typhoeus/easy.rb +0 -115
  37. data/lib/typhoeus/easy/auth.rb +0 -14
  38. data/lib/typhoeus/easy/callbacks.rb +0 -33
  39. data/lib/typhoeus/easy/ffi_helper.rb +0 -61
  40. data/lib/typhoeus/easy/infos.rb +0 -90
  41. data/lib/typhoeus/easy/options.rb +0 -115
  42. data/lib/typhoeus/easy/proxy.rb +0 -20
  43. data/lib/typhoeus/easy/ssl.rb +0 -82
  44. data/lib/typhoeus/filter.rb +0 -28
  45. data/lib/typhoeus/form.rb +0 -61
  46. data/lib/typhoeus/header.rb +0 -54
  47. data/lib/typhoeus/hydra/callbacks.rb +0 -24
  48. data/lib/typhoeus/hydra/connect_options.rb +0 -61
  49. data/lib/typhoeus/hydra/stubbing.rb +0 -68
  50. data/lib/typhoeus/hydra_mock.rb +0 -131
  51. data/lib/typhoeus/multi.rb +0 -146
  52. data/lib/typhoeus/param_processor.rb +0 -43
  53. data/lib/typhoeus/remote.rb +0 -306
  54. data/lib/typhoeus/remote_method.rb +0 -108
  55. data/lib/typhoeus/remote_proxy_object.rb +0 -50
  56. data/lib/typhoeus/utils.rb +0 -50
@@ -0,0 +1,50 @@
1
+ module Typhoeus
2
+ module Responses
3
+
4
+ # This class represents the response header.
5
+ # It can be accessed like a hash.
6
+ class Header < Hash
7
+ # Create a new header.
8
+ #
9
+ # @example Create new header.
10
+ # Header.new(raw)
11
+ #
12
+ # @param [ String ] raw The raw header.
13
+ def initialize(raw)
14
+ @raw = raw
15
+ parse
16
+ end
17
+
18
+ # Returns the raw header or empty string.
19
+ #
20
+ # @example Return raw header.
21
+ # header.raw
22
+ #
23
+ # @return [ String ] The raw header.
24
+ def raw
25
+ @raw ||= ''
26
+ end
27
+
28
+ # Parses the raw header.
29
+ #
30
+ # @example Parse header.
31
+ # header.parse
32
+ def parse
33
+ raw.lines.each do |header|
34
+ unless header =~ /^HTTP\/1.[01]/
35
+ parts = header.split(':', 2)
36
+ unless parts.empty?
37
+ parts.map(&:strip!)
38
+ if self.has_key?(parts[0])
39
+ self[parts[0]] = [self[parts[0]]] unless self[parts[0]].kind_of? Array
40
+ self[parts[0]] << parts[1]
41
+ else
42
+ self[parts[0]] = parts[1]
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,43 @@
1
+ module Typhoeus
2
+ module Responses
3
+
4
+ # This module contains logic about informations
5
+ # on a response.
6
+ module Informations
7
+
8
+ # All available informations.
9
+ AVAILABLE_INFORMATIONS = Ethon::Easies::Informations::AVAILABLE_INFORMATIONS.keys+
10
+ [:return_code, :response_body, :response_header]
11
+
12
+ AVAILABLE_INFORMATIONS.each do |name|
13
+ define_method(name) do
14
+ options[name.to_sym]
15
+ end
16
+ end
17
+
18
+ # Returns the response header.
19
+ #
20
+ # @example Return header.
21
+ # response.header
22
+ #
23
+ # @return [ Header ] The response header.
24
+ def header
25
+ return nil if response_header.nil? && @header.nil?
26
+ @header ||= Responses::Header.new(response_header.split("\r\n\r\n").last)
27
+ end
28
+
29
+ # Return all redirections in between as multiple
30
+ # responses with header.
31
+ #
32
+ # @example Return redirections.
33
+ # response.redirections
34
+ #
35
+ # @return [ Array ] The redirections
36
+ def redirections
37
+ return [] unless response_header
38
+ response_header.split("\r\n\r\n")[0..-2].map{ |h| Response.new(:response_header => h) }
39
+ end
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,27 @@
1
+ module Typhoeus
2
+ module Responses # :nodoc:
3
+
4
+ # This module contains logic for providing the
5
+ # old accessors.
6
+ module Legacy
7
+
8
+ # The legacy mapping.
9
+ MAPPING = {
10
+ :body => :response_body,
11
+ :code => :response_code,
12
+ :curl_return_code => :return_code,
13
+ :time => :total_time,
14
+ :app_connect_time => :appconnect_time,
15
+ :start_transfer_time => :starttransfer_time,
16
+ :name_lookup_time => :namelookup_time,
17
+ :headers_hash => :header
18
+ }
19
+
20
+ MAPPING.each do |old, new|
21
+ define_method(old) do
22
+ options[new] || options[old]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,78 @@
1
+ module Typhoeus
2
+ module Responses
3
+
4
+ # This module contains logic about the http
5
+ # status.
6
+ module Status
7
+
8
+ # Return the status message if present.
9
+ #
10
+ # @example Return status message.
11
+ # reesponse.status_message
12
+ #
13
+ # @return [ String ] The message.
14
+ def status_message
15
+ return @status_message if defined?(@status_message) && @status_message
16
+ return options[:status_message] unless options[:status_message].nil?
17
+
18
+ # HTTP servers can choose not to include the explanation to HTTP codes. The RFC
19
+ # states this (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4):
20
+ # Except when responding to a HEAD request, the server SHOULD include an entity containing
21
+ # an explanation of the error situation [...]
22
+ # This means 'HTTP/1.1 404' is as valid as 'HTTP/1.1 404 Not Found' and we have to handle it.
23
+
24
+ # Regexp doc: http://rubular.com/r/eAr1oVYsVa
25
+ if first_header_line != nil and first_header_line[/\d{3} (.*)$/, 1] != nil
26
+ @status_message = first_header_line[/\d{3} (.*)$/, 1].chomp
27
+ else
28
+ @status_message = nil
29
+ end
30
+ end
31
+
32
+ # Return the http version.
33
+ #
34
+ # @example Return http version.
35
+ # response.http_version
36
+ #
37
+ # @return [ String ] The http version.
38
+ def http_version
39
+ @http_version ||= first_header_line ? first_header_line[/HTTP\/(\S+)/, 1] : nil
40
+ end
41
+
42
+ # Return wether the response is a success.
43
+ #
44
+ # @example Return if the response was successful.
45
+ # response.success?
46
+ #
47
+ # @return [ Boolean ] Return true if successful, false else.
48
+ def success?
49
+ return_code == :ok && response_code >= 200 && response_code < 300
50
+ end
51
+
52
+ # Return wether the response is modified.
53
+ #
54
+ # @example Return if the response was modified.
55
+ # response.modified?
56
+ #
57
+ # @return [ Boolean ] Return true if modified, false else.
58
+ def modified?
59
+ return_code == :ok && response_code != 304
60
+ end
61
+
62
+ # Return wether the response is timed out.
63
+ #
64
+ # @example Return if the response timed out..
65
+ # response.time_out?
66
+ #
67
+ # @return [ Boolean ] Return true if timed out, false else.
68
+ def timed_out?
69
+ return_code == 28
70
+ end
71
+
72
+ # :nodoc:
73
+ def first_header_line
74
+ @first_header_line ||= response_header.to_s.split("\n").first
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,3 +1,5 @@
1
1
  module Typhoeus
2
- VERSION = '0.4.2'
2
+
3
+ # The current Typhoeus version.
4
+ VERSION = '0.5.0.alpha'
3
5
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typhoeus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
5
- prerelease:
4
+ version: 0.5.0.alpha
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - David Balatero
@@ -11,16 +11,16 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-06-09 00:00:00.000000000 Z
14
+ date: 2012-08-16 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: ffi
17
+ name: ethon
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
22
22
  - !ruby/object:Gem::Version
23
- version: '1.0'
23
+ version: 0.4.2
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -28,119 +28,7 @@ dependencies:
28
28
  requirements:
29
29
  - - ~>
30
30
  - !ruby/object:Gem::Version
31
- version: '1.0'
32
- - !ruby/object:Gem::Dependency
33
- name: mime-types
34
- requirement: !ruby/object:Gem::Requirement
35
- none: false
36
- requirements:
37
- - - ~>
38
- - !ruby/object:Gem::Version
39
- version: '1.18'
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
- requirements:
45
- - - ~>
46
- - !ruby/object:Gem::Version
47
- version: '1.18'
48
- - !ruby/object:Gem::Dependency
49
- name: sinatra
50
- requirement: !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ~>
54
- - !ruby/object:Gem::Version
55
- version: '1.3'
56
- type: :development
57
- prerelease: false
58
- version_requirements: !ruby/object:Gem::Requirement
59
- none: false
60
- requirements:
61
- - - ~>
62
- - !ruby/object:Gem::Version
63
- version: '1.3'
64
- - !ruby/object:Gem::Dependency
65
- name: json
66
- requirement: !ruby/object:Gem::Requirement
67
- none: false
68
- requirements:
69
- - - ~>
70
- - !ruby/object:Gem::Version
71
- version: '1.7'
72
- type: :development
73
- prerelease: false
74
- version_requirements: !ruby/object:Gem::Requirement
75
- none: false
76
- requirements:
77
- - - ~>
78
- - !ruby/object:Gem::Version
79
- version: '1.7'
80
- - !ruby/object:Gem::Dependency
81
- name: rake
82
- requirement: !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
85
- - - ~>
86
- - !ruby/object:Gem::Version
87
- version: '0.9'
88
- type: :development
89
- prerelease: false
90
- version_requirements: !ruby/object:Gem::Requirement
91
- none: false
92
- requirements:
93
- - - ~>
94
- - !ruby/object:Gem::Version
95
- version: '0.9'
96
- - !ruby/object:Gem::Dependency
97
- name: mocha
98
- requirement: !ruby/object:Gem::Requirement
99
- none: false
100
- requirements:
101
- - - ~>
102
- - !ruby/object:Gem::Version
103
- version: '0.10'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- none: false
108
- requirements:
109
- - - ~>
110
- - !ruby/object:Gem::Version
111
- version: '0.10'
112
- - !ruby/object:Gem::Dependency
113
- name: rspec
114
- requirement: !ruby/object:Gem::Requirement
115
- none: false
116
- requirements:
117
- - - ~>
118
- - !ruby/object:Gem::Version
119
- version: '2.10'
120
- type: :development
121
- prerelease: false
122
- version_requirements: !ruby/object:Gem::Requirement
123
- none: false
124
- requirements:
125
- - - ~>
126
- - !ruby/object:Gem::Version
127
- version: '2.10'
128
- - !ruby/object:Gem::Dependency
129
- name: guard-rspec
130
- requirement: !ruby/object:Gem::Requirement
131
- none: false
132
- requirements:
133
- - - ~>
134
- - !ruby/object:Gem::Version
135
- version: '0.6'
136
- type: :development
137
- prerelease: false
138
- version_requirements: !ruby/object:Gem::Requirement
139
- none: false
140
- requirements:
141
- - - ~>
142
- - !ruby/object:Gem::Version
143
- version: '0.6'
31
+ version: 0.4.2
144
32
  description: Like a modern code version of the mythical beast with 100 serpent heads,
145
33
  Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic.
146
34
  email:
@@ -149,31 +37,33 @@ executables: []
149
37
  extensions: []
150
38
  extra_rdoc_files: []
151
39
  files:
152
- - lib/typhoeus/curl.rb
153
- - lib/typhoeus/easy/auth.rb
154
- - lib/typhoeus/easy/callbacks.rb
155
- - lib/typhoeus/easy/ffi_helper.rb
156
- - lib/typhoeus/easy/infos.rb
157
- - lib/typhoeus/easy/options.rb
158
- - lib/typhoeus/easy/proxy.rb
159
- - lib/typhoeus/easy/ssl.rb
160
- - lib/typhoeus/easy.rb
161
- - lib/typhoeus/filter.rb
162
- - lib/typhoeus/form.rb
163
- - lib/typhoeus/header.rb
164
- - lib/typhoeus/hydra/callbacks.rb
165
- - lib/typhoeus/hydra/connect_options.rb
166
- - lib/typhoeus/hydra/stubbing.rb
40
+ - lib/typhoeus/config.rb
41
+ - lib/typhoeus/errors/no_stub.rb
42
+ - lib/typhoeus/errors/typhoeus_error.rb
43
+ - lib/typhoeus/errors.rb
44
+ - lib/typhoeus/expectation.rb
167
45
  - lib/typhoeus/hydra.rb
168
- - lib/typhoeus/hydra_mock.rb
169
- - lib/typhoeus/multi.rb
170
- - lib/typhoeus/param_processor.rb
171
- - lib/typhoeus/remote.rb
172
- - lib/typhoeus/remote_method.rb
173
- - lib/typhoeus/remote_proxy_object.rb
46
+ - lib/typhoeus/hydras/block_connection.rb
47
+ - lib/typhoeus/hydras/easy_factory.rb
48
+ - lib/typhoeus/hydras/easy_pool.rb
49
+ - lib/typhoeus/hydras/memoizable.rb
50
+ - lib/typhoeus/hydras/queueable.rb
51
+ - lib/typhoeus/hydras/runnable.rb
52
+ - lib/typhoeus/hydras/stubbable.rb
174
53
  - lib/typhoeus/request.rb
54
+ - lib/typhoeus/requests/actions.rb
55
+ - lib/typhoeus/requests/block_connection.rb
56
+ - lib/typhoeus/requests/callbacks.rb
57
+ - lib/typhoeus/requests/marshal.rb
58
+ - lib/typhoeus/requests/memoizable.rb
59
+ - lib/typhoeus/requests/operations.rb
60
+ - lib/typhoeus/requests/responseable.rb
61
+ - lib/typhoeus/requests/stubbable.rb
175
62
  - lib/typhoeus/response.rb
176
- - lib/typhoeus/utils.rb
63
+ - lib/typhoeus/responses/header.rb
64
+ - lib/typhoeus/responses/informations.rb
65
+ - lib/typhoeus/responses/legacy.rb
66
+ - lib/typhoeus/responses/status.rb
177
67
  - lib/typhoeus/version.rb
178
68
  - lib/typhoeus.rb
179
69
  - CHANGELOG.md
@@ -193,6 +83,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
193
83
  - - ! '>='
194
84
  - !ruby/object:Gem::Version
195
85
  version: '0'
86
+ segments:
87
+ - 0
88
+ hash: 835980537043066263
196
89
  required_rubygems_version: !ruby/object:Gem::Requirement
197
90
  none: false
198
91
  requirements:
@@ -201,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
94
  version: 1.3.6
202
95
  requirements: []
203
96
  rubyforge_project: ! '[none]'
204
- rubygems_version: 1.8.24
97
+ rubygems_version: 1.8.23
205
98
  signing_key:
206
99
  specification_version: 3
207
100
  summary: Parallel HTTP library on top of libcurl multi.
@@ -1,453 +0,0 @@
1
- require 'ffi'
2
- require 'rbconfig'
3
- require 'thread'
4
-
5
- module Typhoeus
6
- module Curl
7
- # this does not implement the full curl lib. just what is needed for typhoeus
8
-
9
- def Curl.windows?
10
- !(RbConfig::CONFIG['host_os'] !~ /mingw|mswin|bccwin/)
11
- end
12
-
13
- extend ::FFI::Library
14
-
15
- VERSION_NOW = 3
16
-
17
- GLOBAL_SSL = 0x01
18
- GLOBAL_WIN32 = 0x02
19
- GLOBAL_ALL = (GLOBAL_SSL | GLOBAL_WIN32)
20
- GLOBAL_DEFAULT = GLOBAL_ALL
21
-
22
- EasyCode = enum :easy_code, [
23
- :ok,
24
- :unsupported_protocol,
25
- :failed_init,
26
- :url_malformat,
27
- :not_built_in,
28
- :couldnt_resolve_proxy,
29
- :couldnt_resolve_host,
30
- :couldnt_connect,
31
- :ftp_weird_server_reply,
32
- :remote_access_denied,
33
- :ftp_accept_failed,
34
- :ftp_weird_pass_reply,
35
- :ftp_accept_timeout,
36
- :ftp_weird_pasv_reply,
37
- :ftp_weird_227_format,
38
- :ftp_cant_get_host,
39
- :obsolete16,
40
- :ftp_couldnt_set_type,
41
- :partial_file,
42
- :ftp_couldnt_retr_file,
43
- :obsolete20,
44
- :quote_error,
45
- :http_returned_error,
46
- :write_error,
47
- :obsolete24,
48
- :upload_failed,
49
- :read_error,
50
- :out_of_memory,
51
- :operation_timedout,
52
- :obsolete29,
53
- :ftp_port_failed,
54
- :ftp_couldnt_use_rest,
55
- :obsolete32,
56
- :range_error,
57
- :http_post_error,
58
- :ssl_connect_error,
59
- :bad_download_resume,
60
- :file_couldnt_read_file,
61
- :ldap_cannot_bind,
62
- :ldap_search_failed,
63
- :obsolete40,
64
- :function_not_found,
65
- :aborted_by_callback,
66
- :bad_function_argument,
67
- :obsolete44,
68
- :interface_failed,
69
- :obsolete46,
70
- :too_many_redirects ,
71
- :unknown_option,
72
- :telnet_option_syntax ,
73
- :obsolete50,
74
- :peer_failed_verification,
75
- :got_nothing,
76
- :ssl_engine_notfound,
77
- :ssl_engine_setfailed,
78
- :send_error,
79
- :recv_error,
80
- :obsolete57,
81
- :ssl_certproblem,
82
- :ssl_cipher,
83
- :ssl_cacert,
84
- :bad_content_encoding,
85
- :ldap_invalid_url,
86
- :filesize_exceeded,
87
- :use_ssl_failed,
88
- :send_fail_rewind,
89
- :ssl_engine_initfailed,
90
- :login_denied,
91
- :tftp_notfound,
92
- :tftp_perm,
93
- :remote_disk_full,
94
- :tftp_illegal,
95
- :tftp_unknownid,
96
- :remote_file_exists,
97
- :tftp_nosuchuser,
98
- :conv_failed,
99
- :conv_reqd,
100
- :ssl_cacert_badfile,
101
- :remote_file_not_found,
102
- :ssh,
103
- :ssl_shutdown_failed,
104
- :again,
105
- :ssl_crl_badfile,
106
- :ssl_issuer_error,
107
- :ftp_pret_failed,
108
- :rtsp_cseq_error,
109
- :rtsp_session_error,
110
- :ftp_bad_file_list,
111
- :chunk_failed,
112
- :last]
113
-
114
- MultiCode = enum :multi_code, [
115
- :call_multi_perform, -1,
116
- :ok,
117
- :bad_handle,
118
- :bad_easy_handle,
119
- :out_of_memory,
120
- :internal_error,
121
- :bad_socket,
122
- :unknown_option,
123
- :last]
124
-
125
- OptionType = enum [
126
- :long, 0,
127
- :object_point, 10000,
128
- :function_point, 20000,
129
- :off_t, 30000]
130
-
131
- Option = enum :option, [
132
- :file, OptionType[:object_point] + 1,
133
- :writedata, OptionType[:object_point] + 1,
134
- :url, OptionType[:object_point] + 2,
135
- :port, OptionType[:long] + 3,
136
- :proxy, OptionType[:object_point] + 4,
137
- :userpwd, OptionType[:object_point] + 5,
138
- :proxyuserpwd, OptionType[:object_point] + 6,
139
- :range, OptionType[:object_point] + 7,
140
- :infile, OptionType[:object_point] + 9,
141
- :readdata, OptionType[:object_point] + 9,
142
- :errorbuffer, OptionType[:object_point] + 10,
143
- :writefunction, OptionType[:function_point] + 11,
144
- :readfunction, OptionType[:function_point] + 12,
145
- :timeout, OptionType[:long] + 13,
146
- :infilesize, OptionType[:long] + 14,
147
- :postfields, OptionType[:object_point] + 15,
148
- :referer, OptionType[:object_point] + 16,
149
- :ftpport, OptionType[:object_point] + 17,
150
- :useragent, OptionType[:object_point] + 18,
151
- :low_speed_time, OptionType[:long] + 20,
152
- :resume_from, OptionType[:long] + 21,
153
- :cookie, OptionType[:object_point] + 22,
154
- :httpheader, OptionType[:object_point] + 23,
155
- :httppost, OptionType[:object_point] + 24,
156
- :sslcert, OptionType[:object_point] + 25,
157
- :sslcertpasswd, OptionType[:object_point] + 26,
158
- :sslkeypasswd, OptionType[:object_point] + 26,
159
- :crlf, OptionType[:long] + 27,
160
- :quote, OptionType[:object_point] + 28,
161
- :writeheader, OptionType[:object_point] + 29,
162
- :headerdata, OptionType[:object_point] + 29,
163
- :cookiefile, OptionType[:object_point] + 31,
164
- :sslversion, OptionType[:long] + 32,
165
- :timecondition, OptionType[:long] + 33,
166
- :timevalue, OptionType[:long] + 34,
167
- :customrequest, OptionType[:object_point] + 36,
168
- :stderr, OptionType[:object_point] + 37,
169
- :postquote, OptionType[:object_point] + 39,
170
- :writeinfo, OptionType[:object_point] + 40,
171
- :verbose, OptionType[:long] + 41,
172
- :header, OptionType[:long] + 42,
173
- :noprogress, OptionType[:long] + 43,
174
- :nobody, OptionType[:long] + 44,
175
- :failonerror, OptionType[:long] + 45,
176
- :upload, OptionType[:long] + 46,
177
- :post, OptionType[:long] + 47,
178
- :ftplistonly, OptionType[:long] + 48,
179
- :ftpappend, OptionType[:long] + 50,
180
- :netrc, OptionType[:long] + 51,
181
- :followlocation, OptionType[:long] + 52,
182
- :transfertext, OptionType[:long] + 53,
183
- :put, OptionType[:long] + 54,
184
- :progressfunction, OptionType[:function_point] + 56,
185
- :progressdata, OptionType[:object_point] + 57,
186
- :autoreferer, OptionType[:long] + 58,
187
- :proxyport, OptionType[:long] + 59,
188
- :postfieldsize, OptionType[:long] + 60,
189
- :httpproxytunnel, OptionType[:long] + 61,
190
- :interface, OptionType[:object_point] + 62,
191
- :ssl_verifypeer, OptionType[:long] + 64,
192
- :cainfo, OptionType[:object_point] + 65,
193
- :maxredirs, OptionType[:long] + 68,
194
- :filetime, OptionType[:long] + 69,
195
- :telnetoptions, OptionType[:object_point] + 70,
196
- :maxconnects, OptionType[:long] + 71,
197
- :closepolicy, OptionType[:long] + 72,
198
- :fresh_connect, OptionType[:long] + 74,
199
- :forbid_reuse, OptionType[:long] + 75,
200
- :random_file, OptionType[:object_point] + 76,
201
- :egdsocket, OptionType[:object_point] + 77,
202
- :connecttimeout, OptionType[:long] + 78,
203
- :headerfunction, OptionType[:function_point] + 79,
204
- :httpget, OptionType[:long] + 80,
205
- :ssl_verifyhost, OptionType[:long] + 81,
206
- :cookiejar, OptionType[:object_point] + 82,
207
- :ssl_cipher_list, OptionType[:object_point] + 83,
208
- :http_version, OptionType[:long] + 84,
209
- :ftp_use_epsv, OptionType[:long] + 85,
210
- :sslcerttype, OptionType[:object_point] + 86,
211
- :sslkey, OptionType[:object_point] + 87,
212
- :sslkeytype, OptionType[:object_point] + 88,
213
- :sslengine, OptionType[:object_point] + 89,
214
- :sslengine_default, OptionType[:long] + 90,
215
- :dns_use_global_cache, OptionType[:long] + 91,
216
- :dns_cache_timeout, OptionType[:long] + 92,
217
- :prequote, OptionType[:object_point] + 93,
218
- :debugfunction, OptionType[:function_point] + 94,
219
- :debugdata, OptionType[:object_point] + 95,
220
- :cookiesession, OptionType[:long] + 96,
221
- :capath, OptionType[:object_point] + 97,
222
- :buffersize, OptionType[:long] + 98,
223
- :nosignal, OptionType[:long] + 99,
224
- :share, OptionType[:object_point] + 100,
225
- :proxytype, OptionType[:long] + 101,
226
- :encoding, OptionType[:object_point] + 102,
227
- :private, OptionType[:object_point] + 103,
228
- :unrestricted_auth, OptionType[:long] + 105,
229
- :ftp_use_eprt, OptionType[:long] + 106,
230
- :httpauth, OptionType[:long] + 107,
231
- :ssl_ctx_function, OptionType[:function_point] + 108,
232
- :ssl_ctx_data, OptionType[:object_point] + 109,
233
- :ftp_create_missing_dirs, OptionType[:long] + 110,
234
- :proxyauth, OptionType[:long] + 111,
235
- :ipresolve, OptionType[:long] + 113,
236
- :maxfilesize, OptionType[:long] + 114,
237
- :infilesize_large, OptionType[:off_t] + 115,
238
- :resume_from_large, OptionType[:off_t] + 116,
239
- :maxfilesize_large, OptionType[:off_t] + 117,
240
- :netrc_file, OptionType[:object_point] + 118,
241
- :ftp_ssl, OptionType[:long] + 119,
242
- :postfieldsize_large, OptionType[:off_t] + 120,
243
- :tcp_nodelay, OptionType[:long] + 121,
244
- :ftpsslauth, OptionType[:long] + 129,
245
- :ioctlfunction, OptionType[:function_point] + 130,
246
- :ioctldata, OptionType[:object_point] + 131,
247
- :ftp_account, OptionType[:object_point] + 134,
248
- :cookielist, OptionType[:object_point] + 135,
249
- :ignore_content_length, OptionType[:long] + 136,
250
- :ftp_skip_pasv_ip, OptionType[:long] + 137,
251
- :ftp_filemethod, OptionType[:long] + 138,
252
- :localport, OptionType[:long] + 139,
253
- :localportrange, OptionType[:long] + 140,
254
- :connect_only, OptionType[:long] + 141,
255
- :conv_from_network_function, OptionType[:function_point] + 142,
256
- :conv_to_network_function, OptionType[:function_point] + 143,
257
- :max_send_speed_large, OptionType[:off_t] + 145,
258
- :max_recv_speed_large, OptionType[:off_t] + 146,
259
- :ftp_alternative_to_user, OptionType[:object_point] + 147,
260
- :sockoptfunction, OptionType[:function_point] + 148,
261
- :sockoptdata, OptionType[:object_point] + 149,
262
- :ssl_sessionid_cache, OptionType[:long] + 150,
263
- :ssh_auth_types, OptionType[:long] + 151,
264
- :ssh_public_keyfile, OptionType[:object_point] + 152,
265
- :ssh_private_keyfile, OptionType[:object_point] + 153,
266
- :ftp_ssl_ccc, OptionType[:long] + 154,
267
- :timeout_ms, OptionType[:long] + 155,
268
- :connecttimeout_ms, OptionType[:long] + 156,
269
- :http_transfer_decoding, OptionType[:long] + 157,
270
- :http_content_decoding, OptionType[:long] + 158,
271
- :copypostfields, OptionType[:object_point] + 165]
272
-
273
- InfoType = enum [
274
- :string, 0x100000,
275
- :long, 0x200000,
276
- :double, 0x300000,
277
- :slist, 0x400000]
278
-
279
- Info = enum :info, [
280
- :effective_url, InfoType[:string] + 1,
281
- :response_code, InfoType[:long] + 2,
282
- :total_time, InfoType[:double] + 3,
283
- :namelookup_time, InfoType[:double] + 4,
284
- :connect_time, InfoType[:double] + 5,
285
- :pretransfer_time, InfoType[:double] + 6,
286
- :size_upload, InfoType[:double] + 7,
287
- :size_download, InfoType[:double] + 8,
288
- :speed_download, InfoType[:double] + 9,
289
- :speed_upload, InfoType[:double] + 10,
290
- :header_size, InfoType[:long] + 11,
291
- :request_size, InfoType[:long] + 12,
292
- :ssl_verifyresult, InfoType[:long] + 13,
293
- :filetime, InfoType[:long] + 14,
294
- :content_length_download, InfoType[:double] + 15,
295
- :content_length_upload, InfoType[:double] + 16,
296
- :starttransfer_time, InfoType[:double] + 17,
297
- :content_type, InfoType[:string] + 18,
298
- :redirect_time, InfoType[:double] + 19,
299
- :redirect_count, InfoType[:long] + 20,
300
- :private, InfoType[:string] + 21,
301
- :http_connectcode, InfoType[:long] + 22,
302
- :httpauth_avail, InfoType[:long] + 23,
303
- :proxyauth_avail, InfoType[:long] + 24,
304
- :os_errno, InfoType[:long] + 25,
305
- :num_connects, InfoType[:long] + 26,
306
- :ssl_engines, InfoType[:slist] + 27,
307
- :cookielist, InfoType[:slist] + 28,
308
- :lastsocket, InfoType[:long] + 29,
309
- :ftp_entry_path, InfoType[:string] + 30,
310
- :redirect_url, InfoType[:string] + 31,
311
- :primary_ip, InfoType[:string] + 32,
312
- :appconnect_time, InfoType[:double] + 33,
313
- :certinfo, InfoType[:slist] + 34,
314
- :condition_unmet, InfoType[:long] + 35,
315
- :rtsp_session_id, InfoType[:string] + 36,
316
- :rtsp_client_cseq, InfoType[:long] + 37,
317
- :rtsp_server_cseq, InfoType[:long] + 38,
318
- :rtsp_cseq_recv, InfoType[:long] + 39,
319
- :primary_port, InfoType[:long] + 40,
320
- :local_ip, InfoType[:string] + 41,
321
- :local_port, InfoType[:long] + 42,
322
- :last, 42]
323
-
324
- FormOption = enum :form_option, [
325
- :none,
326
- :copyname,
327
- :ptrname,
328
- :namelength,
329
- :copycontents,
330
- :ptrcontents,
331
- :contentslength,
332
- :filecontent,
333
- :array,
334
- :obsolete,
335
- :file,
336
- :buffer,
337
- :bufferptr,
338
- :bufferlength,
339
- :contenttype,
340
- :contentheader,
341
- :filename,
342
- :end,
343
- :obsolete2,
344
- :stream,
345
- :last]
346
-
347
- Auth = enum [
348
- :basic, 0x01,
349
- :digest, 0x02,
350
- :gssnegotiate, 0x04,
351
- :ntlm, 0x08,
352
- :digest_ie, 0x10,
353
- :auto, 0x1f] # all options or'd together
354
-
355
- Proxy = enum [
356
- :http, 0,
357
- :http_1_0, 1,
358
- :socks4, 4,
359
- :socks5, 5,
360
- :socks4a, 6]
361
-
362
- SSLVersion = enum [
363
- :default, 0,
364
- :tlsv1, 1,
365
- :sslv2, 2,
366
- :sslv3, 3]
367
-
368
- MsgCode = enum :msg_code, [:none, :done, :last]
369
-
370
- class MsgData < ::FFI::Union
371
- layout :whatever, :pointer,
372
- :code, :easy_code
373
- end
374
-
375
- class Msg < ::FFI::Struct
376
- layout :code, :msg_code,
377
- :easy_handle, :pointer,
378
- :data, MsgData
379
- end
380
-
381
- class FDSet < ::FFI::Struct
382
- # XXX how does this work on non-windows? how can curl know the new size...
383
- FD_SETSIZE = 524288 # set a higher maximum number of fds. this has never applied to windows, so just use the default there
384
-
385
- if Curl.windows?
386
- layout :fd_count, :u_int,
387
- :fd_array, [:u_int, 64] # 2048 FDs
388
-
389
- def clear; self[:fd_count] = 0; end
390
- else
391
- layout :fds_bits, [:long, FD_SETSIZE / ::FFI::Type::LONG.size]
392
-
393
- def clear; super; end
394
- end
395
- end
396
-
397
- class Timeval < ::FFI::Struct
398
- layout :sec, :time_t,
399
- :usec, :suseconds_t
400
- end
401
-
402
- callback :callback, [:pointer, :size_t, :size_t, :pointer], :size_t
403
-
404
- ffi_lib_flags :now, :global
405
- ffi_lib 'libcurl'
406
-
407
- attach_function :global_init, :curl_global_init, [:long], :int
408
-
409
- attach_function :easy_init, :curl_easy_init, [], :pointer
410
- attach_function :easy_cleanup, :curl_easy_cleanup, [:pointer], :void
411
- attach_function :easy_getinfo, :curl_easy_getinfo, [:pointer, :info, :pointer], :easy_code
412
- attach_function :easy_setopt, :curl_easy_setopt, [:pointer, :option, :pointer], :easy_code
413
- attach_function :easy_setopt_string, :curl_easy_setopt, [:pointer, :option, :string], :easy_code
414
- attach_function :easy_setopt_long, :curl_easy_setopt, [:pointer, :option, :long], :easy_code
415
- attach_function :easy_setopt_callback, :curl_easy_setopt, [:pointer, :option, :callback], :easy_code
416
- attach_function :easy_perform, :curl_easy_perform, [:pointer], :easy_code
417
- attach_function :easy_strerror, :curl_easy_strerror, [:int], :string
418
- attach_function :easy_escape, :curl_easy_escape, [:pointer, :pointer, :int], :string
419
- attach_function :easy_reset, :curl_easy_reset, [:pointer], :void
420
-
421
- attach_function :formadd, :curl_formadd, [:pointer, :pointer, :varargs], :int
422
-
423
- attach_function :multi_init, :curl_multi_init, [], :pointer
424
- attach_function :multi_add_handle, :curl_multi_add_handle, [:pointer, :pointer], :multi_code
425
- attach_function :multi_remove_handle, :curl_multi_remove_handle, [:pointer, :pointer], :multi_code
426
- attach_function :multi_info_read, :curl_multi_info_read, [:pointer, :pointer], Msg.ptr
427
- attach_function :multi_perform, :curl_multi_perform, [:pointer, :pointer], :multi_code
428
- attach_function :multi_timeout, :curl_multi_timeout, [:pointer, :pointer], :multi_code
429
- attach_function :multi_fdset, :curl_multi_fdset, [:pointer, FDSet.ptr, FDSet.ptr, FDSet.ptr, :pointer], :multi_code
430
- attach_function :multi_strerror, :curl_multi_strerror, [:int], :string
431
-
432
- attach_function :version, :curl_version, [], :string
433
- attach_function :slist_append, :curl_slist_append, [:pointer, :string], :pointer
434
- attach_function :slist_free_all, :curl_slist_free_all, [:pointer], :void
435
-
436
- ffi_lib (windows? ? 'ws2_32' : ::FFI::Library::LIBC)
437
- @blocking = true
438
- attach_function :select, [:int, FDSet.ptr, FDSet.ptr, FDSet.ptr, Timeval.ptr], :int
439
-
440
- @@initialized = false
441
- @@init_mutex = Mutex.new
442
-
443
- def Curl.init
444
- # ensure curl lib is initialised. not thread-safe so must be wrapped in a mutex
445
- @@init_mutex.synchronize {
446
- if not @@initialized
447
- raise RuntimeError.new('curl failed to initialise') if Curl.global_init(GLOBAL_ALL) != 0
448
- @@initialized = true
449
- end
450
- }
451
- end
452
- end
453
- end