curb 0.9.11 → 1.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ecd73a0ad8d98960321b8d523e25bad95ff25e8900e8acb187051ca40c7a1cba
4
- data.tar.gz: c154996d92946fe83fa12d695b073d5026e4a55e92efd177bfad021461f2b313
3
+ metadata.gz: dce5f49b09bacccf705e3d25ba29031dd4fc82c2721860eef02bb4a8af2dd0e2
4
+ data.tar.gz: 9456ed69688f2236bdd17f338e26faaf46b91f0fd4e51b3a48d5551ff8fdc433
5
5
  SHA512:
6
- metadata.gz: 48854a4f0d77befe0e81b31a3d39e826b2ef65d58d0226b617a355ba8d063ab4998853a8709ae6d2e3c4629c09ff987099398a1c884b76d95dcf956d941fc660
7
- data.tar.gz: 3291675a74eb40f42d936bb65689da7d5f295e038ed019482d2cf115ba878232ce4e40aeb125d0fe786b5e82428320938ff3c75592a5c54a2d51fbe8589a0931
6
+ metadata.gz: df6ab81576ef567878331724c1600c59ff923be34d3a71bd31d07e4999880743e73c31a502bab8aaece54099fd5142bf954dbf004fffd38f0e6698750e3f9682
7
+ data.tar.gz: 5b7b867979da88d328e9f71a4a6eb7183430de26902311cb8678b443a6c53cf50aa62952f277bc2c2821bafc2af48c0e28067f7dce512ff7c2912b195bc27ad5
data/README.markdown CHANGED
@@ -67,6 +67,12 @@ expand on the above instructions, please report the issue at http://github.com/t
67
67
 
68
68
  On Ubuntu, the dependencies can be satisfied by installing the following packages:
69
69
 
70
+ 18.04 and onwards
71
+
72
+ $ sudo apt-get install libcurl4 libcurl3-gnutls libcurl4-openssl-dev
73
+
74
+ < 18.04
75
+
70
76
  $ sudo apt-get install libcurl3 libcurl3-gnutls libcurl4-openssl-dev
71
77
 
72
78
  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
- Dir.chdir('ext') do
61
- shell('ruby', 'extconf.rb', ENV['EXTCONF_OPTS'].to_s, live_stdout: STDOUT)
62
- end
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
- Dir.chdir('ext') do
67
- pid = system("#{MAKECMD} #{MAKEOPTS} #{target}")
68
- $?.exitstatus
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
- m = make
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
- m = make 'install'
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
@@ -292,18 +292,26 @@ void Init_curb_core() {
292
292
  #endif
293
293
 
294
294
  #ifdef CURL_VERSION_SSL
295
- rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", LONG2NUM(CURL_SSLVERSION_DEFAULT));
295
+ rb_define_const(mCurl, "CURL_SSLVERSION_DEFAULT", LONG2NUM(CURL_SSLVERSION_DEFAULT));
296
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_DEFAULT", LONG2NUM(CURL_SSLVERSION_MAX_DEFAULT));
296
297
  rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1", LONG2NUM(CURL_SSLVERSION_TLSv1));
297
298
  rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", LONG2NUM(CURL_SSLVERSION_SSLv2));
298
299
  rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", LONG2NUM(CURL_SSLVERSION_SSLv3));
299
300
  #if HAVE_CURL_SSLVERSION_TLSV1_0
300
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(CURL_SSLVERSION_TLSv1_0));
301
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(CURL_SSLVERSION_TLSv1_0));
302
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_0", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_0));
301
303
  #endif
302
304
  #if HAVE_CURL_SSLVERSION_TLSV1_1
303
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(CURL_SSLVERSION_TLSv1_1));
305
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(CURL_SSLVERSION_TLSv1_1));
306
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_1", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_1));
304
307
  #endif
305
308
  #if HAVE_CURL_SSLVERSION_TLSV1_2
306
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(CURL_SSLVERSION_TLSv1_2));
309
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(CURL_SSLVERSION_TLSv1_2));
310
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_2", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_2));
311
+ #endif
312
+ #if HAVE_CURL_SSLVERSION_TLSV1_3
313
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_3", LONG2NUM(CURL_SSLVERSION_TLSv1_3));
314
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_3", LONG2NUM(CURL_SSLVERSION_MAX_TLSv1_3));
307
315
  #endif
308
316
 
309
317
  rb_define_const(mCurl, "CURL_USESSL_CONTROL", LONG2NUM(CURB_FTPSSL_CONTROL));
@@ -316,13 +324,20 @@ void Init_curb_core() {
316
324
  rb_define_const(mCurl, "CURL_SSLVERSION_SSLv2", LONG2NUM(-1));
317
325
  rb_define_const(mCurl, "CURL_SSLVERSION_SSLv3", LONG2NUM(-1));
318
326
  #if HAVE_CURL_SSLVERSION_TLSv1_0
319
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(-1));
327
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_0", LONG2NUM(-1));
328
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_0", LONG2NUM(-1));
320
329
  #endif
321
330
  #if HAVE_CURL_SSLVERSION_TLSv1_1
322
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(-1));
331
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_1", LONG2NUM(-1));
332
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_1", LONG2NUM(-1));
323
333
  #endif
324
334
  #if HAVE_CURL_SSLVERSION_TLSv1_2
325
- rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(-1));
335
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_2", LONG2NUM(-1));
336
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_2", LONG2NUM(-1));
337
+ #endif
338
+ #if HAVE_CURL_SSLVERSION_TLSv1_3
339
+ rb_define_const(mCurl, "CURL_SSLVERSION_TLSv1_3", LONG2NUM(-1));
340
+ rb_define_const(mCurl, "CURL_SSLVERSION_MAX_TLSv1_3", LONG2NUM(-1));
326
341
  #endif
327
342
 
328
343
  rb_define_const(mCurl, "CURL_USESSL_CONTROL", LONG2NUM(-1));
@@ -925,12 +940,19 @@ void Init_curb_core() {
925
940
  #endif
926
941
  #if HAVE_CURL_SSLVERSION_TLSv1_0
927
942
  CURB_DEFINE(CURL_SSLVERSION_TLSv1_0);
943
+ CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_0);
928
944
  #endif
929
945
  #if HAVE_CURL_SSLVERSION_TLSv1_1
930
946
  CURB_DEFINE(CURL_SSLVERSION_TLSv1_1);
947
+ CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_1);
931
948
  #endif
932
949
  #if HAVE_CURL_SSLVERSION_TLSv1_2
933
950
  CURB_DEFINE(CURL_SSLVERSION_TLSv1_2);
951
+ CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_2);
952
+ #endif
953
+ #if HAVE_CURL_SSLVERSION_TLSv1_3
954
+ CURB_DEFINE(CURL_SSLVERSION_TLSv1_3);
955
+ CURB_DEFINE(CURL_SSLVERSION_MAX_TLSv1_3);
934
956
  #endif
935
957
  #if HAVE_CURLOPT_SSL_VERIFYPEER
936
958
  CURB_DEFINE(CURLOPT_SSL_VERIFYPEER);
@@ -1050,6 +1072,122 @@ void Init_curb_core() {
1050
1072
  CURB_DEFINE(CURLOPT_HAPROXYPROTOCOL);
1051
1073
  #endif
1052
1074
 
1075
+ #if HAVE_CURLPROTO_RTMPTE
1076
+ CURB_DEFINE(CURLPROTO_RTMPTE);
1077
+ #endif
1078
+
1079
+ #if HAVE_CURLPROTO_RTMPTS
1080
+ CURB_DEFINE(CURLPROTO_RTMPTS);
1081
+ #endif
1082
+
1083
+ #if HAVE_CURLPROTO_SMBS
1084
+ CURB_DEFINE(CURLPROTO_SMBS);
1085
+ #endif
1086
+
1087
+ #if HAVE_CURLPROTO_LDAP
1088
+ CURB_DEFINE(CURLPROTO_LDAP);
1089
+ #endif
1090
+
1091
+ #if HAVE_CURLPROTO_FTP
1092
+ CURB_DEFINE(CURLPROTO_FTP);
1093
+ #endif
1094
+
1095
+ #if HAVE_CURLPROTO_SMTPS
1096
+ CURB_DEFINE(CURLPROTO_SMTPS);
1097
+ #endif
1098
+
1099
+ #if HAVE_CURLPROTO_HTTP
1100
+ CURB_DEFINE(CURLPROTO_HTTP);
1101
+ #endif
1102
+
1103
+ #if HAVE_CURLPROTO_SMTP
1104
+ CURB_DEFINE(CURLPROTO_SMTP);
1105
+ #endif
1106
+
1107
+ #if HAVE_CURLPROTO_TFTP
1108
+ CURB_DEFINE(CURLPROTO_TFTP);
1109
+ #endif
1110
+
1111
+ #if HAVE_CURLPROTO_LDAPS
1112
+ CURB_DEFINE(CURLPROTO_LDAPS);
1113
+ #endif
1114
+
1115
+ #if HAVE_CURLPROTO_IMAPS
1116
+ CURB_DEFINE(CURLPROTO_IMAPS);
1117
+ #endif
1118
+
1119
+ #if HAVE_CURLPROTO_SCP
1120
+ CURB_DEFINE(CURLPROTO_SCP);
1121
+ #endif
1122
+
1123
+ #if HAVE_CURLPROTO_SFTP
1124
+ CURB_DEFINE(CURLPROTO_SFTP);
1125
+ #endif
1126
+
1127
+ #if HAVE_CURLPROTO_TELNET
1128
+ CURB_DEFINE(CURLPROTO_TELNET);
1129
+ #endif
1130
+
1131
+ #if HAVE_CURLPROTO_FILE
1132
+ CURB_DEFINE(CURLPROTO_FILE);
1133
+ #endif
1134
+
1135
+ #if HAVE_CURLPROTO_FTPS
1136
+ CURB_DEFINE(CURLPROTO_FTPS);
1137
+ #endif
1138
+
1139
+ #if HAVE_CURLPROTO_HTTPS
1140
+ CURB_DEFINE(CURLPROTO_HTTPS);
1141
+ #endif
1142
+
1143
+ #if HAVE_CURLPROTO_IMAP
1144
+ CURB_DEFINE(CURLPROTO_IMAP);
1145
+ #endif
1146
+
1147
+ #if HAVE_CURLPROTO_POP3
1148
+ CURB_DEFINE(CURLPROTO_POP3);
1149
+ #endif
1150
+
1151
+ #if HAVE_CURLPROTO_GOPHER
1152
+ CURB_DEFINE(CURLPROTO_GOPHER);
1153
+ #endif
1154
+
1155
+ #if HAVE_CURLPROTO_DICT
1156
+ CURB_DEFINE(CURLPROTO_DICT);
1157
+ #endif
1158
+
1159
+ #if HAVE_CURLPROTO_SMB
1160
+ CURB_DEFINE(CURLPROTO_SMB);
1161
+ #endif
1162
+
1163
+ #if HAVE_CURLPROTO_RTMP
1164
+ CURB_DEFINE(CURLPROTO_RTMP);
1165
+ #endif
1166
+
1167
+ #if HAVE_CURLPROTO_ALL
1168
+ CURB_DEFINE(CURLPROTO_ALL);
1169
+ #endif
1170
+
1171
+ #if HAVE_CURLPROTO_RTMPE
1172
+ CURB_DEFINE(CURLPROTO_RTMPE);
1173
+ #endif
1174
+
1175
+ #if HAVE_CURLPROTO_RTMPS
1176
+ CURB_DEFINE(CURLPROTO_RTMPS);
1177
+ #endif
1178
+
1179
+ #if HAVE_CURLPROTO_RTMPT
1180
+ CURB_DEFINE(CURLPROTO_RTMPT);
1181
+ #endif
1182
+
1183
+ #if HAVE_CURLPROTO_POP3S
1184
+ CURB_DEFINE(CURLPROTO_POP3S);
1185
+ #endif
1186
+
1187
+ #if HAVE_CURLPROTO_RTSP
1188
+ CURB_DEFINE(CURLPROTO_RTSP);
1189
+ #endif
1190
+
1053
1191
  #if LIBCURL_VERSION_NUM >= 0x072B00 /* 7.43.0 */
1054
1192
  CURB_DEFINE(CURLPIPE_NOTHING);
1055
1193
  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.9.11"
32
- #define CURB_VER_NUM 9011
33
- #define CURB_VER_MAJ 0
34
- #define CURB_VER_MIN 9
35
- #define CURB_VER_MIC 11
31
+ #define CURB_VERSION "1.0.0"
32
+ #define CURB_VER_NUM 1000
33
+ #define CURB_VER_MAJ 1
34
+ #define CURB_VER_MIN 0
35
+ #define CURB_VER_MIC 0
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;
@@ -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
- rb_easy_set("url", url);
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);
@@ -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
- /* rest clobbers the private setting, so reset it to self */
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);
@@ -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);
@@ -2607,6 +2615,8 @@ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
2607
2615
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2608
2616
  curl = rbce->curl;
2609
2617
 
2618
+ memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
2619
+
2610
2620
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb);
2611
2621
 
2612
2622
  retval = rb_funcall(self, rb_intern("perform"), 0);
@@ -2672,6 +2682,8 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
2672
2682
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2673
2683
  curl = rbce->curl;
2674
2684
 
2685
+ memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
2686
+
2675
2687
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
2676
2688
 
2677
2689
  if (rbce->multipart_form_post) {
@@ -2743,6 +2755,8 @@ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
2743
2755
  Data_Get_Struct(self, ruby_curl_easy, rbce);
2744
2756
  curl = rbce->curl;
2745
2757
 
2758
+ memset(rbce->err_buf, 0, sizeof(rbce->err_buf));
2759
+
2746
2760
  curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
2747
2761
  ruby_curl_easy_put_data_set(self, data);
2748
2762
 
@@ -2955,7 +2969,7 @@ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
2955
2969
  * Retrieve the time, in seconds, it took from the start until the SSL/SSH
2956
2970
  * connect/handshake to the remote host was completed. This time is most often
2957
2971
  * very near to the pre transfer time, except for cases such as HTTP
2958
- * pippelining where the pretransfer time can be delayed due to waits in line
2972
+ * pipelining where the pretransfer time can be delayed due to waits in line
2959
2973
  * for the pipeline and more.
2960
2974
  */
2961
2975
  #if defined(HAVE_CURLINFO_APPCONNECT_TIME)
@@ -3448,6 +3462,21 @@ static VALUE ruby_curl_easy_last_result(VALUE self) {
3448
3462
  return LONG2NUM(rbce->last_result);
3449
3463
  }
3450
3464
 
3465
+ /*
3466
+ * call-seq:
3467
+ * easy.last_error => "Error details" or nil
3468
+ */
3469
+ static VALUE ruby_curl_easy_last_error(VALUE self) {
3470
+ ruby_curl_easy *rbce;
3471
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3472
+
3473
+ if (rbce->err_buf[0]) { // curl returns NULL or empty string if none
3474
+ return rb_str_new2(rbce->err_buf);
3475
+ } else {
3476
+ return Qnil;
3477
+ }
3478
+ }
3479
+
3451
3480
  /*
3452
3481
  * call-seq:
3453
3482
  * easy.setopt Fixnum, value => value
@@ -3546,6 +3575,9 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3546
3575
  case CURLOPT_TCP_NODELAY: {
3547
3576
  curl_easy_setopt(rbce->curl, CURLOPT_TCP_NODELAY, NUM2LONG(val));
3548
3577
  } break;
3578
+ case CURLOPT_RANGE: {
3579
+ curl_easy_setopt(rbce->curl, CURLOPT_RANGE, StringValueCStr(val));
3580
+ } break;
3549
3581
  case CURLOPT_RESUME_FROM: {
3550
3582
  curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, NUM2LONG(val));
3551
3583
  } break;
@@ -3606,6 +3638,15 @@ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3606
3638
  GetOpenFile(val, open_f_ptr);
3607
3639
  curl_easy_setopt(rbce->curl, CURLOPT_STDERR, rb_io_stdio_file(open_f_ptr));
3608
3640
  break;
3641
+ case CURLOPT_PROTOCOLS:
3642
+ case CURLOPT_REDIR_PROTOCOLS:
3643
+ curl_easy_setopt(rbce->curl, option, NUM2LONG(val));
3644
+ break;
3645
+ #if HAVE_CURLOPT_SSL_SESSIONID_CACHE
3646
+ case CURLOPT_SSL_SESSIONID_CACHE:
3647
+ curl_easy_setopt(rbce->curl, CURLOPT_SSL_SESSIONID_CACHE, NUM2LONG(val));
3648
+ break;
3649
+ #endif
3609
3650
  default:
3610
3651
  rb_raise(rb_eTypeError, "Curb unsupported option");
3611
3652
  }
@@ -3913,6 +3954,7 @@ void init_curb_easy() {
3913
3954
  rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
3914
3955
  rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
3915
3956
  rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
3957
+ rb_define_method(cCurlEasy, "last_error", ruby_curl_easy_last_error, 0);
3916
3958
 
3917
3959
  rb_define_method(cCurlEasy, "setopt", ruby_curl_easy_set_opt, 2);
3918
3960
  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/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
@@ -75,8 +75,9 @@ module Curl
75
75
  end
76
76
 
77
77
  if self.last_result != 0 && self.on_failure.nil?
78
- error = Curl::Easy.error(self.last_result)
79
- raise error.first.new(self.head)
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
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
@@ -21,7 +21,7 @@ class TestCurbCurlEasy < Test::Unit::TestCase
21
21
  end
22
22
  output = File.read(path)
23
23
 
24
- assert_match('HTTP/1.1 200 OK ', output)
24
+ assert_match(/HTTP\/1\.1\ 200\ OK(?:\ )?/, output)
25
25
  assert_match('Host: 127.0.0.1:9129', output)
26
26
  end
27
27
 
@@ -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
- # 0123456 default & reserved RubyVM. It will probably include 7 from Dir.glob
13
- lsof=`/usr/bin/which lsof`.strip
14
- open_fds = lambda do
15
- `#{lsof} -p #{Process.pid} | egrep "TCP|UDP" | wc -l`.strip.to_i
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
- # NOTE: we use google here because connecting to our TEST_URL as a local host address appears to not register correctly with lsof as a socket... if anyone knows a better way would be great to not have an external dependency here in the test
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
- assert_equal (after_open - before_open), 1, "with max connections set to 1 at this point the connection to google should still be open"
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
- assert_equal (after_open - before_open), 0, "after closing the multi handle all connections should be closed"
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
- # NOTE: we use google here because connecting to our TEST_URL as a local host address appears to not register correctly with lsof as a socket... if anyone knows a better way would be great to not have an external dependency here in the test
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
- assert_equal (after_open - before_open), 0, "auto close the connections"
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
- assert true, curl.http_get
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,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.11
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Bamford
8
8
  - Todd A. Fisher
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-11-02 00:00:00.000000000 Z
12
+ date: 2022-01-14 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
@@ -52,7 +52,6 @@ files:
52
52
  - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
53
53
  - tests/bug_instance_post_differs_from_class_post.rb
54
54
  - tests/bug_issue102.rb
55
- - tests/bug_issue277.rb
56
55
  - tests/bug_multi_segfault.rb
57
56
  - tests/bug_postfields_crash.rb
58
57
  - tests/bug_postfields_crash2.rb
@@ -70,6 +69,7 @@ files:
70
69
  - tests/tc_curl_maxfilesize.rb
71
70
  - tests/tc_curl_multi.rb
72
71
  - tests/tc_curl_postfield.rb
72
+ - tests/tc_curl_protocols.rb
73
73
  - tests/timeout.rb
74
74
  - tests/timeout_server.rb
75
75
  - tests/unittests.rb
@@ -77,7 +77,7 @@ homepage: https://github.com/taf2/curb
77
77
  licenses:
78
78
  - MIT
79
79
  metadata: {}
80
- post_install_message:
80
+ post_install_message:
81
81
  rdoc_options:
82
82
  - "--main"
83
83
  - README.markdown
@@ -95,36 +95,36 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  requirements: []
98
- rubygems_version: 3.0.8
99
- signing_key:
98
+ rubygems_version: 3.3.3
99
+ signing_key:
100
100
  specification_version: 4
101
101
  summary: Ruby libcurl bindings
102
102
  test_files:
103
- - tests/tc_curl_multi.rb
104
103
  - tests/alltests.rb
105
- - tests/tc_curl_easy_setopt.rb
106
- - tests/tc_curl.rb
107
- - tests/bug_postfields_crash.rb
108
- - tests/bug_crash_on_progress.rb
109
- - tests/helper.rb
110
- - tests/bug_issue277.rb
111
- - tests/bug_postfields_crash2.rb
112
- - tests/bug_require_last_or_segfault.rb
113
- - tests/timeout.rb
114
104
  - tests/bug_crash_on_debug.rb
115
- - tests/unittests.rb
116
- - tests/bug_issue102.rb
105
+ - tests/bug_crash_on_progress.rb
117
106
  - tests/bug_curb_easy_blocks_ruby_threads.rb
118
- - tests/bug_multi_segfault.rb
107
+ - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
119
108
  - tests/bug_instance_post_differs_from_class_post.rb
109
+ - tests/bug_issue102.rb
110
+ - tests/bug_multi_segfault.rb
111
+ - tests/bug_postfields_crash.rb
112
+ - tests/bug_postfields_crash2.rb
113
+ - tests/bug_require_last_or_segfault.rb
114
+ - tests/bugtests.rb
115
+ - tests/helper.rb
116
+ - tests/mem_check.rb
120
117
  - tests/require_last_or_segfault_script.rb
121
- - tests/timeout_server.rb
118
+ - tests/signals.rb
119
+ - tests/tc_curl.rb
122
120
  - tests/tc_curl_download.rb
123
121
  - tests/tc_curl_easy.rb
124
- - tests/mem_check.rb
125
- - tests/tc_curl_postfield.rb
126
- - tests/tc_curl_maxfilesize.rb
127
- - tests/bugtests.rb
128
122
  - tests/tc_curl_easy_resolve.rb
129
- - tests/signals.rb
130
- - tests/bug_curb_easy_post_with_string_no_content_length_header.rb
123
+ - tests/tc_curl_easy_setopt.rb
124
+ - tests/tc_curl_maxfilesize.rb
125
+ - tests/tc_curl_multi.rb
126
+ - tests/tc_curl_postfield.rb
127
+ - tests/tc_curl_protocols.rb
128
+ - tests/timeout.rb
129
+ - tests/timeout_server.rb
130
+ - tests/unittests.rb
@@ -1,32 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
-
3
-
4
- require 'curb'
5
-
6
- class BugIssue102 < Test::Unit::TestCase
7
-
8
- def test_gc_closewait
9
- 100.times do
10
- responses = {}
11
- requests = ["http://www.google.co.uk/", "http://www.ruby-lang.org/"]
12
- m = Curl::Multi.new
13
- # add a few easy handles
14
- requests.each do |url|
15
- responses[url] = ""
16
- c = Curl::Easy.new(url) do|curl|
17
- curl.follow_location = true
18
- curl.on_body{|data| responses[url] << data; data.size }
19
- curl.on_success {|easy| #puts "success, add more easy handles"
20
- }
21
- end
22
- m.add(c)
23
- end
24
-
25
- m.perform do
26
- #puts "idling... can do some work here"
27
- end
28
- GC.start
29
- end
30
- end
31
-
32
- end