curb 0.9.11 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.markdown +33 -4
- data/Rakefile +8 -11
- data/ext/curb.c +150 -8
- data/ext/curb.h +10 -5
- data/ext/curb_easy.c +74 -25
- data/ext/curb_easy.h +3 -0
- data/ext/curb_multi.c +11 -11
- data/ext/curb_postfield.c +7 -7
- data/ext/extconf.rb +36 -0
- data/lib/curl/easy.rb +8 -7
- data/lib/curl.rb +11 -3
- data/tests/helper.rb +0 -1
- data/tests/tc_curl_easy.rb +9 -1
- data/tests/tc_curl_multi.rb +52 -11
- data/tests/tc_curl_protocols.rb +37 -0
- data/tests/timeout.rb +21 -5
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b452d79ee28ee380d6741f39f9fbf826a33a46d473fa4444edb6a56a122af8f8
|
|
4
|
+
data.tar.gz: '094812699e5b64584d6dd02a17b16884ee696a20dbf324c05498a46509e39b16'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0df71c1a4eb7896f89da78a79ba9160d5606aa235b89544e08630c558a7cebb1220ec026f99f404915f52e15162cf2c988a66abe04932c3cd1104a1784bd3056
|
|
7
|
+
data.tar.gz: '08fba6b5b9a9404f839e4110b0d485e1595be36554345abb88a05482183204f4e0f13001a7731db75e89ca890bfa8ad19ccced63dfecd0e766f1b825ff5e9f1a'
|
data/README.markdown
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the
|
|
7
7
|
libcurl(3), a fully-featured client-side URL transfer library.
|
|
8
|
-
cURL and libcurl live at [
|
|
8
|
+
cURL and libcurl live at [https://curl.se/libcurl/](https://curl.se/libcurl/) .
|
|
9
9
|
|
|
10
10
|
Curb is a work-in-progress, and currently only supports libcurl's `easy` and `multi` modes.
|
|
11
11
|
|
|
@@ -14,9 +14,31 @@ Curb is a work-in-progress, and currently only supports libcurl's `easy` and `mu
|
|
|
14
14
|
Curb is copyright (c)2006 Ross Bamford, and released under the terms of the
|
|
15
15
|
Ruby license. See the LICENSE file for the gory details.
|
|
16
16
|
|
|
17
|
+
## Easy mode
|
|
18
|
+
|
|
19
|
+
Get stuff
|
|
20
|
+
```
|
|
21
|
+
res = Curl.get("https://www.google.com/")
|
|
22
|
+
puts res.response_code
|
|
23
|
+
puts res.header_str
|
|
24
|
+
puts res.body
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Post stuff
|
|
28
|
+
```
|
|
29
|
+
res = Curl.post("https://your-server.com/endpoint", {post: "this"}.to_json) {|http|
|
|
30
|
+
http.headers["Content-Type"] = "application/json"
|
|
31
|
+
}
|
|
32
|
+
puts res.response_code
|
|
33
|
+
puts res.header_str
|
|
34
|
+
puts res.body
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
17
39
|
## You will need
|
|
18
40
|
|
|
19
|
-
* A working Ruby installation (`
|
|
41
|
+
* A working Ruby installation (`2.0.0+` will work but `2.1+` preferred) (it's possible it still works with 1.8.7 but you'd have to tell me if not...)
|
|
20
42
|
* A working libcurl development installation
|
|
21
43
|
(Ideally one of the versions listed in the compatibility chart below that maps to your `curb` version)
|
|
22
44
|
* A sane build environment (e.g. gcc, make)
|
|
@@ -29,7 +51,8 @@ tested and reported to work across a variety of platforms / rubies)
|
|
|
29
51
|
|
|
30
52
|
| Gem Version | Release Date | libcurl versions |
|
|
31
53
|
| ----------- | ----------- | ---------------- |
|
|
32
|
-
| 0.
|
|
54
|
+
| 1.0.0 | Jan 2022 | 7.58 - 7.81 |
|
|
55
|
+
| 0.9.8 | Jan 2019 | 7.58 - 7.81 |
|
|
33
56
|
| 0.9.7 | Nov 2018 | 7.56 - 7.60 |
|
|
34
57
|
| 0.9.6 | May 2018 | 7.51 - 7.59 |
|
|
35
58
|
| 0.9.5 | May 2018 | 7.51 - 7.59 |
|
|
@@ -43,7 +66,7 @@ tested and reported to work across a variety of platforms / rubies)
|
|
|
43
66
|
$ gem install curb
|
|
44
67
|
|
|
45
68
|
On Windows, make sure you're using the [DevKit](http://rubyinstaller.org/downloads/) and
|
|
46
|
-
the [development version of libcurl](http://curl.
|
|
69
|
+
the [development version of libcurl](http://curl.se/gknw.net/7.39.0/dist-w32/curl-7.39.0-devel-mingw32.zip). Unzip, then run this in your command
|
|
47
70
|
line (alter paths to your curl location, but remember to use forward slashes):
|
|
48
71
|
|
|
49
72
|
gem install curb --platform=ruby -- --with-curl-lib=C:/curl-7.39.0-devel-mingw32/lib --with-curl-include=C:/curl-7.39.0-devel-mingw32/include
|
|
@@ -67,6 +90,12 @@ expand on the above instructions, please report the issue at http://github.com/t
|
|
|
67
90
|
|
|
68
91
|
On Ubuntu, the dependencies can be satisfied by installing the following packages:
|
|
69
92
|
|
|
93
|
+
18.04 and onwards
|
|
94
|
+
|
|
95
|
+
$ sudo apt-get install libcurl4 libcurl3-gnutls libcurl4-openssl-dev
|
|
96
|
+
|
|
97
|
+
< 18.04
|
|
98
|
+
|
|
70
99
|
$ sudo apt-get install libcurl3 libcurl3-gnutls libcurl4-openssl-dev
|
|
71
100
|
|
|
72
101
|
On RedHat:
|
data/Rakefile
CHANGED
|
@@ -57,22 +57,20 @@ MAKEOPTS = ENV['MAKE_OPTS'] || ''
|
|
|
57
57
|
CURB_SO = "ext/curb_core.#{(defined?(RbConfig) ? RbConfig : Config)::MAKEFILE_CONFIG['DLEXT']}"
|
|
58
58
|
|
|
59
59
|
file 'ext/Makefile' => 'ext/extconf.rb' do
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
shell(['ruby', 'extconf.rb', ENV['EXTCONF_OPTS'].to_s],
|
|
61
|
+
{ :live_stdout => STDOUT , :cwd => "#{Dir.pwd}/ext" }
|
|
62
|
+
).error!
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def make(target = '')
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
end
|
|
66
|
+
shell(["#{MAKECMD}", "#{MAKEOPTS}", "#{target}"].reject(&:empty?),
|
|
67
|
+
{ :live_stdout => STDOUT, :cwd => "#{Dir.pwd}/ext" }
|
|
68
|
+
).error!
|
|
70
69
|
end
|
|
71
70
|
|
|
72
71
|
# Let make handle dependencies between c/o/so - we'll just run it.
|
|
73
72
|
file CURB_SO => (['ext/Makefile'] + Dir['ext/*.c'] + Dir['ext/*.h']) do
|
|
74
|
-
|
|
75
|
-
fail "Make failed (status #{m})" unless m == 0
|
|
73
|
+
make
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
desc "Compile the shared object"
|
|
@@ -80,8 +78,7 @@ task :compile => [CURB_SO]
|
|
|
80
78
|
|
|
81
79
|
desc "Install to your site_ruby directory"
|
|
82
80
|
task :install do
|
|
83
|
-
|
|
84
|
-
fail "Make install failed (status #{m})" unless m == 0
|
|
81
|
+
make 'install'
|
|
85
82
|
end
|
|
86
83
|
|
|
87
84
|
# Test Tasks ---------------------------------------------------------
|
data/ext/curb.c
CHANGED
|
@@ -235,12 +235,16 @@ static VALUE ruby_curl_http2_q(VALUE mod) {
|
|
|
235
235
|
#endif
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
static void finalize_curb_core(VALUE data) {
|
|
239
|
+
curl_global_cleanup();
|
|
240
|
+
}
|
|
241
|
+
|
|
238
242
|
void Init_curb_core() {
|
|
239
|
-
// TODO we need to call curl_global_cleanup at exit!
|
|
240
243
|
curl_version_info_data *ver;
|
|
241
244
|
VALUE curlver, curllongver, curlvernum;
|
|
242
245
|
|
|
243
246
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
247
|
+
rb_set_end_proc(finalize_curb_core, Qnil);
|
|
244
248
|
ver = curl_version_info(CURLVERSION_NOW);
|
|
245
249
|
|
|
246
250
|
mCurl = rb_define_module("Curl");
|
|
@@ -292,18 +296,26 @@ void Init_curb_core() {
|
|
|
292
296
|
#endif
|
|
293
297
|
|
|
294
298
|
#ifdef CURL_VERSION_SSL
|
|
295
|
-
rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT",
|
|
299
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", LONG2NUM(CURL_SSLVERSION_DEFAULT));
|
|
300
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_DEFAULT", LONG2NUM(CURL_SSLVERSION_MAX_DEFAULT));
|
|
296
301
|
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", LONG2NUM(CURL_SSLVERSION_TLSv1));
|
|
297
302
|
rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", LONG2NUM(CURL_SSLVERSION_SSLv2));
|
|
298
303
|
rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", LONG2NUM(CURL_SSLVERSION_SSLv3));
|
|
299
304
|
#if HAVE_CURL_SSLVERSION_TLSV1_0
|
|
300
|
-
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0",
|
|
305
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(CURL_SSLVERSION_TLSv1_0));
|
|
306
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_0", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_0));
|
|
301
307
|
#endif
|
|
302
308
|
#if HAVE_CURL_SSLVERSION_TLSV1_1
|
|
303
|
-
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1",
|
|
309
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(CURL_SSLVERSION_TLSv1_1));
|
|
310
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_1", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_1));
|
|
304
311
|
#endif
|
|
305
312
|
#if HAVE_CURL_SSLVERSION_TLSV1_2
|
|
306
|
-
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2",
|
|
313
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(CURL_SSLVERSION_TLSv1_2));
|
|
314
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_2", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_2));
|
|
315
|
+
#endif
|
|
316
|
+
#if HAVE_CURL_SSLVERSION_TLSV1_3
|
|
317
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_3", LONG2NUM(CURL_SSLVERSION_TLSv1_3));
|
|
318
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_3", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_3));
|
|
307
319
|
#endif
|
|
308
320
|
|
|
309
321
|
rb_define_const(mCurl, "CURL_USESSL_CONTROL", LONG2NUM(CURB_FTPSSL_CONTROL));
|
|
@@ -316,13 +328,20 @@ void Init_curb_core() {
|
|
|
316
328
|
rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", LONG2NUM(-1));
|
|
317
329
|
rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", LONG2NUM(-1));
|
|
318
330
|
#if HAVE_CURL_SSLVERSION_TLSv1_0
|
|
319
|
-
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0",
|
|
331
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(-1));
|
|
332
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_0", LONG2NUM(-1));
|
|
320
333
|
#endif
|
|
321
334
|
#if HAVE_CURL_SSLVERSION_TLSv1_1
|
|
322
|
-
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1",
|
|
335
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(-1));
|
|
336
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_1", LONG2NUM(-1));
|
|
323
337
|
#endif
|
|
324
338
|
#if HAVE_CURL_SSLVERSION_TLSv1_2
|
|
325
|
-
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2",
|
|
339
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(-1));
|
|
340
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_2", LONG2NUM(-1));
|
|
341
|
+
#endif
|
|
342
|
+
#if HAVE_CURL_SSLVERSION_TLSv1_3
|
|
343
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_3", LONG2NUM(-1));
|
|
344
|
+
rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_3", LONG2NUM(-1));
|
|
326
345
|
#endif
|
|
327
346
|
|
|
328
347
|
rb_define_const(mCurl, "CURL_USESSL_CONTROL", LONG2NUM(-1));
|
|
@@ -925,12 +944,19 @@ void Init_curb_core() {
|
|
|
925
944
|
#endif
|
|
926
945
|
#if HAVE_CURL_SSLVERSION_TLSv1_0
|
|
927
946
|
CURB_DEFINE(CURL_SSLVERSION_TLSv1_0);
|
|
947
|
+
CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_0);
|
|
928
948
|
#endif
|
|
929
949
|
#if HAVE_CURL_SSLVERSION_TLSv1_1
|
|
930
950
|
CURB_DEFINE(CURL_SSLVERSION_TLSv1_1);
|
|
951
|
+
CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_1);
|
|
931
952
|
#endif
|
|
932
953
|
#if HAVE_CURL_SSLVERSION_TLSv1_2
|
|
933
954
|
CURB_DEFINE(CURL_SSLVERSION_TLSv1_2);
|
|
955
|
+
CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_2);
|
|
956
|
+
#endif
|
|
957
|
+
#if HAVE_CURL_SSLVERSION_TLSv1_3
|
|
958
|
+
CURB_DEFINE(CURL_SSLVERSION_TLSv1_3);
|
|
959
|
+
CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_3);
|
|
934
960
|
#endif
|
|
935
961
|
#if HAVE_CURLOPT_SSL_VERIFYPEER
|
|
936
962
|
CURB_DEFINE(CURLOPT_SSL_VERIFYPEER);
|
|
@@ -1050,6 +1076,122 @@ void Init_curb_core() {
|
|
|
1050
1076
|
CURB_DEFINE(CURLOPT_HAPROXYPROTOCOL);
|
|
1051
1077
|
#endif
|
|
1052
1078
|
|
|
1079
|
+
#if HAVE_CURLPROTO_RTMPTE
|
|
1080
|
+
CURB_DEFINE(CURLPROTO_RTMPTE);
|
|
1081
|
+
#endif
|
|
1082
|
+
|
|
1083
|
+
#if HAVE_CURLPROTO_RTMPTS
|
|
1084
|
+
CURB_DEFINE(CURLPROTO_RTMPTS);
|
|
1085
|
+
#endif
|
|
1086
|
+
|
|
1087
|
+
#if HAVE_CURLPROTO_SMBS
|
|
1088
|
+
CURB_DEFINE(CURLPROTO_SMBS);
|
|
1089
|
+
#endif
|
|
1090
|
+
|
|
1091
|
+
#if HAVE_CURLPROTO_LDAP
|
|
1092
|
+
CURB_DEFINE(CURLPROTO_LDAP);
|
|
1093
|
+
#endif
|
|
1094
|
+
|
|
1095
|
+
#if HAVE_CURLPROTO_FTP
|
|
1096
|
+
CURB_DEFINE(CURLPROTO_FTP);
|
|
1097
|
+
#endif
|
|
1098
|
+
|
|
1099
|
+
#if HAVE_CURLPROTO_SMTPS
|
|
1100
|
+
CURB_DEFINE(CURLPROTO_SMTPS);
|
|
1101
|
+
#endif
|
|
1102
|
+
|
|
1103
|
+
#if HAVE_CURLPROTO_HTTP
|
|
1104
|
+
CURB_DEFINE(CURLPROTO_HTTP);
|
|
1105
|
+
#endif
|
|
1106
|
+
|
|
1107
|
+
#if HAVE_CURLPROTO_SMTP
|
|
1108
|
+
CURB_DEFINE(CURLPROTO_SMTP);
|
|
1109
|
+
#endif
|
|
1110
|
+
|
|
1111
|
+
#if HAVE_CURLPROTO_TFTP
|
|
1112
|
+
CURB_DEFINE(CURLPROTO_TFTP);
|
|
1113
|
+
#endif
|
|
1114
|
+
|
|
1115
|
+
#if HAVE_CURLPROTO_LDAPS
|
|
1116
|
+
CURB_DEFINE(CURLPROTO_LDAPS);
|
|
1117
|
+
#endif
|
|
1118
|
+
|
|
1119
|
+
#if HAVE_CURLPROTO_IMAPS
|
|
1120
|
+
CURB_DEFINE(CURLPROTO_IMAPS);
|
|
1121
|
+
#endif
|
|
1122
|
+
|
|
1123
|
+
#if HAVE_CURLPROTO_SCP
|
|
1124
|
+
CURB_DEFINE(CURLPROTO_SCP);
|
|
1125
|
+
#endif
|
|
1126
|
+
|
|
1127
|
+
#if HAVE_CURLPROTO_SFTP
|
|
1128
|
+
CURB_DEFINE(CURLPROTO_SFTP);
|
|
1129
|
+
#endif
|
|
1130
|
+
|
|
1131
|
+
#if HAVE_CURLPROTO_TELNET
|
|
1132
|
+
CURB_DEFINE(CURLPROTO_TELNET);
|
|
1133
|
+
#endif
|
|
1134
|
+
|
|
1135
|
+
#if HAVE_CURLPROTO_FILE
|
|
1136
|
+
CURB_DEFINE(CURLPROTO_FILE);
|
|
1137
|
+
#endif
|
|
1138
|
+
|
|
1139
|
+
#if HAVE_CURLPROTO_FTPS
|
|
1140
|
+
CURB_DEFINE(CURLPROTO_FTPS);
|
|
1141
|
+
#endif
|
|
1142
|
+
|
|
1143
|
+
#if HAVE_CURLPROTO_HTTPS
|
|
1144
|
+
CURB_DEFINE(CURLPROTO_HTTPS);
|
|
1145
|
+
#endif
|
|
1146
|
+
|
|
1147
|
+
#if HAVE_CURLPROTO_IMAP
|
|
1148
|
+
CURB_DEFINE(CURLPROTO_IMAP);
|
|
1149
|
+
#endif
|
|
1150
|
+
|
|
1151
|
+
#if HAVE_CURLPROTO_POP3
|
|
1152
|
+
CURB_DEFINE(CURLPROTO_POP3);
|
|
1153
|
+
#endif
|
|
1154
|
+
|
|
1155
|
+
#if HAVE_CURLPROTO_GOPHER
|
|
1156
|
+
CURB_DEFINE(CURLPROTO_GOPHER);
|
|
1157
|
+
#endif
|
|
1158
|
+
|
|
1159
|
+
#if HAVE_CURLPROTO_DICT
|
|
1160
|
+
CURB_DEFINE(CURLPROTO_DICT);
|
|
1161
|
+
#endif
|
|
1162
|
+
|
|
1163
|
+
#if HAVE_CURLPROTO_SMB
|
|
1164
|
+
CURB_DEFINE(CURLPROTO_SMB);
|
|
1165
|
+
#endif
|
|
1166
|
+
|
|
1167
|
+
#if HAVE_CURLPROTO_RTMP
|
|
1168
|
+
CURB_DEFINE(CURLPROTO_RTMP);
|
|
1169
|
+
#endif
|
|
1170
|
+
|
|
1171
|
+
#if HAVE_CURLPROTO_ALL
|
|
1172
|
+
CURB_DEFINE(CURLPROTO_ALL);
|
|
1173
|
+
#endif
|
|
1174
|
+
|
|
1175
|
+
#if HAVE_CURLPROTO_RTMPE
|
|
1176
|
+
CURB_DEFINE(CURLPROTO_RTMPE);
|
|
1177
|
+
#endif
|
|
1178
|
+
|
|
1179
|
+
#if HAVE_CURLPROTO_RTMPS
|
|
1180
|
+
CURB_DEFINE(CURLPROTO_RTMPS);
|
|
1181
|
+
#endif
|
|
1182
|
+
|
|
1183
|
+
#if HAVE_CURLPROTO_RTMPT
|
|
1184
|
+
CURB_DEFINE(CURLPROTO_RTMPT);
|
|
1185
|
+
#endif
|
|
1186
|
+
|
|
1187
|
+
#if HAVE_CURLPROTO_POP3S
|
|
1188
|
+
CURB_DEFINE(CURLPROTO_POP3S);
|
|
1189
|
+
#endif
|
|
1190
|
+
|
|
1191
|
+
#if HAVE_CURLPROTO_RTSP
|
|
1192
|
+
CURB_DEFINE(CURLPROTO_RTSP);
|
|
1193
|
+
#endif
|
|
1194
|
+
|
|
1053
1195
|
#if LIBCURL_VERSION_NUM >= 0x072B00 /* 7.43.0 */
|
|
1054
1196
|
CURB_DEFINE(CURLPIPE_NOTHING);
|
|
1055
1197
|
CURB_DEFINE(CURLPIPE_HTTP1);
|
data/ext/curb.h
CHANGED
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
#include "curb_macros.h"
|
|
29
29
|
|
|
30
30
|
// These should be managed from the Rake 'release' task.
|
|
31
|
-
#define CURB_VERSION "0.
|
|
32
|
-
#define CURB_VER_NUM
|
|
33
|
-
#define CURB_VER_MAJ
|
|
34
|
-
#define CURB_VER_MIN
|
|
35
|
-
#define CURB_VER_MIC
|
|
31
|
+
#define CURB_VERSION "1.0.1"
|
|
32
|
+
#define CURB_VER_NUM 1001
|
|
33
|
+
#define CURB_VER_MAJ 1
|
|
34
|
+
#define CURB_VER_MIN 0
|
|
35
|
+
#define CURB_VER_MIC 1
|
|
36
36
|
#define CURB_VER_PATCH 0
|
|
37
37
|
|
|
38
38
|
|
|
@@ -49,6 +49,11 @@
|
|
|
49
49
|
#define RHASH_SIZE(hash) RHASH(hash)->tbl->num_entries
|
|
50
50
|
#endif
|
|
51
51
|
|
|
52
|
+
// ruby 1.8 does not provide the macro
|
|
53
|
+
#ifndef DBL2NUM
|
|
54
|
+
#define DBL2NUM(dbl) rb_float_new(dbl)
|
|
55
|
+
#endif
|
|
56
|
+
|
|
52
57
|
extern VALUE mCurl;
|
|
53
58
|
|
|
54
59
|
extern void Init_curb_core();
|
data/ext/curb_easy.c
CHANGED
|
@@ -268,6 +268,8 @@ void curl_easy_free(ruby_curl_easy *rbce) {
|
|
|
268
268
|
static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
|
|
269
269
|
rbce->opts = rb_hash_new();
|
|
270
270
|
|
|
271
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
272
|
+
|
|
271
273
|
rbce->curl_headers = NULL;
|
|
272
274
|
rbce->curl_proxy_headers = NULL;
|
|
273
275
|
rbce->curl_ftp_commands = NULL;
|
|
@@ -327,9 +329,9 @@ static VALUE ruby_curl_easy_allocate(VALUE klass) {
|
|
|
327
329
|
|
|
328
330
|
/*
|
|
329
331
|
* call-seq:
|
|
330
|
-
* Curl::Easy.new =>
|
|
331
|
-
* Curl::Easy.new(url = nil) =>
|
|
332
|
-
* Curl::Easy.new(url = nil) { |self| ... } =>
|
|
332
|
+
* Curl::Easy.new => #<Curl::Easy...>
|
|
333
|
+
* Curl::Easy.new(url = nil) => #<Curl::Easy...>
|
|
334
|
+
* Curl::Easy.new(url = nil) { |self| ... } => #<Curl::Easy...>
|
|
333
335
|
*
|
|
334
336
|
* Initialize a new Curl::Easy instance, optionally supplying the URL.
|
|
335
337
|
* The block form allows further configuration to be supplied before
|
|
@@ -355,8 +357,9 @@ static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
355
357
|
|
|
356
358
|
ruby_curl_easy_zero(rbce);
|
|
357
359
|
|
|
358
|
-
|
|
360
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
359
361
|
|
|
362
|
+
rb_easy_set("url", url);
|
|
360
363
|
|
|
361
364
|
/* set the pointer to the curl handle */
|
|
362
365
|
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
|
@@ -373,8 +376,8 @@ static VALUE ruby_curl_easy_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
373
376
|
|
|
374
377
|
/*
|
|
375
378
|
* call-seq:
|
|
376
|
-
* easy.clone =>
|
|
377
|
-
* easy.dup =>
|
|
379
|
+
* easy.clone => <easy clone>
|
|
380
|
+
* easy.dup => <easy clone>
|
|
378
381
|
*
|
|
379
382
|
* Clone this Curl::Easy instance, creating a new instance.
|
|
380
383
|
* This method duplicates the underlying CURL* handle.
|
|
@@ -392,6 +395,8 @@ static VALUE ruby_curl_easy_clone(VALUE self) {
|
|
|
392
395
|
newrbce->curl_ftp_commands = NULL;
|
|
393
396
|
newrbce->curl_resolve = NULL;
|
|
394
397
|
|
|
398
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
399
|
+
|
|
395
400
|
return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
|
|
396
401
|
}
|
|
397
402
|
|
|
@@ -461,7 +466,9 @@ static VALUE ruby_curl_easy_reset(VALUE self) {
|
|
|
461
466
|
curl_easy_reset(rbce->curl);
|
|
462
467
|
ruby_curl_easy_zero(rbce);
|
|
463
468
|
|
|
464
|
-
|
|
469
|
+
curl_easy_setopt(rbce->curl, CURLOPT_ERRORBUFFER, &rbce->err_buf);
|
|
470
|
+
|
|
471
|
+
/* reset clobbers the private setting, so reset it to self */
|
|
465
472
|
ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
|
|
466
473
|
if (ecode != CURLE_OK) {
|
|
467
474
|
raise_curl_easy_error_exception(ecode);
|
|
@@ -950,7 +957,7 @@ static VALUE ruby_curl_easy_ftp_commands_set(VALUE self, VALUE ftp_commands) {
|
|
|
950
957
|
}
|
|
951
958
|
|
|
952
959
|
/*
|
|
953
|
-
* call-seq
|
|
960
|
+
* call-seq:
|
|
954
961
|
* easy.ftp_commands => array or nil
|
|
955
962
|
*/
|
|
956
963
|
static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
|
|
@@ -969,7 +976,7 @@ static VALUE ruby_curl_easy_resolve_set(VALUE self, VALUE resolve) {
|
|
|
969
976
|
}
|
|
970
977
|
|
|
971
978
|
/*
|
|
972
|
-
* call-seq
|
|
979
|
+
* call-seq:
|
|
973
980
|
* easy.resolve => array or nil
|
|
974
981
|
*/
|
|
975
982
|
static VALUE ruby_curl_easy_resolve_get(VALUE self) {
|
|
@@ -1539,6 +1546,7 @@ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
|
|
|
1539
1546
|
* Curl::CURL_SSLVERSION_TLSv1_0
|
|
1540
1547
|
* Curl::CURL_SSLVERSION_TLSv1_1
|
|
1541
1548
|
* Curl::CURL_SSLVERSION_TLSv1_2
|
|
1549
|
+
* Curl::CURL_SSLVERSION_TLSv1_3
|
|
1542
1550
|
*/
|
|
1543
1551
|
static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
|
|
1544
1552
|
CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
|
|
@@ -1587,7 +1595,7 @@ static VALUE ruby_curl_easy_ftp_filemethod_set(VALUE self, VALUE ftp_filemethod)
|
|
|
1587
1595
|
}
|
|
1588
1596
|
|
|
1589
1597
|
/*
|
|
1590
|
-
* call-seq
|
|
1598
|
+
* call-seq:
|
|
1591
1599
|
* easy.ftp_filemethod => fixnum
|
|
1592
1600
|
*
|
|
1593
1601
|
* Get the configuration for how libcurl will reach files on the server.
|
|
@@ -1959,7 +1967,7 @@ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
|
|
|
1959
1967
|
|
|
1960
1968
|
/*
|
|
1961
1969
|
* call-seq:
|
|
1962
|
-
* easy.on_body { |body_data| ... } =>
|
|
1970
|
+
* easy.on_body { |body_data| ... } => <old handler>
|
|
1963
1971
|
*
|
|
1964
1972
|
* Assign or remove the +on_body+ handler for this Curl::Easy instance.
|
|
1965
1973
|
* To remove a previously-supplied handler, call this method with no
|
|
@@ -1978,7 +1986,7 @@ static VALUE ruby_curl_easy_on_body_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1978
1986
|
|
|
1979
1987
|
/*
|
|
1980
1988
|
* call-seq:
|
|
1981
|
-
* easy.on_success { |easy| ... } =>
|
|
1989
|
+
* easy.on_success { |easy| ... } => <old handler>
|
|
1982
1990
|
*
|
|
1983
1991
|
* Assign or remove the +on_success+ handler for this Curl::Easy instance.
|
|
1984
1992
|
* To remove a previously-supplied handler, call this method with no
|
|
@@ -1993,7 +2001,7 @@ static VALUE ruby_curl_easy_on_success_set(int argc, VALUE *argv, VALUE self) {
|
|
|
1993
2001
|
|
|
1994
2002
|
/*
|
|
1995
2003
|
* call-seq:
|
|
1996
|
-
* easy.on_failure {|easy,code| ... } =>
|
|
2004
|
+
* easy.on_failure {|easy,code| ... } => <old handler>
|
|
1997
2005
|
*
|
|
1998
2006
|
* Assign or remove the +on_failure+ handler for this Curl::Easy instance.
|
|
1999
2007
|
* To remove a previously-supplied handler, call this method with no
|
|
@@ -2008,7 +2016,7 @@ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
|
|
|
2008
2016
|
|
|
2009
2017
|
/*
|
|
2010
2018
|
* call-seq:
|
|
2011
|
-
* easy.on_missing {|easy,code| ... } =>
|
|
2019
|
+
* easy.on_missing {|easy,code| ... } => <old handler;>
|
|
2012
2020
|
*
|
|
2013
2021
|
* Assign or remove the on_missing handler for this Curl::Easy instance.
|
|
2014
2022
|
* To remove a previously-supplied handler, call this method with no attached
|
|
@@ -2023,7 +2031,7 @@ static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
|
|
|
2023
2031
|
|
|
2024
2032
|
/*
|
|
2025
2033
|
* call-seq:
|
|
2026
|
-
* easy.on_redirect {|easy,code| ... } =>
|
|
2034
|
+
* easy.on_redirect {|easy,code| ... } => <old handler;>
|
|
2027
2035
|
*
|
|
2028
2036
|
* Assign or remove the on_redirect handler for this Curl::Easy instance.
|
|
2029
2037
|
* To remove a previously-supplied handler, call this method with no attached
|
|
@@ -2038,7 +2046,7 @@ static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
|
|
|
2038
2046
|
|
|
2039
2047
|
/*
|
|
2040
2048
|
* call-seq:
|
|
2041
|
-
* easy.on_complete {|easy| ... } =>
|
|
2049
|
+
* easy.on_complete {|easy| ... } => <old handler>
|
|
2042
2050
|
*
|
|
2043
2051
|
* Assign or remove the +on_complete+ handler for this Curl::Easy instance.
|
|
2044
2052
|
* To remove a previously-supplied handler, call this method with no
|
|
@@ -2052,7 +2060,7 @@ static VALUE ruby_curl_easy_on_complete_set(int argc, VALUE *argv, VALUE self) {
|
|
|
2052
2060
|
|
|
2053
2061
|
/*
|
|
2054
2062
|
* call-seq:
|
|
2055
|
-
* easy.on_header { |header_data| ... } =>
|
|
2063
|
+
* easy.on_header { |header_data| ... } => <old handler>
|
|
2056
2064
|
*
|
|
2057
2065
|
* Assign or remove the +on_header+ handler for this Curl::Easy instance.
|
|
2058
2066
|
* To remove a previously-supplied handler, call this method with no
|
|
@@ -2068,7 +2076,7 @@ static VALUE ruby_curl_easy_on_header_set(int argc, VALUE *argv, VALUE self) {
|
|
|
2068
2076
|
|
|
2069
2077
|
/*
|
|
2070
2078
|
* call-seq:
|
|
2071
|
-
* easy.on_progress { |dl_total, dl_now, ul_total, ul_now| ... } =>
|
|
2079
|
+
* easy.on_progress { |dl_total, dl_now, ul_total, ul_now| ... } => <old handler>
|
|
2072
2080
|
*
|
|
2073
2081
|
* Assign or remove the +on_progress+ handler for this Curl::Easy instance.
|
|
2074
2082
|
* To remove a previously-supplied handler, call this method with no
|
|
@@ -2089,7 +2097,7 @@ static VALUE ruby_curl_easy_on_progress_set(int argc, VALUE *argv, VALUE self) {
|
|
|
2089
2097
|
|
|
2090
2098
|
/*
|
|
2091
2099
|
* call-seq:
|
|
2092
|
-
* easy.on_debug { |type, data| ... } =>
|
|
2100
|
+
* easy.on_debug { |type, data| ... } => <old handler>
|
|
2093
2101
|
*
|
|
2094
2102
|
* Assign or remove the +on_debug+ handler for this Curl::Easy instance.
|
|
2095
2103
|
* To remove a previously-supplied handler, call this method with no
|
|
@@ -2128,11 +2136,14 @@ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
|
|
|
2128
2136
|
|
|
2129
2137
|
name = rb_obj_as_string(rb_ary_entry(header, 0));
|
|
2130
2138
|
value = rb_obj_as_string(rb_ary_entry(header, 1));
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2139
|
+
if (rb_str_strlen(value) == 0) { // removing the header e.g. Accept: with nothing trailing should remove it see: https://curl.se/libcurl/c/CURLOPT_HTTPHEADER.html
|
|
2140
|
+
header_str = rb_str_plus(name, rb_str_new2(":"));
|
|
2141
|
+
} else {
|
|
2142
|
+
// This is a bit inefficient, but we don't want to be modifying
|
|
2143
|
+
// the actual values in the original hash.
|
|
2144
|
+
header_str = rb_str_plus(name, rb_str_new2(": "));
|
|
2145
|
+
header_str = rb_str_plus(header_str, value);
|
|
2146
|
+
}
|
|
2136
2147
|
} else {
|
|
2137
2148
|
header_str = rb_obj_as_string(header);
|
|
2138
2149
|
}
|
|
@@ -2607,6 +2618,8 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
|
|
|
2607
2618
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2608
2619
|
curl = rbce->curl;
|
|
2609
2620
|
|
|
2621
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
2622
|
+
|
|
2610
2623
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb);
|
|
2611
2624
|
|
|
2612
2625
|
retval = rb_funcall(self, rb_intern("perform"), 0);
|
|
@@ -2672,6 +2685,8 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
|
|
|
2672
2685
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2673
2686
|
curl = rbce->curl;
|
|
2674
2687
|
|
|
2688
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
2689
|
+
|
|
2675
2690
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2676
2691
|
|
|
2677
2692
|
if (rbce->multipart_form_post) {
|
|
@@ -2743,6 +2758,8 @@ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
|
|
|
2743
2758
|
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
2744
2759
|
curl = rbce->curl;
|
|
2745
2760
|
|
|
2761
|
+
memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
|
|
2762
|
+
|
|
2746
2763
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
|
|
2747
2764
|
ruby_curl_easy_put_data_set(self, data);
|
|
2748
2765
|
|
|
@@ -2761,6 +2778,10 @@ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
|
|
|
2761
2778
|
* your own body handler, this string will be empty.
|
|
2762
2779
|
*/
|
|
2763
2780
|
static VALUE ruby_curl_easy_body_str_get(VALUE self) {
|
|
2781
|
+
/*
|
|
2782
|
+
TODO: can we force_encoding on the return here if we see charset=utf-8 in the content-type header?
|
|
2783
|
+
Content-Type: application/json; charset=utf-8
|
|
2784
|
+
*/
|
|
2764
2785
|
CURB_OBJECT_HGETTER(ruby_curl_easy, body_data);
|
|
2765
2786
|
}
|
|
2766
2787
|
|
|
@@ -2955,7 +2976,7 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
|
|
|
2955
2976
|
* Retrieve the time, in seconds, it took from the start until the SSL/SSH
|
|
2956
2977
|
* connect/handshake to the remote host was completed. This time is most often
|
|
2957
2978
|
* very near to the pre transfer time, except for cases such as HTTP
|
|
2958
|
-
*
|
|
2979
|
+
* pipelining where the pretransfer time can be delayed due to waits in line
|
|
2959
2980
|
* for the pipeline and more.
|
|
2960
2981
|
*/
|
|
2961
2982
|
#if defined(HAVE_CURLINFO_APPCONNECT_TIME)
|
|
@@ -3448,6 +3469,21 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
|
|
|
3448
3469
|
return LONG2NUM(rbce->last_result);
|
|
3449
3470
|
}
|
|
3450
3471
|
|
|
3472
|
+
/*
|
|
3473
|
+
* call-seq:
|
|
3474
|
+
* easy.last_error => "Error details" or nil
|
|
3475
|
+
*/
|
|
3476
|
+
static VALUE ruby_curl_easy_last_error(VALUE self) {
|
|
3477
|
+
ruby_curl_easy *rbce;
|
|
3478
|
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
|
|
3479
|
+
|
|
3480
|
+
if (rbce->err_buf[0]) { // curl returns NULL or empty string if none
|
|
3481
|
+
return rb_str_new2(rbce->err_buf);
|
|
3482
|
+
} else {
|
|
3483
|
+
return Qnil;
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3451
3487
|
/*
|
|
3452
3488
|
* call-seq:
|
|
3453
3489
|
* easy.setopt Fixnum, value => value
|
|
@@ -3546,6 +3582,9 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3546
3582
|
case CURLOPT_TCP_NODELAY: {
|
|
3547
3583
|
curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
|
|
3548
3584
|
} break;
|
|
3585
|
+
case CURLOPT_RANGE: {
|
|
3586
|
+
curl_easy_setopt(rbce->curl, CURLOPT_RANGE, StringValueCStr(val));
|
|
3587
|
+
} break;
|
|
3549
3588
|
case CURLOPT_RESUME_FROM: {
|
|
3550
3589
|
curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, NUM2LONG(val));
|
|
3551
3590
|
} break;
|
|
@@ -3606,6 +3645,15 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
|
|
|
3606
3645
|
GetOpenFile(val, open_f_ptr);
|
|
3607
3646
|
curl_easy_setopt(rbce->curl, CURLOPT_STDERR, rb_io_stdio_file(open_f_ptr));
|
|
3608
3647
|
break;
|
|
3648
|
+
case CURLOPT_PROTOCOLS:
|
|
3649
|
+
case CURLOPT_REDIR_PROTOCOLS:
|
|
3650
|
+
curl_easy_setopt(rbce->curl, option, NUM2LONG(val));
|
|
3651
|
+
break;
|
|
3652
|
+
#if HAVE_CURLOPT_SSL_SESSIONID_CACHE
|
|
3653
|
+
case CURLOPT_SSL_SESSIONID_CACHE:
|
|
3654
|
+
curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
|
|
3655
|
+
break;
|
|
3656
|
+
#endif
|
|
3609
3657
|
default:
|
|
3610
3658
|
rb_raise(rb_eTypeError, "Curb unsupported option");
|
|
3611
3659
|
}
|
|
@@ -3913,6 +3961,7 @@ void init_curb_easy() {
|
|
|
3913
3961
|
rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
|
|
3914
3962
|
rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
|
|
3915
3963
|
rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
|
|
3964
|
+
rb_define_method(cCurlEasy, "last_error", ruby_curl_easy_last_error, 0);
|
|
3916
3965
|
|
|
3917
3966
|
rb_define_method(cCurlEasy, "setopt", ruby_curl_easy_set_opt, 2);
|
|
3918
3967
|
rb_define_method(cCurlEasy, "getinfo", ruby_curl_easy_get_opt, 1);
|
data/ext/curb_easy.h
CHANGED
|
@@ -36,6 +36,9 @@ typedef struct {
|
|
|
36
36
|
/* The handler */
|
|
37
37
|
CURL *curl;
|
|
38
38
|
|
|
39
|
+
/* Buffer for error details from CURLOPT_ERRORBUFFER */
|
|
40
|
+
char err_buf[CURL_ERROR_SIZE];
|
|
41
|
+
|
|
39
42
|
VALUE opts; /* rather then allocate everything we might need to store, allocate a Hash and only store objects we actually use... */
|
|
40
43
|
VALUE multi; /* keep a multi handle alive for each easy handle not being used by a multi handle. This improves easy performance when not within a multi context */
|
|
41
44
|
|
data/ext/curb_multi.c
CHANGED
|
@@ -64,7 +64,7 @@ static void ruby_curl_multi_init(ruby_curl_multi *rbcm) {
|
|
|
64
64
|
|
|
65
65
|
/*
|
|
66
66
|
* call-seq:
|
|
67
|
-
* Curl::Multi.new =>
|
|
67
|
+
* Curl::Multi.new => #<Curl::Easy...>
|
|
68
68
|
*
|
|
69
69
|
* Create a new Curl::Multi instance
|
|
70
70
|
*/
|
|
@@ -132,7 +132,7 @@ VALUE ruby_curl_multi_get_autoclose(VALUE klass) {
|
|
|
132
132
|
|
|
133
133
|
/*
|
|
134
134
|
* call-seq:
|
|
135
|
-
* multi.requests => [
|
|
135
|
+
* multi.requests => [#<Curl::Easy...>, ...]
|
|
136
136
|
*
|
|
137
137
|
* Returns an array containing all the active requests on this Curl::Multi object.
|
|
138
138
|
*/
|
|
@@ -300,10 +300,14 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
|
300
300
|
rbce->callback_active = 1;
|
|
301
301
|
val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
|
|
302
302
|
rbce->callback_active = 0;
|
|
303
|
-
//rb_funcall( rb_easy_get("complete_proc"), idCall, 1, easy );
|
|
304
303
|
}
|
|
305
304
|
|
|
305
|
+
#ifdef HAVE_CURLINFO_RESPONSE_CODE
|
|
306
306
|
curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &response_code);
|
|
307
|
+
#else
|
|
308
|
+
// old libcurl
|
|
309
|
+
curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CODE, &response_code);
|
|
310
|
+
#endif
|
|
307
311
|
|
|
308
312
|
if (result != 0) {
|
|
309
313
|
if (!rb_easy_nil("failure_proc")) {
|
|
@@ -313,8 +317,7 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
|
313
317
|
rbce->callback_active = 0;
|
|
314
318
|
//rb_funcall( rb_easy_get("failure_proc"), idCall, 2, easy, rb_curl_easy_error(result) );
|
|
315
319
|
}
|
|
316
|
-
}
|
|
317
|
-
else if (!rb_easy_nil("success_proc") &&
|
|
320
|
+
} else if (!rb_easy_nil("success_proc") &&
|
|
318
321
|
((response_code >= 200 && response_code < 300) || response_code == 0)) {
|
|
319
322
|
/* NOTE: we allow response_code == 0, in the case of non http requests e.g. reading from disk */
|
|
320
323
|
callargs = rb_ary_new3(2, rb_easy_get("success_proc"), easy);
|
|
@@ -322,22 +325,19 @@ static void rb_curl_mutli_handle_complete(VALUE self, CURL *easy_handle, int res
|
|
|
322
325
|
val = rb_rescue(call_status_handler1, callargs, callback_exception, Qnil);
|
|
323
326
|
rbce->callback_active = 0;
|
|
324
327
|
//rb_funcall( rb_easy_get("success_proc"), idCall, 1, easy );
|
|
325
|
-
}
|
|
326
|
-
else if (!rb_easy_nil("redirect_proc") &&
|
|
328
|
+
} else if (!rb_easy_nil("redirect_proc") &&
|
|
327
329
|
(response_code >= 300 && response_code < 400)) {
|
|
328
330
|
rbce->callback_active = 1;
|
|
329
331
|
callargs = rb_ary_new3(3, rb_easy_get("redirect_proc"), easy, rb_curl_easy_error(result));
|
|
330
332
|
rbce->callback_active = 0;
|
|
331
333
|
val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
|
|
332
|
-
}
|
|
333
|
-
else if (!rb_easy_nil("missing_proc") &&
|
|
334
|
+
} else if (!rb_easy_nil("missing_proc") &&
|
|
334
335
|
(response_code >= 400 && response_code < 500)) {
|
|
335
336
|
rbce->callback_active = 1;
|
|
336
337
|
callargs = rb_ary_new3(3, rb_easy_get("missing_proc"), easy, rb_curl_easy_error(result));
|
|
337
338
|
rbce->callback_active = 0;
|
|
338
339
|
val = rb_rescue(call_status_handler2, callargs, callback_exception, Qnil);
|
|
339
|
-
}
|
|
340
|
-
else if (!rb_easy_nil("failure_proc") &&
|
|
340
|
+
} else if (!rb_easy_nil("failure_proc") &&
|
|
341
341
|
(response_code >= 500 && response_code <= 999)) {
|
|
342
342
|
callargs = rb_ary_new3(3, rb_easy_get("failure_proc"), easy, rb_curl_easy_error(result));
|
|
343
343
|
rbce->callback_active = 1;
|
data/ext/curb_postfield.c
CHANGED
|
@@ -195,9 +195,9 @@ void curl_postfield_free(ruby_curl_postfield *rbcpf) {
|
|
|
195
195
|
|
|
196
196
|
/*
|
|
197
197
|
* call-seq:
|
|
198
|
-
* Curl::PostField.content(name, content) =>
|
|
199
|
-
* Curl::PostField.content(name, content, content_type = nil) =>
|
|
200
|
-
* Curl::PostField.content(name, content_type = nil) { |field| ... } =>
|
|
198
|
+
* Curl::PostField.content(name, content) => #<Curl::PostField...>
|
|
199
|
+
* Curl::PostField.content(name, content, content_type = nil) => #<Curl::PostField...>
|
|
200
|
+
* Curl::PostField.content(name, content_type = nil) { |field| ... } => #<Curl::PostField...>
|
|
201
201
|
*
|
|
202
202
|
* Create a new Curl::PostField, supplying the field name, content,
|
|
203
203
|
* and, optionally, Content-type (curl will attempt to determine this if
|
|
@@ -241,9 +241,9 @@ static VALUE ruby_curl_postfield_new_content(int argc, VALUE *argv, VALUE klass)
|
|
|
241
241
|
|
|
242
242
|
/*
|
|
243
243
|
* call-seq:
|
|
244
|
-
* Curl::PostField.file(name, local_file_name) =>
|
|
245
|
-
* Curl::PostField.file(name, local_file_name, remote_file_name = local_file_name) =>
|
|
246
|
-
* Curl::PostField.file(name, remote_file_name) { |field| ... } =>
|
|
244
|
+
* Curl::PostField.file(name, local_file_name) => #<Curl::PostField...>
|
|
245
|
+
* Curl::PostField.file(name, local_file_name, remote_file_name = local_file_name) => #<Curl::PostField...>
|
|
246
|
+
* Curl::PostField.file(name, remote_file_name) { |field| ... } => #<Curl::PostField...>
|
|
247
247
|
*
|
|
248
248
|
* Create a new Curl::PostField for a file upload field, supplying the local filename
|
|
249
249
|
* to read from, and optionally the remote filename (defaults to the local name).
|
|
@@ -399,7 +399,7 @@ static VALUE ruby_curl_postfield_remote_file_get(VALUE self) {
|
|
|
399
399
|
|
|
400
400
|
/*
|
|
401
401
|
* call-seq:
|
|
402
|
-
* field.set_content_proc { |field| ... } =>
|
|
402
|
+
* field.set_content_proc { |field| ... } => <old proc>
|
|
403
403
|
*
|
|
404
404
|
* Set a content proc for this field. This proc will be called during the
|
|
405
405
|
* perform to supply the content for this field, overriding any setting
|
data/ext/extconf.rb
CHANGED
|
@@ -18,6 +18,8 @@ elsif !have_library('curl') or !have_header('curl/curl.h')
|
|
|
18
18
|
fail <<-EOM
|
|
19
19
|
Can't find libcurl or curl/curl.h
|
|
20
20
|
|
|
21
|
+
Make sure development libs (ie libcurl4-openssl-dev) are installed on the system.
|
|
22
|
+
|
|
21
23
|
Try passing --with-curl-dir or --with-curl-lib and --with-curl-include
|
|
22
24
|
options to extconf.
|
|
23
25
|
EOM
|
|
@@ -341,6 +343,9 @@ have_constant :CURL_SSLVERSION_TLSv1_0
|
|
|
341
343
|
have_constant :CURL_SSLVERSION_TLSv1_1
|
|
342
344
|
have_constant :CURL_SSLVERSION_TLSv1_2
|
|
343
345
|
|
|
346
|
+
# Added in 7.52.0
|
|
347
|
+
have_constant :CURL_SSLVERSION_TLSv1_3
|
|
348
|
+
|
|
344
349
|
have_constant "curlopt_ssl_verifypeer"
|
|
345
350
|
have_constant "curlopt_cainfo"
|
|
346
351
|
have_constant "curlopt_issuercert"
|
|
@@ -400,6 +405,37 @@ have_constant "curlopt_path_as_is"
|
|
|
400
405
|
# added in 7.43.0
|
|
401
406
|
have_constant "curlopt_pipewait"
|
|
402
407
|
|
|
408
|
+
# protocol constants
|
|
409
|
+
have_constant "curlproto_all"
|
|
410
|
+
have_constant "curlproto_dict"
|
|
411
|
+
have_constant "curlproto_file"
|
|
412
|
+
have_constant "curlproto_ftp"
|
|
413
|
+
have_constant "curlproto_ftps"
|
|
414
|
+
have_constant "curlproto_gopher"
|
|
415
|
+
have_constant "curlproto_http"
|
|
416
|
+
have_constant "curlproto_https"
|
|
417
|
+
have_constant "curlproto_imap"
|
|
418
|
+
have_constant "curlproto_imaps"
|
|
419
|
+
have_constant "curlproto_ldap"
|
|
420
|
+
have_constant "curlproto_ldaps"
|
|
421
|
+
have_constant "curlproto_pop3"
|
|
422
|
+
have_constant "curlproto_pop3s"
|
|
423
|
+
have_constant "curlproto_rtmp"
|
|
424
|
+
have_constant "curlproto_rtmpe"
|
|
425
|
+
have_constant "curlproto_rtmps"
|
|
426
|
+
have_constant "curlproto_rtmpt"
|
|
427
|
+
have_constant "curlproto_rtmpte"
|
|
428
|
+
have_constant "curlproto_rtmpts"
|
|
429
|
+
have_constant "curlproto_rtsp"
|
|
430
|
+
have_constant "curlproto_scp"
|
|
431
|
+
have_constant "curlproto_sftp"
|
|
432
|
+
have_constant "curlproto_smb"
|
|
433
|
+
have_constant "curlproto_smbs"
|
|
434
|
+
have_constant "curlproto_smtp"
|
|
435
|
+
have_constant "curlproto_smtps"
|
|
436
|
+
have_constant "curlproto_telnet"
|
|
437
|
+
have_constant "curlproto_tftp"
|
|
438
|
+
|
|
403
439
|
if try_compile('int main() { return 0; }','-Wall')
|
|
404
440
|
$CFLAGS << ' -Wall'
|
|
405
441
|
end
|
data/lib/curl/easy.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Curl
|
|
|
21
21
|
#
|
|
22
22
|
def status
|
|
23
23
|
# Matches the last HTTP Status - following the HTTP protocol specification 'Status-Line = HTTP-Version SP Status-Code SP (Opt:)Reason-Phrase CRLF'
|
|
24
|
-
statuses = self.header_str.scan(/HTTP\/\d(\.\d)?\s(\d+\s.*)\r\n/).map{
|
|
24
|
+
statuses = self.header_str.to_s.scan(/HTTP\/\d(\.\d)?\s(\d+\s.*)\r\n/).map {|match| match[1] }
|
|
25
25
|
statuses.last.strip if statuses.length > 0
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -75,8 +75,9 @@ module Curl
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
if self.last_result != 0 && self.on_failure.nil?
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
(err_class, err_summary) = Curl::Easy.error(self.last_result)
|
|
79
|
+
err_detail = self.last_error
|
|
80
|
+
raise err_class.new([err_summary, err_detail].compact.join(": "))
|
|
80
81
|
end
|
|
81
82
|
|
|
82
83
|
ret
|
|
@@ -320,7 +321,7 @@ module Curl
|
|
|
320
321
|
|
|
321
322
|
#
|
|
322
323
|
# call-seq:
|
|
323
|
-
# Curl::Easy.perform(url) { |easy| ... } =>
|
|
324
|
+
# Curl::Easy.perform(url) { |easy| ... } => #<Curl::Easy...>
|
|
324
325
|
#
|
|
325
326
|
# Convenience method that creates a new Curl::Easy instance with
|
|
326
327
|
# the specified URL and calls the general +perform+ method, before returning
|
|
@@ -338,7 +339,7 @@ module Curl
|
|
|
338
339
|
|
|
339
340
|
#
|
|
340
341
|
# call-seq:
|
|
341
|
-
# Curl::Easy.http_get(url) { |easy| ... } =>
|
|
342
|
+
# Curl::Easy.http_get(url) { |easy| ... } => #<Curl::Easy...>
|
|
342
343
|
#
|
|
343
344
|
# Convenience method that creates a new Curl::Easy instance with
|
|
344
345
|
# the specified URL and calls +http_get+, before returning the new instance.
|
|
@@ -355,7 +356,7 @@ module Curl
|
|
|
355
356
|
|
|
356
357
|
#
|
|
357
358
|
# call-seq:
|
|
358
|
-
# Curl::Easy.http_head(url) { |easy| ... } =>
|
|
359
|
+
# Curl::Easy.http_head(url) { |easy| ... } => #<Curl::Easy...>
|
|
359
360
|
#
|
|
360
361
|
# Convenience method that creates a new Curl::Easy instance with
|
|
361
362
|
# the specified URL and calls +http_head+, before returning the new instance.
|
|
@@ -409,7 +410,7 @@ module Curl
|
|
|
409
410
|
|
|
410
411
|
#
|
|
411
412
|
# call-seq:
|
|
412
|
-
# Curl::Easy.http_delete(url) { |easy| ... } =>
|
|
413
|
+
# Curl::Easy.http_delete(url) { |easy| ... } => #<Curl::Easy...>
|
|
413
414
|
#
|
|
414
415
|
# Convenience method that creates a new Curl::Easy instance with
|
|
415
416
|
# the specified URL and calls +http_delete+, before returning the new instance.
|
data/lib/curl.rb
CHANGED
|
@@ -9,12 +9,20 @@ require 'cgi'
|
|
|
9
9
|
module Curl
|
|
10
10
|
|
|
11
11
|
def self.http(verb, url, post_body=nil, put_data=nil, &block)
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
if Thread.current[:curb_curl_yielding]
|
|
13
|
+
handle = Curl::Easy.new # we can't reuse this
|
|
14
|
+
else
|
|
15
|
+
handle = Thread.current[:curb_curl] ||= Curl::Easy.new
|
|
16
|
+
handle.reset
|
|
17
|
+
end
|
|
14
18
|
handle.url = url
|
|
15
19
|
handle.post_body = post_body if post_body
|
|
16
20
|
handle.put_data = put_data if put_data
|
|
17
|
-
|
|
21
|
+
if block_given?
|
|
22
|
+
Thread.current[:curb_curl_yielding] = true
|
|
23
|
+
yield handle
|
|
24
|
+
Thread.current[:curb_curl_yielding] = false
|
|
25
|
+
end
|
|
18
26
|
handle.http(verb)
|
|
19
27
|
handle
|
|
20
28
|
end
|
data/tests/helper.rb
CHANGED
|
@@ -143,7 +143,6 @@ module TestServerMethods
|
|
|
143
143
|
def server_setup(port=9129,servlet=TestServlet)
|
|
144
144
|
@__port = port
|
|
145
145
|
if (@server ||= nil).nil? and !File.exist?(locked_file)
|
|
146
|
-
|
|
147
146
|
File.open(locked_file,'w') {|f| f << 'locked' }
|
|
148
147
|
if TEST_SINGLE_THREADED
|
|
149
148
|
rd, wr = IO.pipe
|
data/tests/tc_curl_easy.rb
CHANGED
|
@@ -10,6 +10,14 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
|
10
10
|
Curl.reset
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
def test_nested_easy_methods
|
|
14
|
+
easy = Curl.get(TestServlet.url) {|http|
|
|
15
|
+
res = Curl.get(TestServlet.url + '/not_here')
|
|
16
|
+
assert_equal 404, res.response_code
|
|
17
|
+
}
|
|
18
|
+
assert_equal 200, easy.response_code
|
|
19
|
+
end
|
|
20
|
+
|
|
13
21
|
def test_curlopt_stderr_with_file
|
|
14
22
|
# does not work with Tempfile directly
|
|
15
23
|
path = Tempfile.new('curb_test_curlopt_stderr').path
|
|
@@ -21,7 +29,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
|
|
|
21
29
|
end
|
|
22
30
|
output = File.read(path)
|
|
23
31
|
|
|
24
|
-
assert_match(
|
|
32
|
+
assert_match(/HTTP\/1\.1\ 200\ OK(?:\ )?/, output)
|
|
25
33
|
assert_match('Host: 127.0.0.1:9129', output)
|
|
26
34
|
end
|
|
27
35
|
|
data/tests/tc_curl_multi.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
+
require 'set'
|
|
2
3
|
|
|
3
4
|
class TestCurbCurlMulti < Test::Unit::TestCase
|
|
4
5
|
def teardown
|
|
@@ -9,20 +10,58 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
9
10
|
# for https://github.com/taf2/curb/issues/277
|
|
10
11
|
# must connect to an external
|
|
11
12
|
def test_connection_keepalive
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
# this test fails with libcurl 7.22.0. I didn't investigate, but it may be related
|
|
14
|
+
# to CURLOPT_MAXCONNECTS bug fixed in 7.30.0:
|
|
15
|
+
# https://github.com/curl/curl/commit/e87e76e2dc108efb1cae87df496416f49c55fca0
|
|
16
|
+
omit("Skip, libcurl too old (< 7.22.0)") if Curl::CURL_VERSION.split('.')[1].to_i <= 22
|
|
17
|
+
|
|
18
|
+
@server.shutdown if @server
|
|
19
|
+
@test_thread.kill if @test_thread
|
|
20
|
+
@server = nil
|
|
21
|
+
File.unlink(locked_file)
|
|
22
|
+
Curl::Multi.autoclose = true
|
|
23
|
+
assert Curl::Multi.autoclose
|
|
24
|
+
# XXX: thought maybe we can clean house here to have the full suite pass in osx... but for now running this test in isolate does pass
|
|
25
|
+
# additionally, if ss allows this to pass on linux without requesting google i think this is a good trade off... leaving some of the thoughts below
|
|
26
|
+
# in hopes that coming back to this later will find it and remember how to fix it
|
|
27
|
+
# types = Set.new
|
|
28
|
+
# close_types = Set.new([TCPServer,TCPSocket,Socket,Curl::Multi, Curl::Easy,WEBrick::Log])
|
|
29
|
+
# ObjectSpace.each_object {|o|
|
|
30
|
+
# if o.respond_to?(:close)
|
|
31
|
+
# types << o.class
|
|
32
|
+
# end
|
|
33
|
+
# if close_types.include?(o.class)
|
|
34
|
+
# o.close
|
|
35
|
+
# end
|
|
36
|
+
# }
|
|
37
|
+
#puts "unique types: #{types.to_a.join("\n")}"
|
|
38
|
+
GC.start # cleanup FDs left over from other tests
|
|
39
|
+
server_setup
|
|
40
|
+
GC.start # cleanup FDs left over from other tests
|
|
41
|
+
|
|
42
|
+
if `which ss`.strip.size == 0
|
|
43
|
+
# osx need lsof still :(
|
|
44
|
+
open_fds = lambda do
|
|
45
|
+
out = `/usr/sbin/lsof -p #{Process.pid} | egrep "TCP|UDP"`# | egrep ':#{TestServlet.port} ' | egrep ESTABLISHED`# | wc -l`.strip.to_i
|
|
46
|
+
#puts out.lines.join("\n")
|
|
47
|
+
out.lines.size
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
ss = `which ss`.strip
|
|
51
|
+
open_fds = lambda do
|
|
52
|
+
`#{ss} -n4 state established dport = :#{TestServlet.port} | wc -l`.strip.to_i
|
|
53
|
+
end
|
|
16
54
|
end
|
|
55
|
+
Curl::Multi.autoclose = false
|
|
17
56
|
before_open = open_fds.call
|
|
57
|
+
#puts "before_open: #{before_open.inspect}"
|
|
18
58
|
assert !Curl::Multi.autoclose
|
|
19
59
|
multi = Curl::Multi.new
|
|
20
60
|
multi.max_connects = 1 # limit to 1 connection within the multi handle
|
|
21
61
|
|
|
22
62
|
did_complete = false
|
|
23
63
|
5.times do |n|
|
|
24
|
-
|
|
25
|
-
easy = Curl::Easy.new("http://google.com/") do |curl|
|
|
64
|
+
easy = Curl::Easy.new(TestServlet.url) do |curl|
|
|
26
65
|
curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
|
|
27
66
|
curl.on_complete {
|
|
28
67
|
did_complete = true
|
|
@@ -34,18 +73,19 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
34
73
|
multi.perform
|
|
35
74
|
assert did_complete
|
|
36
75
|
after_open = open_fds.call
|
|
37
|
-
|
|
76
|
+
#puts "after_open: #{after_open} before_open: #{before_open.inspect}"
|
|
77
|
+
assert_equal 1, (after_open - before_open), "with max connections set to 1 at this point the connection to google should still be open"
|
|
38
78
|
multi.close
|
|
39
79
|
|
|
40
80
|
after_open = open_fds.call
|
|
41
|
-
|
|
81
|
+
#puts "after_open: #{after_open} before_open: #{before_open.inspect}"
|
|
82
|
+
assert_equal 0, (after_open - before_open), "after closing the multi handle all connections should be closed"
|
|
42
83
|
|
|
43
84
|
Curl::Multi.autoclose = true
|
|
44
85
|
multi = Curl::Multi.new
|
|
45
86
|
did_complete = false
|
|
46
87
|
5.times do |n|
|
|
47
|
-
|
|
48
|
-
easy = Curl::Easy.new("http://google.com/") do |curl|
|
|
88
|
+
easy = Curl::Easy.new(TestServlet.url) do |curl|
|
|
49
89
|
curl.timeout = 5 # ensure we don't hang for ever connecting to an external host
|
|
50
90
|
curl.on_complete {
|
|
51
91
|
did_complete = true
|
|
@@ -57,7 +97,8 @@ class TestCurbCurlMulti < Test::Unit::TestCase
|
|
|
57
97
|
multi.perform
|
|
58
98
|
assert did_complete
|
|
59
99
|
after_open = open_fds.call
|
|
60
|
-
|
|
100
|
+
#puts "after_open: #{after_open} before_open: #{before_open.inspect}"
|
|
101
|
+
assert_equal 0, (after_open - before_open), "auto close the connections"
|
|
61
102
|
ensure
|
|
62
103
|
Curl::Multi.autoclose = false # restore default
|
|
63
104
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class TestCurbCurlProtocols < Test::Unit::TestCase
|
|
2
|
+
include TestServerMethods
|
|
3
|
+
|
|
4
|
+
def setup
|
|
5
|
+
@easy = Curl::Easy.new
|
|
6
|
+
@easy.set :protocols, Curl::CURLPROTO_HTTP | Curl::CURLPROTO_HTTPS
|
|
7
|
+
@easy.follow_location = true
|
|
8
|
+
server_setup
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_protocol_allowed
|
|
12
|
+
@easy.set :url, "http://127.0.0.1:9129/this_file_does_not_exist.html"
|
|
13
|
+
@easy.perform
|
|
14
|
+
assert_equal 404, @easy.response_code
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_protocol_denied
|
|
18
|
+
@easy.set :url, "gopher://google.com/"
|
|
19
|
+
assert_raises Curl::Err::UnsupportedProtocolError do
|
|
20
|
+
@easy.perform
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_redir_protocol_allowed
|
|
25
|
+
@easy.set :url, TestServlet.url + "/redirect"
|
|
26
|
+
@easy.set :redir_protocols, Curl::CURLPROTO_HTTP
|
|
27
|
+
@easy.perform
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_redir_protocol_denied
|
|
31
|
+
@easy.set :url, TestServlet.url + "/redirect"
|
|
32
|
+
@easy.set :redir_protocols, Curl::CURLPROTO_HTTPS
|
|
33
|
+
assert_raises Curl::Err::UnsupportedProtocolError do
|
|
34
|
+
@easy.perform
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/tests/timeout.rb
CHANGED
|
@@ -17,9 +17,13 @@ class TestCurbTimeouts < Test::Unit::TestCase
|
|
|
17
17
|
def test_overall_timeout_on_dead_transfer
|
|
18
18
|
curl = Curl::Easy.new(wait_url(2))
|
|
19
19
|
curl.timeout = 1
|
|
20
|
-
assert_raise(Curl::Err::TimeoutError) do
|
|
20
|
+
exception = assert_raise(Curl::Err::TimeoutError) do
|
|
21
21
|
curl.http_get
|
|
22
22
|
end
|
|
23
|
+
assert_match(
|
|
24
|
+
/^Timeout was reached: Operation timed out after/,
|
|
25
|
+
exception.message
|
|
26
|
+
)
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
def test_overall_timeout_ms_on_dead_transfer
|
|
@@ -44,16 +48,20 @@ class TestCurbTimeouts < Test::Unit::TestCase
|
|
|
44
48
|
curl = Curl::Easy.new(serve_url(100, 2, 3))
|
|
45
49
|
curl.timeout = 1
|
|
46
50
|
# transfer is aborted despite data being exchanged
|
|
47
|
-
assert_raise(Curl::Err::TimeoutError) do
|
|
51
|
+
exception = assert_raise(Curl::Err::TimeoutError) do
|
|
48
52
|
curl.http_get
|
|
49
53
|
end
|
|
54
|
+
assert_match(
|
|
55
|
+
/^Timeout was reached: Operation timed out after/,
|
|
56
|
+
exception.message
|
|
57
|
+
)
|
|
50
58
|
end
|
|
51
59
|
|
|
52
60
|
def test_low_speed_time_on_slow_transfer
|
|
53
61
|
curl = Curl::Easy.new(serve_url(100, 1, 3))
|
|
54
62
|
curl.low_speed_time = 2
|
|
55
63
|
# use default low_speed_limit of 1
|
|
56
|
-
|
|
64
|
+
assert_equal true, curl.http_get
|
|
57
65
|
end
|
|
58
66
|
|
|
59
67
|
def test_low_speed_time_on_very_slow_transfer
|
|
@@ -63,18 +71,26 @@ class TestCurbTimeouts < Test::Unit::TestCase
|
|
|
63
71
|
# XXX for some reason this test fails if low speed limit is not specified
|
|
64
72
|
curl.low_speed_limit = 1
|
|
65
73
|
# use default low_speed_limit of 1
|
|
66
|
-
assert_raise(Curl::Err::TimeoutError) do
|
|
74
|
+
exception = assert_raise(Curl::Err::TimeoutError) do
|
|
67
75
|
curl.http_get
|
|
68
76
|
end
|
|
77
|
+
assert_match(
|
|
78
|
+
/^Timeout was reached: Operation too slow/,
|
|
79
|
+
exception.message
|
|
80
|
+
)
|
|
69
81
|
end
|
|
70
82
|
|
|
71
83
|
def test_low_speed_limit_on_slow_transfer
|
|
72
84
|
curl = Curl::Easy.new(serve_url(10, 1, 3))
|
|
73
85
|
curl.low_speed_time = 2
|
|
74
86
|
curl.low_speed_limit = 1000
|
|
75
|
-
assert_raise(Curl::Err::TimeoutError) do
|
|
87
|
+
exception = assert_raise(Curl::Err::TimeoutError) do
|
|
76
88
|
curl.http_get
|
|
77
89
|
end
|
|
90
|
+
assert_match(
|
|
91
|
+
/^Timeout was reached: Operation too slow/,
|
|
92
|
+
exception.message
|
|
93
|
+
)
|
|
78
94
|
end
|
|
79
95
|
|
|
80
96
|
def test_clearing_low_speed_time
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: curb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ross Bamford
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
|
13
13
|
dependencies: []
|
|
14
14
|
description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings
|
|
15
15
|
for the libcurl(3), a fully-featured client-side URL transfer library. cURL and
|
|
@@ -70,6 +70,7 @@ files:
|
|
|
70
70
|
- tests/tc_curl_maxfilesize.rb
|
|
71
71
|
- tests/tc_curl_multi.rb
|
|
72
72
|
- tests/tc_curl_postfield.rb
|
|
73
|
+
- tests/tc_curl_protocols.rb
|
|
73
74
|
- tests/timeout.rb
|
|
74
75
|
- tests/timeout_server.rb
|
|
75
76
|
- tests/unittests.rb
|
|
@@ -95,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
95
96
|
- !ruby/object:Gem::Version
|
|
96
97
|
version: '0'
|
|
97
98
|
requirements: []
|
|
98
|
-
rubygems_version: 3.
|
|
99
|
+
rubygems_version: 3.1.4
|
|
99
100
|
signing_key:
|
|
100
101
|
specification_version: 4
|
|
101
102
|
summary: Ruby libcurl bindings
|
|
@@ -113,6 +114,7 @@ test_files:
|
|
|
113
114
|
- tests/timeout.rb
|
|
114
115
|
- tests/bug_crash_on_debug.rb
|
|
115
116
|
- tests/unittests.rb
|
|
117
|
+
- tests/tc_curl_protocols.rb
|
|
116
118
|
- tests/bug_issue102.rb
|
|
117
119
|
- tests/bug_curb_easy_blocks_ruby_threads.rb
|
|
118
120
|
- tests/bug_multi_segfault.rb
|