Module: Curl
- Defined in:
- lib/curl.rb,
lib/curl/easy.rb,
lib/curl/multi.rb,
lib/curl/download.rb,
ext/curb.c
Overview
Defined Under Namespace
Modules: Err
Classes: DownloadTargetExistsError, Easy, Multi, PostField, SafeDownloadOutput, SafetyConfig, Upload
Constant Summary
collapse
- DOWNLOAD_OPTION_KEYS =
[:download_dir, :overwrite].freeze
- CURB_VERSION =
rb_str_new2(CURB_VERSION)
- VERSION =
curlver
- CURL_VERSION =
curlver
- VERNUM =
curlvernum
- CURL_VERNUM =
curlvernum
- LONG_VERSION =
curllongver
- CURL_LONG_VERSION =
curllongver
- CURLINFO_TEXT =
Passed to on_debug handler to indicate that the data is informational text.
LONG2NUM(CURLINFO_TEXT)
LONG2NUM(CURLINFO_HEADER_IN)
LONG2NUM(CURLINFO_HEADER_OUT)
- CURLINFO_DATA_IN =
Passed to on_debug handler to indicate that the data is protocol data received from the peer.
LONG2NUM(CURLINFO_DATA_IN)
- CURLINFO_DATA_OUT =
Passed to on_debug handler to indicate that the data is protocol data sent to the peer.
LONG2NUM(CURLINFO_DATA_OUT)
- CURL_MULTICWD =
LONG2NUM(CURLFTPMETHOD_MULTICWD)
- CURL_NOCWD =
LONG2NUM(CURLFTPMETHOD_NOCWD)
- CURL_SINGLECWD =
LONG2NUM(CURLFTPMETHOD_SINGLECWD)
- CURLPROXY_HTTP =
LONG2NUM(-1)
- CURL_SSLVERSION_DEFAULT =
LONG2NUM(-1)
- CURL_SSLVERSION_MAX_DEFAULT =
LONG2NUM(CURL_SSLVERSION_MAX_DEFAULT)
- CURL_SSLVERSION_TLSv1 =
LONG2NUM(-1)
- CURL_SSLVERSION_SSLv2 =
LONG2NUM(-1)
- CURL_SSLVERSION_SSLv3 =
LONG2NUM(-1)
- CURL_SSLVERSION_TLSv1_0 =
LONG2NUM(-1)
- CURL_SSLVERSION_MAX_TLSv1_0 =
LONG2NUM(-1)
- CURL_SSLVERSION_TLSv1_1 =
LONG2NUM(-1)
- CURL_SSLVERSION_MAX_TLSv1_1 =
LONG2NUM(-1)
- CURL_SSLVERSION_TLSv1_2 =
LONG2NUM(-1)
- CURL_SSLVERSION_MAX_TLSv1_2 =
LONG2NUM(-1)
- CURL_SSLVERSION_TLSv1_3 =
LONG2NUM(-1)
- CURL_SSLVERSION_MAX_TLSv1_3 =
LONG2NUM(-1)
- CURL_USESSL_CONTROL =
LONG2NUM(-1)
- CURL_USESSL_NONE =
LONG2NUM(-1)
- CURL_USESSL_TRY =
LONG2NUM(-1)
- CURL_USESSL_ALL =
LONG2NUM(-1)
- CURLPROXY_SOCKS4 =
LONG2NUM(-2)
- CURLPROXY_SOCKS4A =
LONG2NUM(-2)
- CURLPROXY_SOCKS5 =
LONG2NUM(-2)
- CURLPROXY_SOCKS5_HOSTNAME =
LONG2NUM(-2)
- CURLAUTH_BASIC =
LONG2NUM(0)
- CURLAUTH_DIGEST =
LONG2NUM(0)
- CURLAUTH_GSSNEGOTIATE =
LONG2NUM(0)
- CURLAUTH_NTLM =
LONG2NUM(0)
- CURLAUTH_ANYSAFE =
LONG2NUM(0)
- CURLAUTH_ANY =
LONG2NUM(0)
- PIPE_NOTHING =
LONG2NUM(CURLPIPE_NOTHING)
- PIPE_HTTP1 =
LONG2NUM(CURLPIPE_HTTP1)
- PIPE_MULTIPLEX =
LONG2NUM(CURLPIPE_MULTIPLEX)
- HTTP_2_0 =
LONG2NUM(CURL_HTTP_VERSION_2_0)
- HTTP_2TLS =
LONG2NUM(CURL_HTTP_VERSION_2TLS)
- HTTP_2_PRIOR_KNOWLEDGE =
LONG2NUM(CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE)
- HTTP_1_1 =
LONG2NUM(CURL_HTTP_VERSION_1_1)
- HTTP_1_0 =
LONG2NUM(CURL_HTTP_VERSION_1_0)
- HTTP_NONE =
LONG2NUM(CURL_HTTP_VERSION_NONE)
Class Method Summary
collapse
-
.asyncdns? ⇒ Boolean
Returns true if the installed libcurl was built with support for asynchronous name lookups, which allows more exact timeouts (even on Windows) and less blocking when using the multi interface.
-
.block_scheduler_waiter(waiter) ⇒ Object
-
.complete_scheduler_waiter(waiter) ⇒ Object
-
.conv? ⇒ Boolean
Returns true if the installed libcurl was built with support for character conversions.
-
.debug? ⇒ Boolean
Returns true if the installed libcurl was built with extra debug capabilities built-in.
-
.deferred_exception_source_id(state) ⇒ Object
-
.delete(url, params = {}, &block) ⇒ Object
-
.download_filename_from_url(url) ⇒ Object
-
.download_options_hash?(value) ⇒ Boolean
-
.drain_scheduler_pending(state) ⇒ Object
-
.ensure_scheduler_driver(state) ⇒ Object
-
.fail_scheduler_waiter(waiter, error) ⇒ Object
-
.get(url, params = {}, &block) ⇒ Object
-
.gssnegotiate? ⇒ Boolean
Returns true if the installed libcurl supports HTTP GSS-Negotiate.
-
.head(url, params = {}, &block) ⇒ Object
-
.http(verb, url, post_body = nil, put_data = nil) {|handle| ... } ⇒ Object
-
.http2? ⇒ Boolean
Returns true if the installed libcurl was built with support for HTTP2.
-
.idn? ⇒ Boolean
Returns true if the installed libcurl was built with support for IDNA, domain names with international letters.
-
.ipv6? ⇒ Boolean
Returns true if the installed libcurl supports IPv6.
-
.kerberos4? ⇒ Boolean
Returns true if the installed libcurl supports Kerberos4 authentication with FTP connections.
-
.largefile? ⇒ Boolean
Returns true if the installed libcurl was built with support for large files.
-
.libz? ⇒ Boolean
Returns true if the installed libcurl supports HTTP deflate using libz.
-
.normalize_download_arguments(filename, options) ⇒ Object
-
.ntlm? ⇒ Boolean
Returns true if the installed libcurl supports HTTP NTLM.
-
.open_safe_download_output(path, overwrite: false) ⇒ Object
-
.options(url, params = {}, &block) ⇒ Object
-
.parse_download_options(options) ⇒ Object
-
.patch(url, params = {}, &block) ⇒ Object
-
.perform_with_scheduler(easy) ⇒ Object
-
.post(url, params = {}, &block) ⇒ Object
-
.postalize(params = {}) ⇒ Object
-
.prepare_download_output(url, filename = nil, options = {}) ⇒ Object
-
.put(url, params = {}, &block) ⇒ Object
-
.release_scheduler_error(state, error) ⇒ Object
-
.release_scheduler_waiters(state) ⇒ Object
-
.reset ⇒ Object
-
.resolve_download_output(url, filename = nil, options = {}) ⇒ Object
-
.safe! {|config| ... } ⇒ Object
-
.safe_delete(url, params = {}, options = {}, &block) ⇒ Object
-
.safe_download_path(url, destination_dir = Dir.pwd, filename: nil) ⇒ Object
-
.safe_get(url, params = {}, options = {}, &block) ⇒ Object
-
.safe_head(url, params = {}, options = {}, &block) ⇒ Object
-
.safe_http(verb, url, post_body = nil, put_data = nil, options = {}, &block) ⇒ Object
-
.safe_http_option_hash?(value) ⇒ Boolean
-
.safe_http_option_keys ⇒ Object
-
.safe_http_options(options) ⇒ Object
-
.safe_options(url, params = {}, options = {}, &block) ⇒ Object
-
.safe_patch(url, params = {}, options = {}, &block) ⇒ Object
-
.safe_post(url, params = {}, options = {}, &block) ⇒ Object
-
.safe_put(url, params = {}, options = {}, &block) ⇒ Object
-
.scheduler_active? ⇒ Boolean
-
.scheduler_state ⇒ Object
-
.scheduler_waiter_blocking_supported? ⇒ Boolean
-
.scheduler_yield ⇒ Object
-
.split_safe_http_params_options(params, options) ⇒ Object
-
.spnego? ⇒ Boolean
Returns true if the installed libcurl was built with support for SPNEGO authentication (Simple and Protected GSS-API Negotiation Mechanism, defined in RFC 2478).
-
.ssl? ⇒ Boolean
Returns true if the installed libcurl supports SSL connections.
-
.sspi? ⇒ Boolean
Returns true if the installed libcurl was built with support for SSPI.
-
.urlalize(url, params = {}) ⇒ Object
-
.validate_download_filename!(filename) ⇒ Object
-
.wake_scheduler_waiter(waiter) ⇒ Object
Class Method Details
.asyncdns? ⇒ Boolean
Returns true if the installed libcurl was built with support for asynchronous name lookups, which allows more exact timeouts (even on Windows) and less blocking when using the multi interface. For libcurl versions < 7.10.7, always returns false.
128
129
130
131
132
133
134
135
|
# File 'ext/curb.c', line 128
static VALUE ruby_curl_asyncdns_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_ASYNCHDNS
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_ASYNCHDNS) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.block_scheduler_waiter(waiter) ⇒ Object
458
459
460
461
462
463
464
465
466
467
468
469
470
471
|
# File 'lib/curl.rb', line 458
def self.block_scheduler_waiter(waiter)
unless scheduler_waiter_blocking_supported?
sleep 0
return
end
waiter[:fiber] = Fiber.current
waiter[:scheduler] ||= Fiber.scheduler
return if waiter[:done] || waiter[:error]
waiter[:scheduler].block(waiter, nil)
ensure
waiter[:fiber] = nil if waiter[:fiber].equal?(Fiber.current)
end
|
.complete_scheduler_waiter(waiter) ⇒ Object
433
434
435
436
437
438
|
# File 'lib/curl.rb', line 433
def self.complete_scheduler_waiter(waiter)
return if waiter[:done]
waiter[:done] = true
wake_scheduler_waiter(waiter)
end
|
.conv? ⇒ Boolean
Returns true if the installed libcurl was built with support for character conversions. For libcurl versions < 7.15.4, always returns false.
215
216
217
218
219
220
221
222
|
# File 'ext/curb.c', line 215
static VALUE ruby_curl_conv_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_CONV
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_CONV) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.debug? ⇒ Boolean
Returns true if the installed libcurl was built with extra debug capabilities built-in. For libcurl versions < 7.10.6, always returns false.
110
111
112
113
114
115
116
117
|
# File 'ext/curb.c', line 110
static VALUE ruby_curl_debug_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_DEBUG
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_DEBUG) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.deferred_exception_source_id(state) ⇒ Object
414
415
416
417
418
|
# File 'lib/curl.rb', line 414
def self.deferred_exception_source_id(state)
return unless state[:multi].instance_variable_defined?(:@__curb_deferred_exception_source_id)
state[:multi].instance_variable_get(:@__curb_deferred_exception_source_id)
end
|
.delete(url, params = {}, &block) ⇒ Object
649
650
651
|
# File 'lib/curl.rb', line 649
def self.delete(url, params={}, &block)
http :DELETE, url, postalize(params), nil, &block
end
|
.download_filename_from_url(url) ⇒ Object
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/curl/download.rb', line 62
def download_filename_from_url(url)
path = begin
URI.parse(url.to_s).path
rescue URI::InvalidURIError
url.to_s.split(/\?/, 2).first
end
basename = File.basename(path.to_s)
validate_download_filename!(basename)
end
|
.download_options_hash?(value) ⇒ Boolean
11
12
13
|
# File 'lib/curl/download.rb', line 11
def download_options_hash?(value)
value.is_a?(Hash) && value.keys.all? { |key| DOWNLOAD_OPTION_KEYS.include?(key) }
end
|
.drain_scheduler_pending(state) ⇒ Object
590
591
592
593
594
595
596
597
598
599
600
601
602
|
# File 'lib/curl.rb', line 590
def self.drain_scheduler_pending(state)
pending = state[:pending]
until pending.empty?
easy = pending.first
break if state[:multi].instance_variable_defined?(:@__curb_deferred_exception)
state[:multi].add(easy)
break unless state[:multi].requests.key?(easy.object_id)
pending.shift
end
end
|
.ensure_scheduler_driver(state) ⇒ Object
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
|
# File 'lib/curl.rb', line 542
def self.ensure_scheduler_driver(state)
return if state[:driver_running]
state[:driver_running] = true
state[:error] = nil
runner = proc do
begin
pending_count = -1
until pending_count == state[:pending].size
pending_count = state[:pending].size
scheduler_yield
end
loop do
drain_scheduler_pending(state)
break if state[:multi].idle?
begin
state[:multi].perform do
drain_scheduler_pending(state)
release_scheduler_waiters(state)
scheduler_yield
end
ensure
release_scheduler_waiters(state)
end
end
rescue => e
release_scheduler_waiters(state)
release_scheduler_error(state, e)
ensure
state[:driver_running] = false
ensure_scheduler_driver(state) if state[:error].nil? && !state[:pending].empty?
end
end
if Fiber.respond_to?(:schedule)
Fiber.schedule(&runner)
else
Fiber.new(blocking: false, &runner).resume
end
end
|
.fail_scheduler_waiter(waiter, error) ⇒ Object
440
441
442
443
444
445
|
# File 'lib/curl.rb', line 440
def self.fail_scheduler_waiter(waiter, error)
return if waiter[:error]
waiter[:error] = error
wake_scheduler_waiter(waiter)
end
|
.get(url, params = {}, &block) ⇒ Object
624
625
626
|
# File 'lib/curl.rb', line 624
def self.get(url, params={}, &block)
http :GET, urlalize(url, params), nil, nil, &block
end
|
.gssnegotiate? ⇒ Boolean
Returns true if the installed libcurl supports HTTP GSS-Negotiate. For libcurl versions < 7.10.6, always returns false.
93
94
95
96
97
98
99
100
|
# File 'ext/curb.c', line 93
static VALUE ruby_curl_gssnegotiate_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_GSSNEGOTIATE
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_GSSNEGOTIATE) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.head(url, params = {}, &block) ⇒ Object
665
666
667
|
# File 'lib/curl.rb', line 665
def self.head(url, params={}, &block)
http :HEAD, urlalize(url, params), nil, nil, &block
end
|
.http(verb, url, post_body = nil, put_data = nil) {|handle| ... } ⇒ Object
604
605
606
607
608
609
610
611
612
|
# File 'lib/curl.rb', line 604
def self.http(verb, url, post_body=nil, put_data=nil, &block)
handle = Curl::Easy.new
handle.url = url
handle.post_body = post_body if post_body
handle.put_data = put_data if put_data
yield handle if block_given?
handle.http(verb)
handle
end
|
.http2? ⇒ Boolean
Returns true if the installed libcurl was built with support for HTTP2. For libcurl versions < 7.33.0, always returns false.
231
232
233
234
235
236
237
238
|
# File 'ext/curb.c', line 231
static VALUE ruby_curl_http2_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_HTTP2
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_HTTP2) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.idn? ⇒ Boolean
Returns true if the installed libcurl was built with support for IDNA, domain names with international letters. For libcurl versions < 7.12.0, always returns false.
180
181
182
183
184
185
186
187
|
# File 'ext/curb.c', line 180
static VALUE ruby_curl_idn_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_IDN
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_IDN) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.ipv6? ⇒ Boolean
Returns true if the installed libcurl supports IPv6.
21
22
23
24
|
# File 'ext/curb.c', line 21
static VALUE ruby_curl_ipv6_q(VALUE mod) {
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_IPV6) ? Qtrue : Qfalse);
}
|
.kerberos4? ⇒ Boolean
Returns true if the installed libcurl supports Kerberos4 authentication with FTP connections.
33
34
35
36
|
# File 'ext/curb.c', line 33
static VALUE ruby_curl_kerberos4_q(VALUE mod) {
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_KERBEROS4) ? Qtrue : Qfalse);
}
|
.largefile? ⇒ Boolean
Returns true if the installed libcurl was built with support for large files. For libcurl versions < 7.11.1, always returns false.
163
164
165
166
167
168
169
170
|
# File 'ext/curb.c', line 163
static VALUE ruby_curl_largefile_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_LARGEFILE
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_LARGEFILE) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.libz? ⇒ Boolean
Returns true if the installed libcurl supports HTTP deflate using libz. For libcurl versions < 7.10, always returns false.
61
62
63
64
65
66
67
68
|
# File 'ext/curb.c', line 61
static VALUE ruby_curl_libz_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_LIBZ
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_LIBZ) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.normalize_download_arguments(filename, options) ⇒ Object
15
16
17
18
19
20
21
22
|
# File 'lib/curl/download.rb', line 15
def normalize_download_arguments(filename, options)
if download_options_hash?(filename) && options.empty?
options = filename
filename = nil
end
[filename, options || {}]
end
|
.ntlm? ⇒ Boolean
Returns true if the installed libcurl supports HTTP NTLM. For libcurl versions < 7.10.6, always returns false.
77
78
79
80
81
82
83
84
|
# File 'ext/curb.c', line 77
static VALUE ruby_curl_ntlm_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_NTLM
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_NTLM) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.open_safe_download_output(path, overwrite: false) ⇒ Object
98
99
100
|
# File 'lib/curl/download.rb', line 98
def open_safe_download_output(path, overwrite: false)
SafeDownloadOutput.new(path, overwrite: overwrite)
end
|
.options(url, params = {}, &block) ⇒ Object
674
675
676
|
# File 'lib/curl.rb', line 674
def self.options(url, params={}, &block)
http :OPTIONS, urlalize(url, params), nil, nil, &block
end
|
.parse_download_options(options) ⇒ Object
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/curl/download.rb', line 24
def parse_download_options(options)
raise ArgumentError, "download options must be a Hash" unless options.is_a?(Hash)
options = options.dup
download_dir = options.delete(:download_dir)
overwrite = options.key?(:overwrite) ? !!options.delete(:overwrite) : false
raise ArgumentError, "unsupported download option(s): #{options.keys.join(', ')}" unless options.empty?
[download_dir, overwrite]
end
|
.patch(url, params = {}, &block) ⇒ Object
657
658
659
|
# File 'lib/curl.rb', line 657
def self.patch(url, params={}, &block)
http :PATCH, url, postalize(params), nil, &block
end
|
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
|
# File 'lib/curl.rb', line 493
def self.perform_with_scheduler(easy)
state = scheduler_state
waiter = {completed: false, done: false, error: nil, fiber: nil, scheduler: Fiber.scheduler}
state[:waiters][easy.object_id] = waiter
previous_complete = easy.on_complete do |completed_easy|
previous_complete.call(completed_easy) if previous_complete
waiter[:completed] = true
end
state[:pending] << easy
ensure_scheduler_driver(state)
until waiter[:done]
raise waiter[:error] if waiter[:error]
raise state[:error] if state[:error]
block_scheduler_waiter(waiter)
end
while state[:driver_running] && state[:pending].empty? &&
state[:waiters].length == 1 && state[:waiters].key?(easy.object_id)
scheduler_yield
end
true
ensure
state[:waiters].delete(easy.object_id) if defined?(state) && state[:waiters]
if defined?(previous_complete)
if previous_complete
easy.on_complete(&previous_complete)
else
easy.on_complete
end
end
end
|
.post(url, params = {}, &block) ⇒ Object
633
634
635
|
# File 'lib/curl.rb', line 633
def self.post(url, params={}, &block)
http :POST, url, postalize(params), nil, &block
end
|
.postalize(params = {}) ⇒ Object
693
694
695
|
# File 'lib/curl.rb', line 693
def self.postalize(params={})
params.respond_to?(:map) ? URI.encode_www_form(params) : (params.respond_to?(:to_s) ? params.to_s : params)
end
|
.prepare_download_output(url, filename = nil, options = {}) ⇒ Object
55
56
57
58
59
60
|
# File 'lib/curl/download.rb', line 55
def prepare_download_output(url, filename = nil, options = {})
path, io, safe_output, overwrite = resolve_download_output(url, filename, options)
return [path, io, safe_output] unless safe_output
[path, open_safe_download_output(path, overwrite: overwrite), true]
end
|
.put(url, params = {}, &block) ⇒ Object
641
642
643
|
# File 'lib/curl.rb', line 641
def self.put(url, params={}, &block)
http :PUT, url, nil, postalize(params), &block
end
|
.release_scheduler_error(state, error) ⇒ Object
447
448
449
450
451
452
453
454
455
456
|
# File 'lib/curl.rb', line 447
def self.release_scheduler_error(state, error)
source_waiter = state[:waiters][deferred_exception_source_id(state)]
if source_waiter
fail_scheduler_waiter(source_waiter, error)
else
state[:error] = error
state[:waiters].each_value { |waiter| wake_scheduler_waiter(waiter) }
end
end
|
.release_scheduler_waiters(state) ⇒ Object
483
484
485
486
487
488
489
490
491
|
# File 'lib/curl.rb', line 483
def self.release_scheduler_waiters(state)
source_id = deferred_exception_source_id(state)
state[:waiters].each do |easy_id, waiter|
next if source_id == easy_id
complete_scheduler_waiter(waiter) if waiter[:completed]
end
end
|
.reset ⇒ Object
724
725
726
|
# File 'lib/curl.rb', line 724
def self.reset
Thread.current[:curb_curl] = Curl::Easy.new
end
|
.resolve_download_output(url, filename = nil, options = {}) ⇒ Object
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# File 'lib/curl/download.rb', line 35
def resolve_download_output(url, filename = nil, options = {})
filename, options = normalize_download_arguments(filename, options)
download_dir, overwrite = parse_download_options(options)
if filename.is_a?(IO)
filename.binmode if filename.respond_to?(:binmode)
return [nil, filename, false, overwrite]
end
path = if download_dir
safe_download_path(url, download_dir, filename: filename)
elsif filename.nil?
safe_download_path(url)
else
filename.to_s
end
[path, nil, true, overwrite]
end
|
.safe! {|config| ... } ⇒ Object
176
177
178
179
180
181
|
# File 'lib/curl.rb', line 176
def self.safe!
config = SafetyConfig.new
yield config if block_given?
@safety_config = config
bump_safety_generation!
end
|
.safe_delete(url, params = {}, options = {}, &block) ⇒ Object
653
654
655
|
# File 'lib/curl.rb', line 653
def self.safe_delete(url, params={}, options={}, &block)
safe_http :DELETE, url, postalize(params), nil, options, &block
end
|
.safe_download_path(url, destination_dir = Dir.pwd, filename: nil) ⇒ Object
73
74
75
76
77
78
|
# File 'lib/curl/download.rb', line 73
def safe_download_path(url, destination_dir = Dir.pwd, filename: nil)
dir = File.expand_path(destination_dir.to_s)
raise ArgumentError, "download destination directory does not exist: #{destination_dir}" unless File.directory?(dir)
File.join(dir, filename.nil? ? download_filename_from_url(url) : validate_download_filename!(filename))
end
|
.safe_get(url, params = {}, options = {}, &block) ⇒ Object
628
629
630
631
|
# File 'lib/curl.rb', line 628
def self.safe_get(url, params={}, options={}, &block)
params, options = split_safe_http_params_options(params, options)
safe_http :GET, urlalize(url, params), nil, nil, options, &block
end
|
.safe_head(url, params = {}, options = {}, &block) ⇒ Object
669
670
671
672
|
# File 'lib/curl.rb', line 669
def self.safe_head(url, params={}, options={}, &block)
params, options = split_safe_http_params_options(params, options)
safe_http :HEAD, urlalize(url, params), nil, nil, options, &block
end
|
.safe_http(verb, url, post_body = nil, put_data = nil, options = {}, &block) ⇒ Object
614
615
616
617
618
619
620
621
622
|
# File 'lib/curl.rb', line 614
def self.safe_http(verb, url, post_body=nil, put_data=nil, options={}, &block)
options = safe_http_options(options)
http(verb, url, post_body, put_data) do |handle|
yield handle if block
handle.safe_http!
handle.max_body_bytes = options[:max_body_bytes] if options.key?(:max_body_bytes)
end
end
|
.safe_http_option_hash?(value) ⇒ Boolean
716
717
718
|
# File 'lib/curl.rb', line 716
def self.safe_http_option_hash?(value)
value.is_a?(Hash) && !value.empty? && (value.keys - safe_http_option_keys).empty?
end
|
.safe_http_option_keys ⇒ Object
720
721
722
|
# File 'lib/curl.rb', line 720
def self.safe_http_option_keys
[:max_body_bytes]
end
|
.safe_http_options(options) ⇒ Object
697
698
699
700
701
702
703
704
705
706
|
# File 'lib/curl.rb', line 697
def self.safe_http_options(options)
options ||= {}
raise ArgumentError, "safe HTTP options must be a Hash" unless options.is_a?(Hash)
options = options.dup
unsupported = options.keys - safe_http_option_keys
raise ArgumentError, "unsupported safe HTTP option(s): #{unsupported.join(', ')}" unless unsupported.empty?
options
end
|
.safe_options(url, params = {}, options = {}, &block) ⇒ Object
678
679
680
681
|
# File 'lib/curl.rb', line 678
def self.safe_options(url, params={}, options={}, &block)
params, options = split_safe_http_params_options(params, options)
safe_http :OPTIONS, urlalize(url, params), nil, nil, options, &block
end
|
.safe_patch(url, params = {}, options = {}, &block) ⇒ Object
661
662
663
|
# File 'lib/curl.rb', line 661
def self.safe_patch(url, params={}, options={}, &block)
safe_http :PATCH, url, postalize(params), nil, options, &block
end
|
.safe_post(url, params = {}, options = {}, &block) ⇒ Object
637
638
639
|
# File 'lib/curl.rb', line 637
def self.safe_post(url, params={}, options={}, &block)
safe_http :POST, url, postalize(params), nil, options, &block
end
|
.safe_put(url, params = {}, options = {}, &block) ⇒ Object
645
646
647
|
# File 'lib/curl.rb', line 645
def self.safe_put(url, params={}, options={}, &block)
safe_http :PUT, url, nil, postalize(params), options, &block
end
|
.scheduler_active? ⇒ Boolean
410
411
412
|
# File 'lib/curl.rb', line 410
def self.scheduler_active?
Fiber.respond_to?(:scheduler) && !Fiber.scheduler.nil?
end
|
.scheduler_state ⇒ Object
528
529
530
531
532
533
534
535
536
537
538
539
540
|
# File 'lib/curl.rb', line 528
def self.scheduler_state
Thread.current.thread_variable_get(:curb_scheduler_state) || begin
state = {
multi: Curl::Multi.new,
pending: [],
driver_running: false,
error: nil,
waiters: {},
}
Thread.current.thread_variable_set(:curb_scheduler_state, state)
state
end
end
|
.scheduler_waiter_blocking_supported? ⇒ Boolean
420
421
422
423
|
# File 'lib/curl.rb', line 420
def self.scheduler_waiter_blocking_supported?
scheduler = Fiber.scheduler
scheduler && scheduler.respond_to?(:block) && scheduler.respond_to?(:unblock)
end
|
.scheduler_yield ⇒ Object
473
474
475
476
477
478
479
480
481
|
# File 'lib/curl.rb', line 473
def self.scheduler_yield
scheduler = Fiber.scheduler
if scheduler&.respond_to?(:kernel_sleep)
scheduler.kernel_sleep(0)
else
sleep 0
end
end
|
.split_safe_http_params_options(params, options) ⇒ Object
708
709
710
711
712
713
714
|
# File 'lib/curl.rb', line 708
def self.split_safe_http_params_options(params, options)
if options == {} && safe_http_option_hash?(params)
[{}, params]
else
[params, options]
end
end
|
.spnego? ⇒ Boolean
Returns true if the installed libcurl was built with support for SPNEGO authentication (Simple and Protected GSS-API Negotiation Mechanism, defined in RFC 2478). For libcurl versions < 7.10.8, always returns false.
145
146
147
148
149
150
151
152
153
154
|
# File 'ext/curb.c', line 145
static VALUE ruby_curl_spnego_q(VALUE mod) {
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
#ifdef HAVE_CURL_VERSION_SPNEGO
if (ver->features & CURL_VERSION_SPNEGO) return Qtrue;
#endif
#ifdef HAVE_CURL_VERSION_GSSNEGOTIATE
if (ver->features & CURL_VERSION_GSSNEGOTIATE) return Qtrue;
#endif
return Qfalse;
}
|
.ssl? ⇒ Boolean
Returns true if the installed libcurl supports SSL connections. For libcurl versions < 7.10, always returns false.
45
46
47
48
49
50
51
52
|
# File 'ext/curb.c', line 45
static VALUE ruby_curl_ssl_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_SSL
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_SSL) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.sspi? ⇒ Boolean
Returns true if the installed libcurl was built with support for SSPI. This is only available on Windows and makes libcurl use Windows-provided functions for NTLM authentication. It also allows libcurl to use the current user and the current user’s password without the app having to pass them on. For libcurl versions < 7.13.2, always returns false.
199
200
201
202
203
204
205
206
|
# File 'ext/curb.c', line 199
static VALUE ruby_curl_sspi_q(VALUE mod) {
#ifdef HAVE_CURL_VERSION_SSPI
curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
return((ver->features & CURL_VERSION_SSPI) ? Qtrue : Qfalse);
#else
return Qfalse;
#endif
}
|
.urlalize(url, params = {}) ⇒ Object
683
684
685
686
687
688
689
690
691
|
# File 'lib/curl.rb', line 683
def self.urlalize(url, params={})
uri = URI(url)
return uri.to_s if (params || {}).empty?
params_query = URI.encode_www_form(params || {})
uri.query = [uri.query.to_s, params_query].reject(&:empty?).join('&')
uri.to_s
end
|
.validate_download_filename!(filename) ⇒ Object
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/curl/download.rb', line 80
def validate_download_filename!(filename)
filename = filename.to_s
invalid = filename.empty? ||
filename == '.' ||
filename == '..' ||
filename == File::SEPARATOR ||
filename.start_with?('.') ||
filename.include?("\0") ||
filename.include?(File::SEPARATOR) ||
filename.include?('\\') ||
filename.match?(/\A[A-Za-z]:/) ||
(File::ALT_SEPARATOR && filename.include?(File::ALT_SEPARATOR))
raise ArgumentError, "unsafe download filename derived from URL: #{filename.inspect}" if invalid
filename
end
|
.wake_scheduler_waiter(waiter) ⇒ Object
425
426
427
428
429
430
431
|
# File 'lib/curl.rb', line 425
def self.wake_scheduler_waiter(waiter)
fiber = waiter[:fiber]
scheduler = waiter[:scheduler]
return unless fiber&.alive? && scheduler&.respond_to?(:unblock)
scheduler.unblock(waiter, fiber)
end
|