curb 0.9.11 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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