taf2-curb 0.4.2.0 → 0.4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +0 -6
- data/ext/curb.c +1 -1
- data/ext/curb.h +3 -3
- data/ext/curb_easy.c +103 -0
- data/ext/curb_easy.h +4 -0
- data/ext/curb_multi.c +1 -1
- data/lib/curb.rb +44 -6
- data/tests/helper.rb +4 -1
- data/tests/tc_curl_download.rb +8 -3
- data/tests/tc_curl_easy.rb +40 -0
- data/tests/tc_curl_multi.rb +18 -1
- metadata +2 -2
data/Rakefile
CHANGED
@@ -4,12 +4,6 @@ require 'rake/clean'
|
|
4
4
|
require 'rake/testtask'
|
5
5
|
require 'rake/rdoctask'
|
6
6
|
|
7
|
-
#begin
|
8
|
-
# require 'rake/gempackagetask'
|
9
|
-
#rescue LoadError
|
10
|
-
# $stderr.puts("Rubygems support disabled")
|
11
|
-
#end
|
12
|
-
|
13
7
|
CLEAN.include '**/*.o'
|
14
8
|
CLEAN.include "**/*.#{Config::MAKEFILE_CONFIG['DLEXT']}"
|
15
9
|
CLOBBER.include 'doc'
|
data/ext/curb.c
CHANGED
@@ -278,7 +278,7 @@ void Init_curb_core() {
|
|
278
278
|
#ifdef HAVE_CURLAUTH_BASIC
|
279
279
|
rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(CURLAUTH_BASIC));
|
280
280
|
#else
|
281
|
-
rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(0);
|
281
|
+
rb_define_const(mCurl, "CURLAUTH_BASIC", INT2FIX(0));
|
282
282
|
#endif
|
283
283
|
|
284
284
|
/* When passed to Curl::Easy#http_auth_types or Curl::Easy#proxy_auth_types, directs libcurl to use Digest authentication. */
|
data/ext/curb.h
CHANGED
@@ -20,11 +20,11 @@
|
|
20
20
|
#include "curb_macros.h"
|
21
21
|
|
22
22
|
// These should be managed from the Rake 'release' task.
|
23
|
-
#define CURB_VERSION "0.4.
|
24
|
-
#define CURB_VER_NUM
|
23
|
+
#define CURB_VERSION "0.4.3.0"
|
24
|
+
#define CURB_VER_NUM 430
|
25
25
|
#define CURB_VER_MAJ 0
|
26
26
|
#define CURB_VER_MIN 4
|
27
|
-
#define CURB_VER_MIC
|
27
|
+
#define CURB_VER_MIC 3
|
28
28
|
#define CURB_VER_PATCH 0
|
29
29
|
|
30
30
|
|
data/ext/curb_easy.c
CHANGED
@@ -170,7 +170,11 @@ void curl_easy_mark(ruby_curl_easy *rbce) {
|
|
170
170
|
rb_gc_mark(rbce->cookiefile);
|
171
171
|
rb_gc_mark(rbce->cookiejar);
|
172
172
|
rb_gc_mark(rbce->cert);
|
173
|
+
rb_gc_mark(rbce->cacert);
|
174
|
+
rb_gc_mark(rbce->certpassword);
|
175
|
+
rb_gc_mark(rbce->certtype);
|
173
176
|
rb_gc_mark(rbce->encoding);
|
177
|
+
rb_gc_mark(rbce->useragent);
|
174
178
|
rb_gc_mark(rbce->success_proc);
|
175
179
|
rb_gc_mark(rbce->failure_proc);
|
176
180
|
rb_gc_mark(rbce->complete_proc);
|
@@ -238,7 +242,11 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
|
|
238
242
|
rbce->cookiefile = Qnil;
|
239
243
|
rbce->cookiejar = Qnil;
|
240
244
|
rbce->cert = Qnil;
|
245
|
+
rbce->cacert = Qnil;
|
246
|
+
rbce->certpassword = Qnil;
|
247
|
+
rbce->certtype = rb_str_new2("PEM");
|
241
248
|
rbce->encoding = Qnil;
|
249
|
+
rbce->useragent = Qnil;
|
242
250
|
rbce->success_proc = Qnil;
|
243
251
|
rbce->failure_proc = Qnil;
|
244
252
|
rbce->complete_proc = Qnil;
|
@@ -574,6 +582,60 @@ static VALUE ruby_curl_easy_cert_get(VALUE self) {
|
|
574
582
|
CURB_OBJECT_GETTER(ruby_curl_easy, cert);
|
575
583
|
}
|
576
584
|
|
585
|
+
/*
|
586
|
+
* call-seq:
|
587
|
+
* easy.cacert = "cacert.file" => ""
|
588
|
+
*
|
589
|
+
* Set a cacert bundle to use for this Curl::Easy instance. This file
|
590
|
+
* will be used to validate SSL certificates.
|
591
|
+
*
|
592
|
+
*/
|
593
|
+
static VALUE ruby_curl_easy_cacert_set(VALUE self, VALUE cacert) {
|
594
|
+
CURB_OBJECT_SETTER(ruby_curl_easy, cacert);
|
595
|
+
}
|
596
|
+
|
597
|
+
/*
|
598
|
+
* call-seq:
|
599
|
+
* easy.cacert => "cacert.file"
|
600
|
+
*
|
601
|
+
* Obtain the cacert file to use for this Curl::Easy instance.
|
602
|
+
*/
|
603
|
+
static VALUE ruby_curl_easy_cacert_get(VALUE self) {
|
604
|
+
CURB_OBJECT_GETTER(ruby_curl_easy, cacert);
|
605
|
+
}
|
606
|
+
|
607
|
+
/*
|
608
|
+
* call-seq:
|
609
|
+
* easy.certpassword = "cert password" => ""
|
610
|
+
*
|
611
|
+
* Set a password used to open the specified cert
|
612
|
+
*/
|
613
|
+
static VALUE ruby_curl_easy_certpassword_set(VALUE self, VALUE certpassword) {
|
614
|
+
CURB_OBJECT_SETTER(ruby_curl_easy, certpassword);
|
615
|
+
}
|
616
|
+
|
617
|
+
/*
|
618
|
+
* call-seq:
|
619
|
+
* easy.certtype = "PEM|DER" => ""
|
620
|
+
*
|
621
|
+
* Set a cert type to use for this Curl::Easy instance.
|
622
|
+
* Default is PEM
|
623
|
+
*
|
624
|
+
*/
|
625
|
+
static VALUE ruby_curl_easy_certtype_set(VALUE self, VALUE certtype) {
|
626
|
+
CURB_OBJECT_SETTER(ruby_curl_easy, certtype);
|
627
|
+
}
|
628
|
+
|
629
|
+
/*
|
630
|
+
* call-seq:
|
631
|
+
* easy.certtype => "cert.type"
|
632
|
+
*
|
633
|
+
* Obtain the cert type used for this Curl::Easy instance
|
634
|
+
*/
|
635
|
+
static VALUE ruby_curl_easy_certtype_get(VALUE self) {
|
636
|
+
CURB_OBJECT_GETTER(ruby_curl_easy, certtype);
|
637
|
+
}
|
638
|
+
|
577
639
|
/*
|
578
640
|
* call-seq:
|
579
641
|
* easy.encoding= => "string"
|
@@ -595,6 +657,27 @@ static VALUE ruby_curl_easy_encoding_get(VALUE self) {
|
|
595
657
|
CURB_OBJECT_GETTER(ruby_curl_easy, encoding);
|
596
658
|
}
|
597
659
|
|
660
|
+
/*
|
661
|
+
* call-seq:
|
662
|
+
* easy.useragent = "Ruby/Curb" => ""
|
663
|
+
*
|
664
|
+
* Set the user agent string for this Curl::Easy instance
|
665
|
+
*
|
666
|
+
*/
|
667
|
+
static VALUE ruby_curl_easy_useragent_set(VALUE self, VALUE useragent) {
|
668
|
+
CURB_OBJECT_SETTER(ruby_curl_easy, useragent);
|
669
|
+
}
|
670
|
+
|
671
|
+
/*
|
672
|
+
* call-seq:
|
673
|
+
* easy.useragent => "Ruby/Curb"
|
674
|
+
*
|
675
|
+
* Obtain the user agent string used for this Curl::Easy instance
|
676
|
+
*/
|
677
|
+
static VALUE ruby_curl_easy_useragent_get(VALUE self) {
|
678
|
+
CURB_OBJECT_GETTER(ruby_curl_easy, useragent);
|
679
|
+
}
|
680
|
+
|
598
681
|
/* ================== IMMED ATTRS ==================*/
|
599
682
|
|
600
683
|
/*
|
@@ -1488,9 +1571,22 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, VALUE *body_buffer, VALUE *hea
|
|
1488
1571
|
|
1489
1572
|
/* Set up HTTPS cert handling if necessary */
|
1490
1573
|
if (rbce->cert != Qnil) {
|
1574
|
+
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, StringValuePtr(rbce->certtype));
|
1491
1575
|
curl_easy_setopt(curl, CURLOPT_SSLCERT, StringValuePtr(rbce->cert));
|
1576
|
+
if (rbce->certpassword != Qnil) {
|
1577
|
+
curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, StringValuePtr(rbce->certpassword));
|
1578
|
+
}
|
1579
|
+
}
|
1580
|
+
if (rbce->cacert != Qnil) {
|
1581
|
+
// XXX: This should really be using the output of 'curl-config --ca'
|
1492
1582
|
curl_easy_setopt(curl, CURLOPT_CAINFO, "/usr/local/share/curl/curl-ca-bundle.crt");
|
1493
1583
|
}
|
1584
|
+
|
1585
|
+
/* Set the user-agent string if specified */
|
1586
|
+
if (rbce->useragent != Qnil) {
|
1587
|
+
curl_easy_setopt(curl, CURLOPT_USERAGENT, StringValuePtr(rbce->useragent));
|
1588
|
+
}
|
1589
|
+
|
1494
1590
|
|
1495
1591
|
/* Setup HTTP headers if necessary */
|
1496
1592
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
|
@@ -2742,8 +2838,15 @@ void init_curb_easy() {
|
|
2742
2838
|
rb_define_method(cCurlEasy, "cookiejar", ruby_curl_easy_cookiejar_get, 0);
|
2743
2839
|
rb_define_method(cCurlEasy, "cert=", ruby_curl_easy_cert_set, 1);
|
2744
2840
|
rb_define_method(cCurlEasy, "cert", ruby_curl_easy_cert_get, 0);
|
2841
|
+
rb_define_method(cCurlEasy, "cacert=", ruby_curl_easy_cacert_set, 1);
|
2842
|
+
rb_define_method(cCurlEasy, "cacert", ruby_curl_easy_cacert_get, 0);
|
2843
|
+
rb_define_method(cCurlEasy, "certpassword=", ruby_curl_easy_certpassword_set, 1);
|
2844
|
+
rb_define_method(cCurlEasy, "certtype=", ruby_curl_easy_certtype_set, 1);
|
2845
|
+
rb_define_method(cCurlEasy, "certtype", ruby_curl_easy_certtype_get, 0);
|
2745
2846
|
rb_define_method(cCurlEasy, "encoding=", ruby_curl_easy_encoding_set, 1);
|
2746
2847
|
rb_define_method(cCurlEasy, "encoding", ruby_curl_easy_encoding_get, 0);
|
2848
|
+
rb_define_method(cCurlEasy, "useragent=", ruby_curl_easy_useragent_set, 1);
|
2849
|
+
rb_define_method(cCurlEasy, "useragent", ruby_curl_easy_useragent_get, 0);
|
2747
2850
|
|
2748
2851
|
rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
|
2749
2852
|
rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
|
data/ext/curb_easy.h
CHANGED
data/ext/curb_multi.c
CHANGED
@@ -249,7 +249,7 @@ static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
|
|
249
249
|
ruby_curl_multi_remove( self, rbce->self );
|
250
250
|
|
251
251
|
if (rbce->complete_proc != Qnil) {
|
252
|
-
rb_funcall( rbce->complete_proc, idCall, 1, self );
|
252
|
+
rb_funcall( rbce->complete_proc, idCall, 1, rbce->self );
|
253
253
|
}
|
254
254
|
|
255
255
|
long response_code = -1;
|
data/lib/curb.rb
CHANGED
@@ -1,9 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'curb_core'
|
3
|
-
rescue LoadError
|
4
|
-
$: << File.dirname(__FILE__)
|
5
|
-
require 'curb_core'
|
6
|
-
end
|
1
|
+
require 'curb_core'
|
7
2
|
|
8
3
|
module Curl
|
9
4
|
class Easy
|
@@ -43,5 +38,48 @@ module Curl
|
|
43
38
|
return curl
|
44
39
|
end
|
45
40
|
end
|
41
|
+
|
42
|
+
# Allow the incoming cert string to be file:password
|
43
|
+
# but be careful to not use a colon from a windows file path
|
44
|
+
# as the split point. Mimic what curl's main does
|
45
|
+
alias_method :native_cert=, :cert=
|
46
|
+
def cert=(cert_file)
|
47
|
+
pos = cert_file.rindex(':')
|
48
|
+
if pos && pos > 1
|
49
|
+
self.native_cert= cert_file[0..pos-1]
|
50
|
+
self.certpassword= cert_file[pos+1..-1]
|
51
|
+
else
|
52
|
+
self.native_cert= cert_file
|
53
|
+
end
|
54
|
+
self.cert
|
55
|
+
end
|
56
|
+
end
|
57
|
+
class Multi
|
58
|
+
class << self
|
59
|
+
# call-seq:
|
60
|
+
# Curl::Multi.get('url1','url2','url3','url4','url5', :follow_location => true) do|easy|
|
61
|
+
# easy
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# Blocking call to fetch multiple url's in parallel.
|
65
|
+
def get(urls, easy_options={}, multi_options={}, &blk)
|
66
|
+
m = Curl::Multi.new
|
67
|
+
# configure the multi handle
|
68
|
+
multi_options.each do|k,v|
|
69
|
+
m.send("#{k}=", v)
|
70
|
+
end
|
71
|
+
|
72
|
+
# create and configure each easy handle
|
73
|
+
urls.each do|url|
|
74
|
+
c = Curl::Easy.new(url)
|
75
|
+
easy_options.each do|k,v|
|
76
|
+
c.send("#{k}=",v)
|
77
|
+
end
|
78
|
+
c.on_complete {|curl| blk.call curl }
|
79
|
+
m.add(c)
|
80
|
+
end
|
81
|
+
m.perform
|
82
|
+
end
|
83
|
+
end
|
46
84
|
end
|
47
85
|
end
|
data/tests/helper.rb
CHANGED
@@ -21,7 +21,7 @@ require 'webrick'
|
|
21
21
|
# or to test with multiple threads set it to false
|
22
22
|
# this is important since, some code paths will change depending
|
23
23
|
# on the presence of multiple threads
|
24
|
-
TEST_SINGLE_THREADED=
|
24
|
+
TEST_SINGLE_THREADED=true
|
25
25
|
|
26
26
|
# keep webrick quiet
|
27
27
|
class ::WEBrick::HTTPServer
|
@@ -106,6 +106,8 @@ module TestServerMethods
|
|
106
106
|
server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
|
107
107
|
|
108
108
|
server.mount(servlet.path, servlet)
|
109
|
+
server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
|
110
|
+
|
109
111
|
trap("INT") { server.shutdown }
|
110
112
|
GC.start
|
111
113
|
wr.flush
|
@@ -120,6 +122,7 @@ module TestServerMethods
|
|
120
122
|
@server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
|
121
123
|
|
122
124
|
@server.mount(servlet.path, servlet)
|
125
|
+
@server.mount("/ext", WEBrick::HTTPServlet::FileHandler, File.join(File.dirname(__FILE__),'..','ext'))
|
123
126
|
queue = Queue.new # synchronize the thread startup to the main thread
|
124
127
|
|
125
128
|
@test_thread = Thread.new { queue << 1; @server.start }
|
data/tests/tc_curl_download.rb
CHANGED
@@ -4,24 +4,29 @@ class TestCurbCurlDownload < Test::Unit::TestCase
|
|
4
4
|
include TestServerMethods
|
5
5
|
|
6
6
|
def setup
|
7
|
-
server_setup
|
7
|
+
server_setup
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_download_url_to_file
|
11
|
-
dl_url = "http://127.0.0.1:
|
11
|
+
dl_url = "http://127.0.0.1:9129/ext/curb_easy.c"
|
12
12
|
dl_path = File.join("/tmp/dl_url_test.file")
|
13
13
|
|
14
14
|
curb = Curl::Easy.download(dl_url, dl_path)
|
15
15
|
assert File.exist?(dl_path)
|
16
|
+
assert_equal File.read(File.join(File.dirname(__FILE__), '..','ext','curb_easy.c')), File.read(dl_path)
|
17
|
+
ensure
|
18
|
+
File.unlink(dl_path) if File.exist?(dl_path)
|
16
19
|
end
|
17
20
|
|
18
21
|
def test_download_bad_url_gives_404
|
19
|
-
dl_url = "http://127.0.0.1:
|
22
|
+
dl_url = "http://127.0.0.1:9129/this_file_does_not_exist.html"
|
20
23
|
dl_path = File.join("/tmp/dl_url_test.file")
|
21
24
|
|
22
25
|
curb = Curl::Easy.download(dl_url, dl_path)
|
23
26
|
assert_equal Curl::Easy, curb.class
|
24
27
|
assert_equal 404, curb.response_code
|
28
|
+
ensure
|
29
|
+
File.unlink(dl_path) if File.exist?(dl_path)
|
25
30
|
end
|
26
31
|
|
27
32
|
end
|
data/tests/tc_curl_easy.rb
CHANGED
@@ -547,6 +547,46 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
547
547
|
assert_equal "PUT\n#{File.read(__FILE__)}", curl.body_str
|
548
548
|
end
|
549
549
|
|
550
|
+
# Generate a self-signed cert with
|
551
|
+
# openssl req -new -newkey rsa:1024 -days 365 -nodes -x509 \
|
552
|
+
# -keyout tests/cert.pem -out tests/cert.pem
|
553
|
+
def test_cert
|
554
|
+
curl = Curl::Easy.new(TestServlet.url)
|
555
|
+
curl.cert= File.join(File.dirname(__FILE__),"cert.pem")
|
556
|
+
assert /cert.pem$/,curl.cert
|
557
|
+
end
|
558
|
+
|
559
|
+
def test_cert_with_password
|
560
|
+
curl = Curl::Easy.new(TestServlet.url)
|
561
|
+
curl.cert= File.join(File.dirname(__FILE__),"cert.pem:password")
|
562
|
+
assert /cert.pem$/,curl.cert
|
563
|
+
end
|
564
|
+
|
565
|
+
def test_cert_type
|
566
|
+
curl = Curl::Easy.new(TestServlet.url)
|
567
|
+
curl.certtype= "DER"
|
568
|
+
assert "DER", curl.certtype
|
569
|
+
end
|
570
|
+
|
571
|
+
def test_default_certtype
|
572
|
+
curl = Curl::Easy.new(TestServlet.url)
|
573
|
+
assert "PEM", curl.certtype
|
574
|
+
end
|
575
|
+
|
576
|
+
# Generate a CA cert with instructions at
|
577
|
+
# http://technocage.com/~caskey/openssl/
|
578
|
+
def test_ca_cert
|
579
|
+
curl = Curl::Easy.new(TestServlet.url)
|
580
|
+
curl.cacert= File.join(File.dirname(__FILE__),"cacert.pem")
|
581
|
+
assert /cacert.pem$/, curl.cacert
|
582
|
+
end
|
583
|
+
|
584
|
+
def test_user_agent
|
585
|
+
curl = Curl::Easy.new(TestServlet.url)
|
586
|
+
curl.useragent= "Curb-Easy/Ruby"
|
587
|
+
assert /ScrubDog$/,curl.useragent
|
588
|
+
end
|
589
|
+
|
550
590
|
include TestServerMethods
|
551
591
|
|
552
592
|
def setup
|
data/tests/tc_curl_multi.rb
CHANGED
@@ -89,7 +89,6 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
89
89
|
end
|
90
90
|
m.add c
|
91
91
|
end
|
92
|
-
|
93
92
|
m.perform
|
94
93
|
|
95
94
|
assert n, responses.size
|
@@ -246,4 +245,22 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
246
245
|
end
|
247
246
|
=end
|
248
247
|
|
248
|
+
def test_multi_easy_get_01
|
249
|
+
urls = []
|
250
|
+
root_uri = 'http://127.0.0.1:9129/ext/'
|
251
|
+
# send a request to fetch all c files in the ext dir
|
252
|
+
Dir[File.dirname(__FILE__) + "/../ext/*.c"].each do|path|
|
253
|
+
urls << root_uri + File.basename(path)
|
254
|
+
end
|
255
|
+
Curl::Multi.get(urls, {:follow_location => true}, {:pipeline => true}) do|curl|
|
256
|
+
assert_equal 200, curl.response_code
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
include TestServerMethods
|
261
|
+
|
262
|
+
def setup
|
263
|
+
server_setup
|
264
|
+
end
|
265
|
+
|
249
266
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taf2-curb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ross Bamford
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-
|
13
|
+
date: 2009-07-02 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|