typhoeus 0.4.2 → 0.5.0.alpha

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