scnr-ethon 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +379 -0
  3. data/LICENSE +20 -0
  4. data/README.md +118 -0
  5. data/ethon.gemspec +29 -0
  6. data/lib/ethon/curl.rb +90 -0
  7. data/lib/ethon/curls/classes.rb +65 -0
  8. data/lib/ethon/curls/codes.rb +122 -0
  9. data/lib/ethon/curls/constants.rb +80 -0
  10. data/lib/ethon/curls/form_options.rb +37 -0
  11. data/lib/ethon/curls/functions.rb +58 -0
  12. data/lib/ethon/curls/infos.rb +151 -0
  13. data/lib/ethon/curls/messages.rb +19 -0
  14. data/lib/ethon/curls/options.rb +503 -0
  15. data/lib/ethon/curls/settings.rb +12 -0
  16. data/lib/ethon/easy/callbacks.rb +149 -0
  17. data/lib/ethon/easy/debug_info.rb +47 -0
  18. data/lib/ethon/easy/features.rb +31 -0
  19. data/lib/ethon/easy/form.rb +107 -0
  20. data/lib/ethon/easy/header.rb +61 -0
  21. data/lib/ethon/easy/http/actionable.rb +157 -0
  22. data/lib/ethon/easy/http/custom.rb +29 -0
  23. data/lib/ethon/easy/http/delete.rb +25 -0
  24. data/lib/ethon/easy/http/get.rb +24 -0
  25. data/lib/ethon/easy/http/head.rb +24 -0
  26. data/lib/ethon/easy/http/options.rb +24 -0
  27. data/lib/ethon/easy/http/patch.rb +24 -0
  28. data/lib/ethon/easy/http/post.rb +26 -0
  29. data/lib/ethon/easy/http/postable.rb +32 -0
  30. data/lib/ethon/easy/http/put.rb +27 -0
  31. data/lib/ethon/easy/http/putable.rb +25 -0
  32. data/lib/ethon/easy/http.rb +68 -0
  33. data/lib/ethon/easy/informations.rb +116 -0
  34. data/lib/ethon/easy/mirror.rb +36 -0
  35. data/lib/ethon/easy/operations.rb +65 -0
  36. data/lib/ethon/easy/options.rb +50 -0
  37. data/lib/ethon/easy/params.rb +29 -0
  38. data/lib/ethon/easy/queryable.rb +154 -0
  39. data/lib/ethon/easy/response_callbacks.rb +136 -0
  40. data/lib/ethon/easy/util.rb +28 -0
  41. data/lib/ethon/easy.rb +315 -0
  42. data/lib/ethon/errors/ethon_error.rb +9 -0
  43. data/lib/ethon/errors/global_init.rb +13 -0
  44. data/lib/ethon/errors/invalid_option.rb +13 -0
  45. data/lib/ethon/errors/invalid_value.rb +13 -0
  46. data/lib/ethon/errors/multi_add.rb +12 -0
  47. data/lib/ethon/errors/multi_fdset.rb +12 -0
  48. data/lib/ethon/errors/multi_remove.rb +12 -0
  49. data/lib/ethon/errors/multi_timeout.rb +13 -0
  50. data/lib/ethon/errors/select.rb +13 -0
  51. data/lib/ethon/errors.rb +17 -0
  52. data/lib/ethon/libc.rb +21 -0
  53. data/lib/ethon/loggable.rb +59 -0
  54. data/lib/ethon/multi/operations.rb +228 -0
  55. data/lib/ethon/multi/options.rb +117 -0
  56. data/lib/ethon/multi/stack.rb +49 -0
  57. data/lib/ethon/multi.rb +126 -0
  58. data/lib/ethon/version.rb +6 -0
  59. data/lib/ethon.rb +36 -0
  60. metadata +117 -0
@@ -0,0 +1,503 @@
1
+ # frozen_string_literal: true
2
+ module Ethon
3
+ module Curls
4
+
5
+ # This module contains logic for setting options on
6
+ # easy or multi interface.
7
+ module Options
8
+
9
+ OPTION_STRINGS = { :easy => 'easy_options', :multi => 'multi_options' }.freeze
10
+ FOPTION_STRINGS = { :easy => 'EASY_OPTIONS', :multi => 'MULTI_OPTIONS' }.freeze
11
+ FUNCS = { :easy => 'easy_setopt', :multi => 'multi_setopt' }.freeze
12
+ # Sets appropriate option for easy, depending on value type.
13
+ def set_option(option, value, handle, type = :easy)
14
+ type = type.to_sym unless type.is_a?(Symbol)
15
+ raise NameError, "Ethon::Curls::Options unknown type #{type}." unless respond_to?(OPTION_STRINGS[type])
16
+ opthash=send(OPTION_STRINGS[type], nil)
17
+ raise Errors::InvalidOption.new(option) unless opthash.include?(option)
18
+
19
+ case opthash[option][:type]
20
+ when :none
21
+ return if value.nil?
22
+ value=1
23
+ va_type=:long
24
+ when :int
25
+ return if value.nil?
26
+ va_type=:long
27
+ value=value.to_i
28
+ when :bool
29
+ return if value.nil?
30
+ va_type=:long
31
+ value=(value&&value!=0) ? 1 : 0
32
+ when :time
33
+ return if value.nil?
34
+ va_type=:long
35
+ value=value.to_i
36
+ when :enum
37
+ return if value.nil?
38
+ va_type=:long
39
+ value = case value
40
+ when Symbol
41
+ opthash[option][:opts][value]
42
+ when String
43
+ opthash[option][:opts][value.to_sym]
44
+ else
45
+ value
46
+ end.to_i
47
+ when :bitmask
48
+ return if value.nil?
49
+ va_type=:long
50
+ value = case value
51
+ when Symbol
52
+ opthash[option][:opts][value]
53
+ when Array
54
+ value.inject(0) { |res,v| res|opthash[option][:opts][v] }
55
+ else
56
+ value
57
+ end.to_i
58
+ when :string
59
+ va_type=:string
60
+ value=value.to_s unless value.nil?
61
+ when :string_as_pointer
62
+ va_type = :pointer
63
+ s = ''
64
+ s = value.to_s unless value.nil?
65
+ value = FFI::MemoryPointer.new(:char, s.bytesize)
66
+ value.put_bytes(0, s)
67
+ when :string_escape_null
68
+ va_type=:string
69
+ value=Util.escape_zero_byte(value) unless value.nil?
70
+ when :ffipointer
71
+ va_type=:pointer
72
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? FFI::Pointer
73
+ when :curl_slist
74
+ va_type=:pointer
75
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? FFI::Pointer
76
+ when :buffer
77
+ raise NotImplementedError, "Ethon::Curls::Options option #{option} buffer type not implemented."
78
+ when :dontuse_object
79
+ raise NotImplementedError, "Ethon::Curls::Options option #{option} type not implemented."
80
+ when :cbdata
81
+ raise NotImplementedError, "Ethon::Curls::Options option #{option} callback data type not implemented. Use Ruby closures."
82
+ when :callback
83
+ va_type=:callback
84
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
85
+ when :socket_callback
86
+ va_type=:socket_callback
87
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
88
+ when :timer_callback
89
+ va_type=:timer_callback
90
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
91
+ when :debug_callback
92
+ va_type=:debug_callback
93
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
94
+ when :progress_callback
95
+ va_type=:progress_callback
96
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
97
+ when :off_t
98
+ return if value.nil?
99
+ va_type=:int64
100
+ value=value.to_i
101
+ end
102
+
103
+ if va_type==:long or va_type==:int64 then
104
+ bits=FFI.type_size(va_type)*8
105
+ tv=((value<0) ? value.abs-1 : value)
106
+ raise Errors::InvalidValue.new(option,value) unless tv<(1<<bits)
107
+ end
108
+ send(FUNCS[type], handle, opthash[option][:opt], va_type, value)
109
+ end
110
+
111
+ OPTION_TYPE_BASE = {
112
+ :long => 0,
113
+ :objectpoint => 10000,
114
+ :functionpoint => 20000,
115
+ :off_t => 30000
116
+ }
117
+ OPTION_TYPE_MAP = {
118
+ :none => :long,
119
+ :int => :long,
120
+ :bool => :long,
121
+ :time => :long,
122
+ :enum => :long, # Two ways to specify values (as opts parameter):
123
+ # * Array of symbols, these will number sequentially
124
+ # starting at 0. Skip elements with nil. (see :netrc)
125
+ # * Hash of :symbol => enum_value (See :proxytype)
126
+ :bitmask => :long, # Three ways to specify values (as opts parameter):
127
+ # * Hash of :symbol => bitmask_value or Array.
128
+ # An Array can be an array of already defined
129
+ # Symbols, which represents a bitwise or of those
130
+ # symbols. (See :httpauth)
131
+ # * Array of symbols, these will number the bits
132
+ # sequentially (i.e. 0, 1, 2, 4, etc.). Skip
133
+ # elements with nil. The last element can be a
134
+ # Hash, which will be interpreted as above.
135
+ # (See :protocols)
136
+ # :all defaults to all bits set
137
+ :string => :objectpoint,
138
+ :string_escape_null => :objectpoint,
139
+ :string_as_pointer => :objectpoint,
140
+ :ffipointer => :objectpoint, # FFI::Pointer
141
+ :curl_slist => :objectpoint,
142
+ :buffer => :objectpoint, # A memory buffer of size defined in the options
143
+ :dontuse_object => :objectpoint, # An object we don't support (e.g. FILE*)
144
+ :cbdata => :objectpoint,
145
+ :callback => :functionpoint,
146
+ :socket_callback => :functionpoint,
147
+ :timer_callback => :functionpoint,
148
+ :debug_callback => :functionpoint,
149
+ :progress_callback => :functionpoint,
150
+ :off_t => :off_t,
151
+ }
152
+
153
+ def self.option(ftype,name,type,num,opts=nil)
154
+ case type
155
+ when :enum
156
+ if opts.is_a? Array then
157
+ opts=Hash[opts.each_with_index.to_a]
158
+ elsif not opts.is_a? Hash then
159
+ raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash."
160
+ end
161
+
162
+ when :bitmask
163
+ if opts.is_a? Array then
164
+ if opts.last.is_a? Hash then
165
+ hopts=opts.pop
166
+ else
167
+ hopts={}
168
+ end
169
+ opts.each_with_index do |v,i|
170
+ next if v.nil?
171
+ if i==0 then
172
+ hopts[v]=0
173
+ else
174
+ hopts[v]=1<<(i-1)
175
+ end
176
+ end
177
+ opts=hopts
178
+ elsif not opts.is_a? Hash then
179
+ raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash."
180
+ end
181
+ opts[:all]=-1 unless opts.include? :all
182
+ opts.each do |k,v|
183
+ if v.is_a? Array then
184
+ opts[k]=v.map { |b| opts[b] }.inject :|
185
+ end
186
+ end
187
+
188
+ when :buffer
189
+ raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash." unless opts.is_a? Integer
190
+
191
+ else
192
+ raise ArgumentError, "Ethon::Curls::Options #{ftype} #{name} Expected no opts." unless opts.nil?
193
+ end
194
+ opthash=const_get(FOPTION_STRINGS[ftype])
195
+ opthash[name] = { :type => type,
196
+ :opt => OPTION_TYPE_BASE[OPTION_TYPE_MAP[type]] + num,
197
+ :opts => opts }
198
+ end
199
+
200
+ def self.option_alias(ftype,name,*aliases)
201
+ opthash=const_get(FOPTION_STRINGS[ftype])
202
+ aliases.each { |a| opthash[a]=opthash[name] }
203
+ end
204
+
205
+ def self.option_type(type)
206
+ cname = FOPTION_STRINGS[type]
207
+ const_set(cname, {})
208
+ define_method(OPTION_STRINGS[type]) do |rt|
209
+ return Ethon::Curls::Options.const_get(cname).map { |k, v| [k, v[:opt]] } if rt == :enum
210
+ Ethon::Curls::Options.const_get(cname)
211
+ end
212
+ end
213
+
214
+ # Curl multi options, refer
215
+ # Defined @ https://github.com/bagder/curl/blob/master/include/curl/multi.h
216
+ # Documentation @ http://curl.haxx.se/libcurl/c/curl_multi_setopt.html
217
+ option_type :multi
218
+
219
+ option :multi, :socketfunction, :socket_callback, 1
220
+ option :multi, :socketdata, :cbdata, 2
221
+ option :multi, :pipelining, :int, 3
222
+ option :multi, :timerfunction, :timer_callback, 4
223
+ option :multi, :timerdata, :cbdata, 5
224
+ option :multi, :maxconnects, :int, 6
225
+ option :multi, :max_host_connections, :int, 7
226
+ option :multi, :max_pipeline_length, :int, 8
227
+ option :multi, :content_length_penalty_size, :off_t, 9
228
+ option :multi, :chunk_length_penalty_size, :off_t, 10
229
+ option :multi, :pipelining_site_bl, :dontuse_object, 11
230
+ option :multi, :pipelining_server_bl, :dontuse_object, 12
231
+ option :multi, :max_total_connections, :int, 3
232
+
233
+ # Curl easy options
234
+ # Defined @ https://github.com/bagder/curl/blob/master/include/curl/curl.h
235
+ # Documentation @ http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
236
+ ## BEHAVIOR OPTIONS
237
+ option_type :easy
238
+
239
+ option :easy, :verbose, :bool, 41
240
+ option :easy, :header, :bool, 42
241
+ option :easy, :noprogress, :bool, 43
242
+ option :easy, :nosignal, :bool, 99
243
+ option :easy, :wildcardmatch, :bool, 197
244
+ ## CALLBACK OPTIONS
245
+ option :easy, :writefunction, :callback, 11
246
+ option :easy, :file, :cbdata, 1
247
+ option_alias :easy, :file, :writedata
248
+ option :easy, :readfunction, :callback, 12
249
+ option :easy, :infile, :cbdata, 9
250
+ option_alias :easy, :infile, :readdata
251
+ option :easy, :ioctlfunction, :callback, 130
252
+ option :easy, :ioctldata, :cbdata, 131
253
+ option :easy, :seekfunction, :callback, 167
254
+ option :easy, :seekdata, :cbdata, 168
255
+ option :easy, :sockoptfunction, :callback, 148
256
+ option :easy, :sockoptdata, :cbdata, 149
257
+ option :easy, :opensocketfunction, :callback, 163
258
+ option :easy, :opensocketdata, :cbdata, 164
259
+ option :easy, :closesocketfunction, :callback, 208
260
+ option :easy, :closesocketdata, :cbdata, 209
261
+ option :easy, :path_as_is, :bool, 234
262
+ option :easy, :progressfunction, :progress_callback, 56
263
+ option :easy, :progressdata, :cbdata, 57
264
+ option :easy, :headerfunction, :callback, 79
265
+ option :easy, :writeheader, :cbdata, 29
266
+ option_alias :easy, :writeheader, :headerdata
267
+ option :easy, :debugfunction, :debug_callback, 94
268
+ option :easy, :debugdata, :cbdata, 95
269
+ option :easy, :ssl_ctx_function, :callback, 108
270
+ option :easy, :ssl_ctx_data, :cbdata, 109
271
+ option :easy, :conv_to_network_function, :callback, 143
272
+ option :easy, :conv_from_network_function, :callback, 142
273
+ option :easy, :conv_from_utf8_function, :callback, 144
274
+ option :easy, :interleavefunction, :callback, 196
275
+ option :easy, :interleavedata, :cbdata, 195
276
+ option :easy, :chunk_bgn_function, :callback, 198
277
+ option :easy, :chunk_end_function, :callback, 199
278
+ option :easy, :chunk_data, :cbdata, 201
279
+ option :easy, :fnmatch_function, :callback, 200
280
+ option :easy, :fnmatch_data, :cbdata, 202
281
+ option :easy, :xferinfofunction, :progress_callback, 219
282
+ option :easy, :xferinfodata, :cbdata, 57
283
+ ## ERROR OPTIONS
284
+ option :easy, :errorbuffer, :buffer, 10, 256
285
+ option :easy, :stderr, :dontuse_object, 37
286
+ option :easy, :failonerror, :bool, 45
287
+ ## NETWORK OPTIONS
288
+ option :easy, :url, :string, 2
289
+ option :easy, :protocols, :bitmask, 181, [nil, :http, :https, :ftp, :ftps, :scp, :sftp, :telnet, :ldap, :ldaps, :dict, :file, :tftp, :imap, :imaps, :pop3, :pop3s, :smtp, :smtps, :rtsp, :rtmp, :rtmpt, :rtmpe, :rtmpte, :rtmps, :rtmpts, :gopher]
290
+ option :easy, :redir_protocols, :bitmask, 182, [nil, :http, :https, :ftp, :ftps, :scp, :sftp, :telnet, :ldap, :ldaps, :dict, :file, :tftp, :imap, :imaps, :pop3, :pop3s, :smtp, :smtps, :rtsp, :rtmp, :rtmpt, :rtmpe, :rtmpte, :rtmps, :rtmpts, :gopher]
291
+ option :easy, :proxy, :string, 4
292
+ option :easy, :proxyport, :int, 59
293
+ option :easy, :proxytype, :enum, 101, [:http, :http_1_0, :https, nil, :socks4, :socks5, :socks4a, :socks5_hostname]
294
+ option :easy, :noproxy, :string, 177
295
+ option :easy, :httpproxytunnel, :bool, 61
296
+ option :easy, :socks5_gssapi_service, :string, 179
297
+ option :easy, :socks5_gssapi_nec, :bool, 180
298
+ option :easy, :interface, :string, 62
299
+ option :easy, :localport, :int, 139
300
+ option :easy, :localportrange, :int, 140
301
+ option :easy, :dns_cache_timeout, :int, 92
302
+ option :easy, :dns_use_global_cache, :bool, 91 # Obsolete
303
+ option :easy, :dns_interface, :string, 221
304
+ option :easy, :dns_local_ip4, :string, 222
305
+ option :easy, :dns_shuffle_addresses, :bool, 275
306
+ option :easy, :buffersize, :int, 98
307
+ option :easy, :port, :int, 3
308
+ option :easy, :tcp_nodelay, :bool, 121
309
+ option :easy, :address_scope, :int, 171
310
+ option :easy, :tcp_fastopen, :bool, 212
311
+ option :easy, :tcp_keepalive, :bool, 213
312
+ option :easy, :tcp_keepidle, :int, 214
313
+ option :easy, :tcp_keepintvl, :int, 215
314
+ ## NAMES and PASSWORDS OPTIONS (Authentication)
315
+ option :easy, :netrc, :enum, 51, [:ignored, :optional, :required]
316
+ option :easy, :netrc_file, :string, 118
317
+ option :easy, :userpwd, :string, 5
318
+ option :easy, :proxyuserpwd, :string, 6
319
+ option :easy, :username, :string, 173
320
+ option :easy, :password, :string, 174
321
+ option :easy, :proxyusername, :string, 175
322
+ option :easy, :proxypassword, :string, 176
323
+ option :easy, :httpauth, :bitmask, 107, [:none, :basic, :digest, :gssnegotiate, :ntlm, :digest_ie, :ntlm_wb, {:only => 1<<31, :any => ~0x10, :anysafe => ~0x11, :auto => 0x1f}]
324
+ option :easy, :tlsauth_type, :enum, 206, [:none, :srp]
325
+ option :easy, :tlsauth_username, :string, 204
326
+ option :easy, :tlsauth_password, :string, 205
327
+ option :easy, :proxyauth, :bitmask, 111, [:none, :basic, :digest, :gssnegotiate, :ntlm, :digest_ie, :ntlm_wb, {:only => 1<<31, :any => ~0x10, :anysafe => ~0x11, :auto => 0x1f}]
328
+ option :easy, :sasl_ir, :bool, 218
329
+ ## HTTP OPTIONS
330
+ option :easy, :autoreferer, :bool, 58
331
+ option :easy, :accept_encoding, :string, 102
332
+ option_alias :easy, :accept_encoding, :encoding
333
+ option :easy, :transfer_encoding, :bool, 207
334
+ option :easy, :followlocation, :bool, 52
335
+ option :easy, :unrestricted_auth, :bool, 105
336
+ option :easy, :maxredirs, :int, 68
337
+ option :easy, :postredir, :bitmask, 161, [:get_all, :post_301, :post_302, :post_303, {:post_all => [:post_301, :post_302, :post_303]}]
338
+ option_alias :easy, :postredir, :post301
339
+ option :easy, :put, :bool, 54
340
+ option :easy, :post, :bool, 47
341
+ option :easy, :postfields, :string, 15
342
+ option :easy, :postfieldsize, :int, 60
343
+ option :easy, :postfieldsize_large, :off_t, 120
344
+ option :easy, :copypostfields, :string_as_pointer, 165
345
+ option :easy, :httppost, :ffipointer, 24
346
+ option :easy, :referer, :string, 16
347
+ option :easy, :useragent, :string, 18
348
+ option :easy, :httpheader, :curl_slist, 23
349
+ option :easy, :http200aliases, :curl_slist, 104
350
+ option :easy, :cookie, :string, 22
351
+ option :easy, :cookiefile, :string, 31
352
+ option :easy, :cookiejar, :string, 82
353
+ option :easy, :cookiesession, :bool, 96
354
+ option :easy, :cookielist, :string, 135
355
+ option :easy, :httpget, :bool, 80
356
+ option :easy, :http_version, :enum, 84, [:none, :httpv1_0, :httpv1_1, :httpv2_0, :httpv2_tls, :httpv2_prior_knowledge]
357
+ option :easy, :ignore_content_length, :bool, 136
358
+ option :easy, :http_content_decoding, :bool, 158
359
+ option :easy, :http_transfer_decoding, :bool, 157
360
+ ## SMTP OPTIONS
361
+ option :easy, :mail_from, :string, 186
362
+ option :easy, :mail_rcpt, :curl_slist, 187
363
+ option :easy, :mail_auth, :string, 217
364
+ ## TFTP OPTIONS
365
+ option :easy, :tftp_blksize, :int, 178
366
+ ## FTP OPTIONS
367
+ option :easy, :ftpport, :string, 17
368
+ option :easy, :quote, :curl_slist, 28
369
+ option :easy, :postquote, :curl_slist, 39
370
+ option :easy, :prequote, :curl_slist, 93
371
+ option :easy, :dirlistonly, :bool, 48
372
+ option_alias :easy, :dirlistonly, :ftplistonly
373
+ option :easy, :append, :bool, 50
374
+ option_alias :easy, :append, :ftpappend
375
+ option :easy, :ftp_use_eprt, :bool, 106
376
+ option :easy, :ftp_use_epsv, :bool, 85
377
+ option :easy, :ftp_use_pret, :bool, 188
378
+ option :easy, :ftp_create_missing_dirs, :bool, 110
379
+ option :easy, :ftp_response_timeout, :int, 112
380
+ option_alias :easy, :ftp_response_timeout, :server_response_timeout
381
+ option :easy, :ftp_alternative_to_user, :string, 147
382
+ option :easy, :ftp_skip_pasv_ip, :bool, 137
383
+ option :easy, :ftpsslauth, :enum, 129, [:default, :ssl, :tls]
384
+ option :easy, :ftp_ssl_ccc, :enum, 154, [:none, :passive, :active]
385
+ option :easy, :ftp_account, :string, 134
386
+ option :easy, :ftp_filemethod, :enum, 138, [:default, :multicwd, :nocwd, :singlecwd]
387
+ ## RTSP OPTIONS
388
+ option :easy, :rtsp_request, :enum, 189, [:none, :options, :describe, :announce, :setup, :play, :pause, :teardown, :get_parameter, :set_parameter, :record, :receive]
389
+ option :easy, :rtsp_session_id, :string, 190
390
+ option :easy, :rtsp_stream_uri, :string, 191
391
+ option :easy, :rtsp_transport, :string, 192
392
+ option_alias :easy, :httpheader, :rtspheader
393
+ option :easy, :rtsp_client_cseq, :int, 193
394
+ option :easy, :rtsp_server_cseq, :int, 194
395
+ ## PROTOCOL OPTIONS
396
+ option :easy, :transfertext, :bool, 53
397
+ option :easy, :proxy_transfer_mode, :bool, 166
398
+ option :easy, :crlf, :bool, 27
399
+ option :easy, :range, :string, 7
400
+ option :easy, :resume_from, :int, 21
401
+ option :easy, :resume_from_large, :off_t, 116
402
+ option :easy, :customrequest, :string, 36
403
+ option :easy, :filetime, :bool, 69
404
+ option :easy, :nobody, :bool, 44
405
+ option :easy, :infilesize, :int, 14
406
+ option :easy, :infilesize_large, :off_t, 115
407
+ option :easy, :upload, :bool, 46
408
+ option :easy, :maxfilesize, :int, 114
409
+ option :easy, :maxfilesize_large, :off_t, 117
410
+ option :easy, :timecondition, :enum, 33, [:none, :ifmodsince, :ifunmodsince, :lastmod]
411
+ option :easy, :timevalue, :time, 34
412
+ ## CONNECTION OPTIONS
413
+ option :easy, :timeout, :int, 13
414
+ option :easy, :timeout_ms, :int, 155
415
+ option :easy, :low_speed_limit, :int, 19
416
+ option :easy, :low_speed_time, :int, 20
417
+ option :easy, :max_send_speed_large, :off_t, 145
418
+ option :easy, :max_recv_speed_large, :off_t, 146
419
+ option :easy, :maxconnects, :int, 71
420
+ option :easy, :fresh_connect, :bool, 74
421
+ option :easy, :forbid_reuse, :bool, 75
422
+ option :easy, :connecttimeout, :int, 78
423
+ option :easy, :connecttimeout_ms, :int, 156
424
+ option :easy, :ipresolve, :enum, 113, [:whatever, :v4, :v6]
425
+ option :easy, :connect_only, :bool, 141
426
+ option :easy, :use_ssl, :enum, 119, [:none, :try, :control, :all]
427
+ option_alias :easy, :use_ssl, :ftp_ssl
428
+ option :easy, :resolve, :curl_slist, 203
429
+ option :easy, :dns_servers, :string, 211
430
+ option :easy, :accepttimeout_ms, :int, 212
431
+ option :easy, :unix_socket_path, :string, 231
432
+ option :easy, :pipewait, :bool, 237
433
+ option_alias :easy, :unix_socket_path, :unix_socket
434
+ ## SSL and SECURITY OPTIONS
435
+ option :easy, :sslcert, :string, 25
436
+ option :easy, :sslcerttype, :string, 86
437
+ option :easy, :sslkey, :string, 87
438
+ option :easy, :sslkeytype, :string, 88
439
+ option :easy, :keypasswd, :string, 26
440
+ option_alias :easy, :keypasswd, :sslcertpasswd
441
+ option_alias :easy, :keypasswd, :sslkeypasswd
442
+ option :easy, :sslengine, :string, 89
443
+ option :easy, :sslengine_default, :none, 90
444
+ option :easy, :sslversion, :enum, 32, [:default, :tlsv1, :sslv2, :sslv3, :tlsv1_0, :tlsv1_1, :tlsv1_2, :tlsv1_3]
445
+ option :easy, :ssl_verifypeer, :bool, 64
446
+ option :easy, :cainfo, :string, 65
447
+ option :easy, :issuercert, :string, 170
448
+ option :easy, :capath, :string, 97
449
+ option :easy, :crlfile, :string, 169
450
+ option :easy, :ssl_verifyhost, :int, 81
451
+ option :easy, :certinfo, :bool, 172
452
+ option :easy, :random_file, :string, 76
453
+ option :easy, :egdsocket, :string, 77
454
+ option :easy, :ssl_cipher_list, :string, 83
455
+ option :easy, :ssl_sessionid_cache, :bool, 150
456
+ option :easy, :ssl_options, :bitmask, 216, [nil, :allow_beast]
457
+ option :easy, :krblevel, :string, 63
458
+ option_alias :easy, :krblevel, :krb4level
459
+ option :easy, :gssapi_delegation, :bitmask, 210, [:none, :policy_flag, :flag]
460
+ option :easy, :pinnedpublickey, :string, 230
461
+ option_alias :easy, :pinnedpublickey, :pinned_public_key
462
+ ## PROXY SSL OPTIONS
463
+ option :easy, :proxy_cainfo, :string, 246
464
+ option :easy, :proxy_capath, :string, 247
465
+ option :easy, :proxy_ssl_verifypeer, :bool, 248
466
+ option :easy, :proxy_ssl_verifyhost, :int, 249
467
+ option :easy, :proxy_sslversion, :enum, 250, [:default, :tlsv1, :sslv2, :sslv3, :tlsv1_0, :tlsv1_1, :tlsv1_2, :tlsv1_3]
468
+ option :easy, :proxy_tlsauth_username, :string, 251
469
+ option :easy, :proxy_tlsauth_password, :string, 252
470
+ option :easy, :proxy_tlsauth_type, :enum, 253, [:none, :srp]
471
+ option :easy, :proxy_sslcert, :string, 254
472
+ option :easy, :proxy_sslcerttype, :string, 255
473
+ option :easy, :proxy_sslkey, :string, 256
474
+ option :easy, :proxy_sslkeytype, :string, 257
475
+ option :easy, :proxy_keypasswd, :string, 258
476
+ option_alias :easy, :proxy_keypasswd, :proxy_sslcertpasswd
477
+ option_alias :easy, :proxy_keypasswd, :proxy_sslkeypasswd
478
+ option :easy, :proxy_ssl_cipher_list, :string, 259
479
+ option :easy, :proxy_crlfile, :string, 260
480
+ option :easy, :proxy_ssl_options, :bitmask, 261, [nil, :allow_beast]
481
+ option :easy, :pre_proxy, :string, 262
482
+ option :easy, :proxy_pinnedpublickey, :string, 263
483
+ option_alias :easy, :proxy_pinnedpublickey, :proxy_pinned_public_key
484
+ option :easy, :proxy_issuercert, :string, 296
485
+ ## SSH OPTIONS
486
+ option :easy, :ssh_auth_types, :bitmask, 151, [:none, :publickey, :password, :host, :keyboard, :agent, {:any => [:all], :default => [:any]}]
487
+ option :easy, :ssh_host_public_key_md5, :string, 162
488
+ option :easy, :ssh_public_keyfile, :string, 152
489
+ option :easy, :ssh_private_keyfile, :string, 153
490
+ option :easy, :ssh_knownhosts, :string, 183
491
+ option :easy, :ssh_keyfunction, :callback, 184
492
+ option :easy, :khstat, :enum, -1, [:fine_add_to_file, :fine, :reject, :defer] # Kludge to make this enum available... Access via CurL::EASY_OPTIONS[:khstat][:opt]
493
+ option :easy, :ssh_keydata, :cbdata, 185
494
+ ## OTHER OPTIONS
495
+ option :easy, :private, :cbdata, 103
496
+ option :easy, :share, :dontuse_object, 100
497
+ option :easy, :new_file_perms, :int, 159
498
+ option :easy, :new_directory_perms, :int, 160
499
+ ## TELNET OPTIONS
500
+ option :easy, :telnetoptions, :curl_slist, 70
501
+ end
502
+ end
503
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module Ethon
3
+ module Curl
4
+ callback :callback, [:pointer, :size_t, :size_t, :pointer], :size_t
5
+ callback :socket_callback, [:pointer, :int, :poll_action, :pointer, :pointer], :multi_code
6
+ callback :timer_callback, [:pointer, :long, :pointer], :multi_code
7
+ callback :debug_callback, [:pointer, :debug_info_type, :pointer, :size_t, :pointer], :int
8
+ callback :progress_callback, [:pointer, :long_long, :long_long, :long_long, :long_long], :int
9
+ ffi_lib_flags :now, :global
10
+ ffi_lib ['libcurl', 'libcurl.so.4']
11
+ end
12
+ end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+ module Ethon
3
+ class Easy
4
+
5
+ # This module contains all the logic around the callbacks,
6
+ # which are needed to interact with libcurl.
7
+ #
8
+ # @api private
9
+ module Callbacks
10
+
11
+ # :nodoc:
12
+ def self.included(base)
13
+ base.send(:attr_accessor, *[:response_body, :response_headers, :debug_info])
14
+ end
15
+
16
+ # Set writefunction and headerfunction callback.
17
+ # They are called by libcurl in order to provide the header and
18
+ # the body from the request.
19
+ #
20
+ # @example Set callbacks.
21
+ # easy.set_callbacks
22
+ def set_callbacks
23
+ Curl.set_option(:writefunction, body_write_callback, handle)
24
+ Curl.set_option(:headerfunction, header_write_callback, handle)
25
+ Curl.set_option(:debugfunction, debug_callback, handle)
26
+ @response_body = String.new
27
+ @response_headers = String.new
28
+ @headers_called = false
29
+ @debug_info = Ethon::Easy::DebugInfo.new
30
+ end
31
+
32
+ # Returns the body write callback.
33
+ #
34
+ # @example Return the callback.
35
+ # easy.body_write_callback
36
+ #
37
+ # @return [ Proc ] The callback.
38
+ def body_write_callback
39
+ @body_write_callback ||= proc do |stream, size, num, object|
40
+ headers
41
+ result = body(chunk = stream.read_string(size * num))
42
+ @response_body << chunk if result == :unyielded
43
+ result != :abort ? size * num : -1
44
+ end
45
+ end
46
+
47
+ # Returns the header write callback.
48
+ #
49
+ # @example Return the callback.
50
+ # easy.header_write_callback
51
+ #
52
+ # @return [ Proc ] The callback.
53
+ def header_write_callback
54
+ @header_write_callback ||= proc {|stream, size, num, object|
55
+ result = headers
56
+ @response_headers << stream.read_string(size * num)
57
+ result != :abort ? size * num : -1
58
+ }
59
+ end
60
+
61
+ # Returns the debug callback. This callback is currently used
62
+ # write the raw http request headers.
63
+ #
64
+ # @example Return the callback.
65
+ # easy.debug_callback
66
+ #
67
+ # @return [ Proc ] The callback.
68
+ def debug_callback
69
+ @debug_callback ||= proc {|handle, type, data, size, udata|
70
+ message = data.read_string(size)
71
+ @debug_info.add type, message
72
+ print message unless [:data_in, :data_out].include?(type)
73
+ 0
74
+ }
75
+ end
76
+
77
+ def set_progress_callback
78
+ if Curl.version_info[:version] >= "7.32.0"
79
+ Curl.set_option(:xferinfofunction, progress_callback, handle)
80
+ else
81
+ Curl.set_option(:progressfunction, progress_callback, handle)
82
+ end
83
+ end
84
+
85
+ # Returns the progress callback.
86
+ #
87
+ # @example Return the callback.
88
+ # easy.progress_callback
89
+ #
90
+ # @return [ Proc ] The callback.
91
+ def progress_callback
92
+ @progress_callback ||= proc { |_, dltotal, dlnow, ultotal, ulnow|
93
+ progress(dltotal, dlnow, ultotal, ulnow)
94
+ 0
95
+ }
96
+ end
97
+
98
+ # Set the read callback. This callback is used by libcurl to
99
+ # read data when performing a PUT request.
100
+ #
101
+ # @example Set the callback.
102
+ # easy.set_read_callback("a=1")
103
+ #
104
+ # @param [ String ] body The body.
105
+ def set_read_callback(body)
106
+ @request_body_read = 0
107
+ readfunction do |stream, size, num, object|
108
+ size = size * num
109
+ body_size = if body.respond_to?(:bytesize)
110
+ body.bytesize
111
+ elsif body.respond_to?(:size)
112
+ body.size
113
+ elsif body.is_a?(File)
114
+ File.size(body.path)
115
+ end
116
+
117
+ left = body_size - @request_body_read
118
+ size = left if size > left
119
+
120
+ if size > 0
121
+ chunk = if body.respond_to?(:byteslice)
122
+ body.byteslice(@request_body_read, size)
123
+ elsif body.respond_to?(:read)
124
+ body.read(size)
125
+ else
126
+ body[@request_body_read, size]
127
+ end
128
+
129
+ stream.write_string(
130
+ chunk, size
131
+ )
132
+ @request_body_read += size
133
+ end
134
+ size
135
+ end
136
+ end
137
+
138
+ # Returns the body read callback.
139
+ #
140
+ # @example Return the callback.
141
+ # easy.read_callback
142
+ #
143
+ # @return [ Proc ] The callback.
144
+ def read_callback
145
+ @read_callback
146
+ end
147
+ end
148
+ end
149
+ end