taf2-curb 0.2.8.0 → 0.3.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.
data/README CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  * http://curb.rubyforge.org/
4
4
  * http://rubyforge.org/projects/curb
5
- * http://groups.google.com/group/curb---ruby-libcurl-bindings
6
5
  * http://github.com/taf2/curb/tree/master
7
6
 
8
7
  Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the
@@ -18,7 +17,7 @@ Ruby license. See the LICENSE file for the gory details.
18
17
 
19
18
  === You will need
20
19
 
21
- * A working Ruby installation (1.8+, tested with 1.8.5)
20
+ * A working Ruby installation (1.8+, tested with 1.8.5, 1.8.6, 1.8.7, and 1.9.1)
22
21
  * A working (lib)curl installation, with development stuff (7.5+, tested with 7.15)
23
22
  * A sane build environment
24
23
 
data/Rakefile CHANGED
@@ -78,7 +78,11 @@ end
78
78
  # Test Tasks ---------------------------------------------------------
79
79
  task :ta => :alltests
80
80
  task :tu => :unittests
81
- task :test => :unittests
81
+ task :test => [:rmpid,:unittests]
82
+
83
+ task :rmpid do
84
+ sh "rm -rf tests/server_lock-*"
85
+ end
82
86
 
83
87
  if ENV['RELTEST']
84
88
  announce "Release task testing - not running regression tests on alltests"
data/ext/curb.h CHANGED
@@ -20,11 +20,11 @@
20
20
  #include "curb_macros.h"
21
21
 
22
22
  // These should be managed from the Rake 'release' task.
23
- #define CURB_VERSION "0.2.8.0"
24
- #define CURB_VER_NUM 280
23
+ #define CURB_VERSION "0.3.0.0"
24
+ #define CURB_VER_NUM 300
25
25
  #define CURB_VER_MAJ 0
26
- #define CURB_VER_MIN 2
27
- #define CURB_VER_MIC 8
26
+ #define CURB_VER_MIN 3
27
+ #define CURB_VER_MIC 0
28
28
  #define CURB_VER_PATCH 0
29
29
 
30
30
 
@@ -32,6 +32,9 @@
32
32
  #ifndef RSTRING_LEN
33
33
  #define RSTRING_LEN(x) RSTRING(x)->len
34
34
  #endif
35
+ #ifndef RSTRING_PTR
36
+ #define RSTRING_PTR(x) RSTRING(x)->ptr
37
+ #endif
35
38
 
36
39
  #ifdef HAVE_RUBY19_HASH
37
40
  #define RHASH_LEN(hash) RHASH(hash)->ntbl->num_entries
data/ext/curb_easy.c CHANGED
@@ -34,22 +34,41 @@ static size_t default_data_handler(char *stream,
34
34
  rb_str_buf_cat(out, stream, size * nmemb);
35
35
  return size * nmemb;
36
36
  }
37
+ typedef struct _PutStream {
38
+ char *buffer;
39
+ size_t offset, len;
40
+ } PutStream;
37
41
 
38
42
  // size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
39
- static size_t read_data_handler(char *stream,
43
+ static size_t read_data_handler(void *ptr,
40
44
  size_t size,
41
45
  size_t nmemb,
42
- char **buffer) {
43
- size_t result = 0;
44
-
45
- if (buffer != NULL && *buffer != NULL) {
46
- int len = size * nmemb;
47
- char *s1 = strncpy(stream, *buffer, len);
48
- result = strlen(s1);
49
- *buffer += result;
50
- }
46
+ void *stream) {
47
+
48
+ PutStream *pstream = (PutStream*)stream;
49
+ size_t sent_bytes = (size * nmemb);
50
+ size_t remaining = pstream->len - pstream->offset;
51
+
52
+ // amount remaining is less then the buffer to send - can send it all
53
+ if( remaining < sent_bytes ) {
54
+ memcpy(ptr, pstream->buffer+pstream->offset, remaining);
55
+ sent_bytes = remaining;
56
+ pstream->offset += remaining;
57
+ }
58
+ else if( remaining > sent_bytes ) { // sent_bytes <= remaining - send what we can fit in the buffer(ptr)
59
+ memcpy(ptr, pstream->buffer+pstream->offset, sent_bytes);
60
+ pstream->offset += sent_bytes;
61
+ }
62
+ else { // they're equal
63
+ memcpy(ptr, pstream->buffer+pstream->offset, --sent_bytes);
64
+ pstream->offset += sent_bytes;
65
+ }
66
+ if (sent_bytes == 0) {
67
+ free(pstream);
68
+ }
51
69
 
52
- return result;
70
+ //printf("sent_bytes: %ld of %ld\n", sent_bytes, remaining);
71
+ return sent_bytes;
53
72
  }
54
73
 
55
74
  static size_t proc_data_handler(char *stream,
@@ -119,6 +138,10 @@ void curl_easy_mark(ruby_curl_easy *rbce) {
119
138
  rb_gc_mark(rbce->postdata_buffer);
120
139
  rb_gc_mark(rbce->bodybuf);
121
140
  rb_gc_mark(rbce->headerbuf);
141
+
142
+ if( rbce->self != Qnil ) {
143
+ rb_gc_mark(rbce->self);
144
+ }
122
145
  }
123
146
 
124
147
  void curl_easy_free(ruby_curl_easy *rbce) {
@@ -205,6 +228,8 @@ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
205
228
  rbce->bodybuf = Qnil;
206
229
  rbce->headerbuf = Qnil;
207
230
  rbce->curl_headers = NULL;
231
+
232
+ rbce->self = Qnil;
208
233
 
209
234
  new_curl = Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, rbce);
210
235
 
@@ -1367,7 +1392,7 @@ VALUE ruby_curl_easy_setup( ruby_curl_easy *rbce, VALUE *body_buffer, VALUE *hea
1367
1392
  }
1368
1393
 
1369
1394
  /* Setup HTTP headers if necessary */
1370
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); // clear
1395
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
1371
1396
 
1372
1397
  if (rbce->headers != Qnil) {
1373
1398
  if ((rb_type(rbce->headers) == T_ARRAY) || (rb_type(rbce->headers) == T_HASH)) {
@@ -1403,8 +1428,8 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce, VALUE bodybuf, V
1403
1428
  if (TYPE(bodybuf) == T_STRING) {
1404
1429
  rbce->body_data = rb_str_to_str(bodybuf);
1405
1430
  }
1406
- else if (rb_respond_to(bodybuf, rb_intern("to_str"))) {
1407
- rbce->body_data = rb_funcall(bodybuf, rb_intern("to_str"), 0);
1431
+ else if (rb_respond_to(bodybuf, rb_intern("to_s"))) {
1432
+ rbce->body_data = rb_funcall(bodybuf, rb_intern("to_s"), 0);
1408
1433
  }
1409
1434
  else {
1410
1435
  rbce->body_data = Qnil;
@@ -1417,8 +1442,8 @@ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce, VALUE bodybuf, V
1417
1442
  if (TYPE(headerbuf) == T_STRING) {
1418
1443
  rbce->header_data = rb_str_to_str(headerbuf);
1419
1444
  }
1420
- else if (rb_respond_to(headerbuf, rb_intern("to_str"))) {
1421
- rbce->header_data = rb_funcall(headerbuf, rb_intern("to_str"), 0);
1445
+ else if (rb_respond_to(headerbuf, rb_intern("to_s"))) {
1446
+ rbce->header_data = rb_funcall(headerbuf, rb_intern("to_s"), 0);
1422
1447
  }
1423
1448
  else {
1424
1449
  rbce->header_data = Qnil;
@@ -1488,26 +1513,34 @@ static VALUE handle_perform(VALUE self, ruby_curl_easy *rbce) {
1488
1513
  FD_ZERO(&fdwrite);
1489
1514
  FD_ZERO(&fdexcep);
1490
1515
 
1491
- /* set a suitable timeout to play around with */
1492
- timeout.tv_sec = 1;
1493
- timeout.tv_usec = 0;
1516
+ //time_t timer = time(NULL);
1494
1517
  /* get file descriptors from the transfers */
1495
1518
  mcode = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
1496
1519
  if (mcode != CURLM_CALL_MULTI_PERFORM && mcode != CURLM_OK) {
1497
1520
  raise_curl_multi_error_exception(mcode);
1498
1521
  }
1499
1522
 
1523
+ /* set a suitable timeout to play around with - ruby seems to be greedy about this and won't necessarily yield so the timeout is small.. */
1524
+ timeout.tv_sec = 0.0;
1525
+ timeout.tv_usec = 100000.0;
1500
1526
  rc = rb_thread_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
1501
1527
  if (rc < 0) {
1502
1528
  rb_raise(rb_eRuntimeError, "select(): %s", strerror(errno));
1503
1529
  }
1504
1530
 
1505
- switch(rc) {
1506
- case 0:
1507
- default:
1508
- /* timeout or readable/writable sockets */
1509
- while(CURLM_CALL_MULTI_PERFORM == (mcode=curl_multi_perform(multi_handle, &still_running)) );
1510
- break;
1531
+ if( rc >= 0 ) {
1532
+ switch(rc) {
1533
+ case 0:
1534
+ //printf("timeout(%.6f) :", difftime(time(NULL), timer) );
1535
+ default:
1536
+ //printf("readable/writable: %d\n", rc);
1537
+ /* timeout or readable/writable sockets */
1538
+ while(CURLM_CALL_MULTI_PERFORM == (mcode=curl_multi_perform(multi_handle, &still_running)) );
1539
+ break;
1540
+ }
1541
+ }
1542
+ else {
1543
+ // error
1511
1544
  }
1512
1545
 
1513
1546
  if (mcode != CURLM_CALL_MULTI_PERFORM && mcode != CURLM_OK) {
@@ -1549,7 +1582,7 @@ static VALUE handle_perform(VALUE self, ruby_curl_easy *rbce) {
1549
1582
  rb_funcall( rbce->success_proc, idCall, 1, self );
1550
1583
  }
1551
1584
  else if (rbce->failure_proc != Qnil &&
1552
- (response_code >= 300 && response_code < 600)) {
1585
+ (response_code >= 300 && response_code <= 999)) {
1553
1586
  rb_funcall( rbce->failure_proc, idCall, 1, self );
1554
1587
  }
1555
1588
 
@@ -1723,21 +1756,31 @@ static VALUE ruby_curl_easy_perform_head(VALUE self) {
1723
1756
  static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
1724
1757
  ruby_curl_easy *rbce;
1725
1758
  CURL *curl;
1726
- char *buffer;
1727
- int len;
1759
+
1760
+ PutStream *pstream = (PutStream*)malloc(sizeof(PutStream));
1761
+ memset(pstream, 0, sizeof(PutStream));
1728
1762
 
1729
1763
  Data_Get_Struct(self, ruby_curl_easy, rbce);
1730
1764
  curl = rbce->curl;
1731
1765
 
1732
- buffer = StringValuePtr(data);
1733
- len = RSTRING_LEN(data);
1766
+ pstream->len = RSTRING_LEN(data);
1767
+ pstream->buffer = StringValuePtr(data);
1768
+
1734
1769
 
1735
1770
  curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
1736
1771
  curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
1737
- curl_easy_setopt(curl, CURLOPT_READDATA, &buffer);
1738
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, len);
1739
-
1740
- return handle_perform(self, rbce);
1772
+ curl_easy_setopt(curl, CURLOPT_READDATA, pstream);
1773
+ //printf("uploading %d bytes\n", pstream->len);
1774
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, pstream->len);
1775
+
1776
+ VALUE ret = handle_perform(self, rbce);
1777
+ /* cleanup */
1778
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 0);
1779
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
1780
+ curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
1781
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
1782
+
1783
+ return ret;
1741
1784
  }
1742
1785
 
1743
1786
  /* =================== DATA FUNCS =============== */
data/ext/curb_errors.c CHANGED
@@ -309,15 +309,21 @@ void raise_curl_easy_error_exception(CURLcode code) {
309
309
  case CURLE_FTP_SSL_FAILED: /* 64 - Requested FTP SSL level failed */
310
310
  exclz = eCurlErrFTPSSLFailed;
311
311
  break;
312
+ #ifdef HAVE_CURLE_SEND_FAIL_REWIND
312
313
  case CURLE_SEND_FAIL_REWIND: /* 65 - Sending the data requires a rewind that failed */
313
314
  exclz = eCurlErrSendFailedRewind;
314
- break;
315
+ break;
316
+ #endif
317
+ #ifdef HAVE_CURLE_SSL_ENGINE_INITFAILED
315
318
  case CURLE_SSL_ENGINE_INITFAILED: /* 66 - failed to initialise ENGINE */
316
319
  exclz = eCurlErrSSLEngineInitFailed;
317
320
  break;
321
+ #endif
322
+ #ifdef HAVE_CURLE_LOGIN_DENIED
318
323
  case CURLE_LOGIN_DENIED: /* 67 - user, password or similar was not accepted and we failed to login */
319
324
  exclz = eCurlErrLoginDenied;
320
325
  break;
326
+ #endif
321
327
 
322
328
  // recent additions, may not be present in all supported versions
323
329
  #ifdef HAVE_CURLE_TFTP_NOTFOUND
@@ -386,12 +392,16 @@ void raise_curl_multi_error_exception(CURLMcode code) {
386
392
  case CURLM_INTERNAL_ERROR: /* 4 */
387
393
  exclz = mCurlErrInternalError;
388
394
  break;
395
+ #if HAVE_CURLM_BAD_SOCKET
389
396
  case CURLM_BAD_SOCKET: /* 5 */
390
397
  exclz = mCurlErrBadSocket;
391
398
  break;
399
+ #endif
400
+ #if HAVE_CURLM_UNKNOWN_OPTION
392
401
  case CURLM_UNKNOWN_OPTION: /* 6 */
393
402
  exclz = mCurlErrUnknownOption;
394
403
  break;
404
+ #endif
395
405
  default:
396
406
  exclz = eCurlErrError;
397
407
  exmsg = "Unknown error result from libcurl";
data/ext/curb_multi.c CHANGED
@@ -4,7 +4,13 @@
4
4
  *
5
5
  * $Id$
6
6
  */
7
+
8
+ #include "curb_config.h"
9
+ #ifdef HAVE_RUBY19_ST_H
10
+ #include <ruby/st.h>
11
+ #else
7
12
  #include <st.h>
13
+ #endif
8
14
  #include "curb_easy.h"
9
15
  #include "curb_errors.h"
10
16
  #include "curb_postfield.h"
@@ -41,12 +47,12 @@ static void curl_multi_flush_easy(VALUE key, VALUE easy, ruby_curl_multi *rbcm)
41
47
 
42
48
  static void curl_multi_free(ruby_curl_multi *rbcm) {
43
49
  //printf("hash entries: %d\n", RHASH(rbcm->requests)->tbl->num_entries );
44
- if (RHASH_LEN(rbcm->requests) > 0) {
50
+ if (rbcm && RHASH_LEN(rbcm->requests) > 0) {
45
51
  rb_hash_foreach( rbcm->requests, (int (*)())curl_multi_flush_easy, (VALUE)rbcm );
46
52
 
47
53
  curl_multi_cleanup(rbcm->handle);
48
54
  //rb_hash_clear(rbcm->requests)
49
- rbcm->requests = rb_hash_new();
55
+ rbcm->requests = Qnil;
50
56
  }
51
57
  }
52
58
 
@@ -73,6 +79,24 @@ static VALUE ruby_curl_multi_new(VALUE self) {
73
79
  return new_curlm;
74
80
  }
75
81
 
82
+ /*
83
+ * call-seq:
84
+ * multi = Curl::Multi.new
85
+ * multi.max_connects = 800
86
+ *
87
+ * Set the max connections in the cache for a multi handle
88
+ */
89
+ static VALUE ruby_curl_multi_max_connects(VALUE self, VALUE count) {
90
+ #ifdef HAVE_CURLMOPT_MAXCONNECTS
91
+ ruby_curl_multi *rbcm;
92
+
93
+ Data_Get_Struct(self, ruby_curl_multi, rbcm);
94
+ curl_multi_setopt(rbcm->handle, CURLMOPT_MAXCONNECTS, NUM2INT(count));
95
+ #endif
96
+
97
+ return self;
98
+ }
99
+
76
100
  /*
77
101
  * call-seq:
78
102
  * multi = Curl::Multi.new
@@ -106,7 +130,7 @@ static VALUE ruby_curl_multi_add(VALUE self, VALUE easy) {
106
130
  curl_multi_perform(rbcm->handle, &(rbcm->running));
107
131
  }
108
132
 
109
- rb_hash_aset( rbcm->requests, rb_int_new((long)rbce->curl), easy );
133
+ rb_hash_aset( rbcm->requests, easy, easy );
110
134
  // active should equal INT2FIX(RHASH(rbcm->requests)->tbl->num_entries)
111
135
 
112
136
  if (rbcm->active > rbcm->running) {
@@ -135,8 +159,10 @@ static VALUE ruby_curl_multi_remove(VALUE self, VALUE easy) {
135
159
 
136
160
  Data_Get_Struct(self, ruby_curl_multi, rbcm);
137
161
 
162
+ ruby_curl_easy *rbce;
163
+ Data_Get_Struct(easy, ruby_curl_easy, rbce);
164
+
138
165
  rb_curl_multi_remove(rbcm,easy);
139
- // active should equal INT2FIX(RHASH(rbcm->requests)->tbl->num_entries)
140
166
 
141
167
  return self;
142
168
  }
@@ -157,7 +183,12 @@ static void rb_curl_multi_remove(ruby_curl_multi *rbcm, VALUE easy) {
157
183
  ruby_curl_easy_cleanup( easy, rbce, rbce->bodybuf, rbce->headerbuf, rbce->curl_headers );
158
184
  rbce->headerbuf = Qnil;
159
185
  rbce->bodybuf = Qnil;
160
- rb_hash_delete( rbcm->requests, rb_int_new((long)rbce->curl) );
186
+
187
+ // active should equal INT2FIX(RHASH(rbcm->requests)->tbl->num_entries)
188
+ VALUE r = rb_hash_delete( rbcm->requests, easy );
189
+ if( r != easy || r == Qnil ) {
190
+ fprintf(stderr, "Critical:: Unable to remove easy from requests\n");
191
+ }
161
192
  }
162
193
 
163
194
  static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
@@ -166,7 +197,6 @@ static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
166
197
  CURLcode ecode;
167
198
  CURL *easy_handle;
168
199
  ruby_curl_easy *rbce = NULL;
169
- // VALUE finished = rb_ary_new();
170
200
 
171
201
  /* check for finished easy handles and remove from the multi handle */
172
202
  while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
@@ -182,8 +212,6 @@ static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
182
212
  if (ecode != 0) {
183
213
  raise_curl_easy_error_exception(ecode);
184
214
  }
185
- //printf( "finished: 0x%X\n", (long)rbce->self );
186
- //rb_ary_push(finished, rbce->self);
187
215
  ruby_curl_multi_remove( self, rbce->self );
188
216
 
189
217
  if (rbce->complete_proc != Qnil) {
@@ -204,21 +232,15 @@ static void rb_curl_multi_read_info(VALUE self, CURLM *multi_handle) {
204
232
  rb_funcall( rbce->success_proc, idCall, 1, rbce->self );
205
233
  }
206
234
  else if (rbce->failure_proc != Qnil &&
207
- (response_code >= 300 && response_code < 600)) {
235
+ (response_code >= 300 && response_code <= 999)) {
208
236
  rb_funcall( rbce->failure_proc, idCall, 1, rbce->self );
209
237
  }
238
+ rbce->self = Qnil;
210
239
  }
211
240
  else {
212
241
  //printf( "missing easy handle\n" );
213
242
  }
214
243
  }
215
-
216
- /*
217
- while (RARRAY(finished)->len > 0) {
218
- //printf( "finished handle\n" );
219
- ruby_curl_multi_remove( self, rb_ary_pop(finished) );
220
- }
221
- */
222
244
  }
223
245
 
224
246
  /* called within ruby_curl_multi_perform */
@@ -321,6 +343,7 @@ void init_curb_multi() {
321
343
  rb_define_singleton_method(cCurlMulti, "new", ruby_curl_multi_new, -1);
322
344
 
323
345
  /* Instnace methods */
346
+ rb_define_method(cCurlMulti, "max_connects=", ruby_curl_multi_max_connects, 1);
324
347
  rb_define_method(cCurlMulti, "add", ruby_curl_multi_add, 1);
325
348
  rb_define_method(cCurlMulti, "remove", ruby_curl_multi_remove, 1);
326
349
  rb_define_method(cCurlMulti, "perform", ruby_curl_multi_perform, 0);
data/ext/curb_postfield.c CHANGED
@@ -429,9 +429,10 @@ static VALUE ruby_curl_postfield_to_str(VALUE self) {
429
429
 
430
430
  if ((rbcpf->local_file == Qnil) && (rbcpf->remote_file == Qnil)) {
431
431
  if (rbcpf->name != Qnil) {
432
- char *tmpchrs;
432
+
433
+ char *tmpchrs = curl_escape(RSTRING_PTR(rbcpf->name), RSTRING_LEN(rbcpf->name));
433
434
 
434
- if ((tmpchrs = curl_escape(StringValuePtr(rbcpf->name), RSTRING_LEN(rbcpf->name))) == NULL) {
435
+ if (!tmpchrs) {
435
436
  rb_raise(eCurlErrInvalidPostField, "Failed to url-encode name `%s'", tmpchrs);
436
437
  } else {
437
438
  VALUE tmpcontent = Qnil;
@@ -445,8 +446,17 @@ static VALUE ruby_curl_postfield_to_str(VALUE self) {
445
446
  } else {
446
447
  tmpcontent = rb_str_new2("");
447
448
  }
448
-
449
- if ((tmpchrs = curl_escape(StringValuePtr(tmpcontent), RSTRING_LEN(tmpcontent))) == NULL) {
449
+ if (TYPE(tmpcontent) != T_STRING) {
450
+ if (rb_respond_to(tmpcontent, rb_intern("to_s"))) {
451
+ tmpcontent = rb_funcall(tmpcontent, rb_intern("to_s"), 0);
452
+ }
453
+ else {
454
+ rb_raise(rb_eRuntimeError, "postfield(%s) is not a string and does not respond_to to_s", RSTRING_PTR(escd_name) );
455
+ }
456
+ }
457
+ //fprintf(stderr, "encoding content: %ld - %s\n", RSTRING_LEN(tmpcontent), RSTRING_PTR(tmpcontent) );
458
+ tmpchrs = curl_escape(RSTRING_PTR(tmpcontent), RSTRING_LEN(tmpcontent));
459
+ if (!tmpchrs) {
450
460
  rb_raise(eCurlErrInvalidPostField, "Failed to url-encode content `%s'", tmpchrs);
451
461
  } else {
452
462
  VALUE escd_content = rb_str_new2(tmpchrs);
data/ext/extconf.rb CHANGED
@@ -70,6 +70,17 @@ have_constant "curle_tftp_illegal"
70
70
  have_constant "curle_tftp_unknownid"
71
71
  have_constant "curle_tftp_exists"
72
72
  have_constant "curle_tftp_nosuchuser"
73
+ # older versions of libcurl 7.12
74
+ have_constant "curle_send_fail_rewind"
75
+ have_constant "curle_ssl_engine_initfailed"
76
+ have_constant "curle_login_denied"
77
+
78
+ # older than 7.16.3
79
+ have_constant "curlmopt_maxconnects"
80
+
81
+ # centos 4.5 build of libcurl
82
+ have_constant "curlm_bad_socket"
83
+ have_constant "curlm_unknown_option"
73
84
 
74
85
  if try_compile('int main() { return 0; }','-Wall')
75
86
  $CFLAGS << ' -Wall'
@@ -77,7 +88,7 @@ end
77
88
 
78
89
  # do some checking to detect ruby 1.8 hash.c vs ruby 1.9 hash.c
79
90
  def test_for(name, const, src)
80
- checking_for "Ruby 1.9" do
91
+ checking_for name do
81
92
  if try_compile(src,"#{$CFLAGS} #{$LIBS}")
82
93
  define const
83
94
  true
@@ -86,7 +97,7 @@ def test_for(name, const, src)
86
97
  end
87
98
  end
88
99
  end
89
- test_for("Ruby 1.9", "RUBY19_HASH", %{
100
+ test_for("Ruby 1.9 Hash", "RUBY19_HASH", %{
90
101
  #include <ruby.h>
91
102
  int main() {
92
103
  VALUE hash = rb_hash_new();
@@ -96,6 +107,22 @@ test_for("Ruby 1.9", "RUBY19_HASH", %{
96
107
  return 1;
97
108
  }
98
109
  })
110
+ test_for("Ruby 1.9 st.h", "RUBY19_ST_H", %{
111
+ #include <ruby.h>
112
+ #include <ruby/st.h>
113
+ int main() {
114
+ return 0;
115
+ }
116
+ })
117
+
118
+ test_for("curl_easy_escape", "CURL_EASY_ESCAPE", %{
119
+ #include <curl/curl.h>
120
+ int main() {
121
+ CURL *easy = curl_easy_init();
122
+ curl_easy_escape(easy,"hello",5);
123
+ return 0;
124
+ }
125
+ })
99
126
 
100
127
  create_header('curb_config.h')
101
128
  create_makefile('curb_core')
data/tests/helper.rb CHANGED
@@ -17,6 +17,12 @@ $TEST_URL = "file://#{URI.escape(File.expand_path(__FILE__).tr('\\','/').tr(':',
17
17
  require 'thread'
18
18
  require 'webrick'
19
19
 
20
+ # set this to true to avoid testing with multiple threads
21
+ # or to test with multiple threads set it to false
22
+ # this is important since, some code paths will change depending
23
+ # on the presence of multiple threads
24
+ TEST_SINGLE_THREADED=false
25
+
20
26
  # keep webrick quiet
21
27
  class ::WEBrick::HTTPServer
22
28
  def access_log(config, req, res)
@@ -87,28 +93,56 @@ module TestServerMethods
87
93
  def server_setup(port=9129,servlet=TestServlet)
88
94
  @__port = port
89
95
  if @server.nil? and !File.exist?(locked_file)
90
- File.open(locked_file,'w') {|f| f << 'locked' }
91
-
92
- # start up a webrick server for testing delete
93
- @server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
94
-
95
- @server.mount(servlet.path, servlet)
96
- queue = Queue.new # synchronize the thread startup to the main thread
97
96
 
98
- @test_thread = Thread.new { queue << 1; @server.start }
97
+ File.open(locked_file,'w') {|f| f << 'locked' }
98
+ if TEST_SINGLE_THREADED
99
+ rd, wr = IO.pipe
100
+ @__pid = fork do
101
+ rd.close
102
+ rd = nil
103
+
104
+ # start up a webrick server for testing delete
105
+ server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
106
+
107
+ server.mount(servlet.path, servlet)
108
+ trap("INT") { server.shutdown }
109
+ GC.start
110
+ wr.flush
111
+ wr.close
112
+ server.start
113
+ end
114
+ wr.close
115
+ rd.read
116
+ rd.close
117
+ else
118
+ # start up a webrick server for testing delete
119
+ @server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => File.expand_path(File.dirname(__FILE__))
120
+
121
+ @server.mount(servlet.path, servlet)
122
+ queue = Queue.new # synchronize the thread startup to the main thread
123
+
124
+ @test_thread = Thread.new { queue << 1; @server.start }
125
+
126
+ # wait for the queue
127
+ value = queue.pop
128
+ if !value
129
+ STDERR.puts "Failed to startup test server!"
130
+ exit(1)
131
+ end
99
132
 
100
- # wait for the queue
101
- value = queue.pop
102
- if !value
103
- STDERR.puts "Failed to startup test server!"
104
- exit(1)
105
133
  end
106
134
 
107
135
  exit_code = lambda do
108
136
  begin
109
- #puts "stopping"
110
- File.unlink locked_file if File.exist?(locked_file)
111
- @server.shutdown unless @server.nil?
137
+ if File.exist?(locked_file)
138
+ File.unlink locked_file
139
+ if TEST_SINGLE_THREADED
140
+ Process.kill 'INT', @__pid
141
+ else
142
+ @server.shutdown unless @server.nil?
143
+ end
144
+ end
145
+ #@server.shutdown unless @server.nil?
112
146
  rescue Object => e
113
147
  puts "Error #{__FILE__}:#{__LINE__}\n#{e.message}"
114
148
  end
@@ -180,7 +180,7 @@ class TestCurbCurlMulti < Test::Unit::TestCase
180
180
  def t_method
181
181
  @buf = ""
182
182
  @m = Curl::Multi.new
183
- 10.times do
183
+ 10.times do|i|
184
184
  c = Curl::Easy.new($TEST_URL)
185
185
  c.on_success{|b| @buf << b.body_str }
186
186
  ObjectSpace.garbage_collect
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taf2-curb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8.0
4
+ version: 0.3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Bamford
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-03-13 00:00:00 -07:00
13
+ date: 2009-06-08 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -41,7 +41,6 @@ files:
41
41
  - ext/curb_macros.h
42
42
  - ext/curb.h
43
43
  - ext/curb_postfield.h
44
- - ext/curb_config.h
45
44
  - ext/curb_multi.h
46
45
  has_rdoc: true
47
46
  homepage: http://curb.rubyforge.org/