taf2-curb 0.2.3

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.
@@ -0,0 +1,499 @@
1
+ /* curb_postfield.c - Field class for POST method
2
+ * Copyright (c)2006 Ross Bamford.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ *
5
+ * $Id: curb_postfield.c 30 2006-12-09 12:30:24Z roscopeco $
6
+ */
7
+ #include "curb_postfield.h"
8
+ #include "curb_errors.h"
9
+
10
+ extern VALUE mCurl;
11
+
12
+ static VALUE idCall;
13
+
14
+ #ifdef RDOC_NEVER_DEFINED
15
+ mCurl = rb_define_module("Curl");
16
+ #endif
17
+
18
+ VALUE cCurlPostField;
19
+
20
+
21
+ /* ================= APPEND FORM FUNC ================ */
22
+
23
+ /* This gets called by the post method on Curl::Easy for each postfield
24
+ * supplied in the arguments. It's job is to add the supplied field to
25
+ * the list that's being built for a perform.
26
+ *
27
+ * THIS FUNC MODIFIES ITS ARGUMENTS. See curl_formadd(3) for details.
28
+ */
29
+ void append_to_form(VALUE self,
30
+ struct curl_httppost **first,
31
+ struct curl_httppost **last) {
32
+ ruby_curl_postfield *rbcpf;
33
+ CURLFORMcode result = -1;
34
+
35
+ Data_Get_Struct(self, ruby_curl_postfield, rbcpf);
36
+
37
+ if (rbcpf->name == Qnil) {
38
+ rb_raise(eCurlErrInvalidPostField, "Cannot post unnamed field");
39
+ } else {
40
+ if ((rbcpf->local_file != Qnil) || (rbcpf->remote_file != Qnil)) {
41
+ // is a file upload field
42
+ if (rbcpf->content_proc != Qnil) {
43
+ // with content proc
44
+ rbcpf->buffer_str = rb_funcall(rbcpf->content_proc, idCall, self);
45
+
46
+ if (rbcpf->remote_file == Qnil) {
47
+ rb_raise(eCurlErrInvalidPostField, "Cannot post file upload field with no filename");
48
+ } else {
49
+ if (rbcpf->content_type == Qnil) {
50
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
51
+ CURLFORM_BUFFER, StringValuePtr(rbcpf->remote_file),
52
+ CURLFORM_BUFFERPTR, StringValuePtr(rbcpf->buffer_str),
53
+ CURLFORM_BUFFERLENGTH, RSTRING_LEN(rbcpf->buffer_str),
54
+ CURLFORM_END);
55
+ } else {
56
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
57
+ CURLFORM_BUFFER, StringValuePtr(rbcpf->remote_file),
58
+ CURLFORM_BUFFERPTR, StringValuePtr(rbcpf->buffer_str),
59
+ CURLFORM_BUFFERLENGTH, RSTRING_LEN(rbcpf->buffer_str),
60
+ CURLFORM_CONTENTTYPE, StringValuePtr(rbcpf->content_type),
61
+ CURLFORM_END);
62
+ }
63
+ }
64
+ } else if (rbcpf->content != Qnil) {
65
+ // with content
66
+ if (rbcpf->remote_file == Qnil) {
67
+ rb_raise(eCurlErrInvalidPostField, "Cannot post file upload field with no filename");
68
+ } else {
69
+ if (rbcpf->content_type == Qnil) {
70
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
71
+ CURLFORM_BUFFER, StringValuePtr(rbcpf->remote_file),
72
+ CURLFORM_BUFFERPTR, StringValuePtr(rbcpf->content),
73
+ CURLFORM_BUFFERLENGTH, RSTRING_LEN(rbcpf->content),
74
+ CURLFORM_END);
75
+ } else {
76
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
77
+ CURLFORM_BUFFER, StringValuePtr(rbcpf->remote_file),
78
+ CURLFORM_BUFFERPTR, StringValuePtr(rbcpf->content),
79
+ CURLFORM_BUFFERLENGTH, RSTRING_LEN(rbcpf->content),
80
+ CURLFORM_CONTENTTYPE, StringValuePtr(rbcpf->content_type),
81
+ CURLFORM_END);
82
+ }
83
+ }
84
+ } else if (rbcpf->local_file != Qnil) {
85
+ // with local filename
86
+ if (rbcpf->local_file == Qnil) {
87
+ rb_raise(eCurlErrInvalidPostField, "Cannot post file upload field no filename");
88
+ } else {
89
+ if (rbcpf->remote_file == Qnil) {
90
+ rbcpf->remote_file = rbcpf->local_file;
91
+ }
92
+
93
+ if (rbcpf->content_type == Qnil) {
94
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
95
+ CURLFORM_FILE, StringValuePtr(rbcpf->local_file),
96
+ CURLFORM_FILENAME, StringValuePtr(rbcpf->remote_file),
97
+ CURLFORM_END);
98
+ } else {
99
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
100
+ CURLFORM_FILE, StringValuePtr(rbcpf->local_file),
101
+ CURLFORM_FILENAME, StringValuePtr(rbcpf->remote_file),
102
+ CURLFORM_CONTENTTYPE, StringValuePtr(rbcpf->content_type),
103
+ CURLFORM_END);
104
+ }
105
+ }
106
+ } else {
107
+ rb_raise(eCurlErrInvalidPostField, "Cannot post file upload field with no data");
108
+ }
109
+ } else {
110
+ // is a content field
111
+ if (rbcpf->content_proc != Qnil) {
112
+ rbcpf->buffer_str = rb_funcall(rbcpf->content_proc, idCall, self);
113
+
114
+ if (rbcpf->content_type == Qnil) {
115
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
116
+ CURLFORM_PTRCONTENTS, StringValuePtr(rbcpf->buffer_str),
117
+ CURLFORM_CONTENTSLENGTH, RSTRING_LEN(rbcpf->buffer_str),
118
+ CURLFORM_END);
119
+ } else {
120
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
121
+ CURLFORM_PTRCONTENTS, StringValuePtr(rbcpf->buffer_str),
122
+ CURLFORM_CONTENTSLENGTH, RSTRING_LEN(rbcpf->buffer_str),
123
+ CURLFORM_CONTENTTYPE, StringValuePtr(rbcpf->content_type),
124
+ CURLFORM_END);
125
+ }
126
+ } else if (rbcpf->content != Qnil) {
127
+ if (rbcpf->content_type == Qnil) {
128
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
129
+ CURLFORM_PTRCONTENTS, StringValuePtr(rbcpf->content),
130
+ CURLFORM_CONTENTSLENGTH, RSTRING_LEN(rbcpf->content),
131
+ CURLFORM_END);
132
+ } else {
133
+ result = curl_formadd(first, last, CURLFORM_PTRNAME, StringValuePtr(rbcpf->name),
134
+ CURLFORM_PTRCONTENTS, StringValuePtr(rbcpf->content),
135
+ CURLFORM_CONTENTSLENGTH, RSTRING_LEN(rbcpf->content),
136
+ CURLFORM_CONTENTTYPE, StringValuePtr(rbcpf->content_type),
137
+ CURLFORM_END);
138
+ }
139
+ } else {
140
+ rb_raise(eCurlErrInvalidPostField, "Cannot post content field with no data");
141
+ }
142
+ }
143
+ }
144
+
145
+ if (result != 0) {
146
+ char *reason;
147
+
148
+ switch (result) {
149
+ case CURL_FORMADD_MEMORY:
150
+ reason = "Memory allocation failed";
151
+ break;
152
+ case CURL_FORMADD_OPTION_TWICE:
153
+ reason = "Duplicate option";
154
+ break;
155
+ case CURL_FORMADD_NULL:
156
+ reason = "Unexpected NULL string";
157
+ break;
158
+ case CURL_FORMADD_UNKNOWN_OPTION:
159
+ reason = "Unknown option";
160
+ break;
161
+ case CURL_FORMADD_INCOMPLETE:
162
+ reason = "Incomplete form data";
163
+ break;
164
+ case CURL_FORMADD_ILLEGAL_ARRAY:
165
+ reason = "Illegal array [BINDING BUG]";
166
+ break;
167
+ case CURL_FORMADD_DISABLED:
168
+ reason = "Installed libcurl cannot support requested feature(s)";
169
+ break;
170
+ default:
171
+ reason = "Unknown error";
172
+ }
173
+
174
+ rb_raise(eCurlErrInvalidPostField, "Failed to add field (%s)", reason);
175
+ }
176
+ }
177
+
178
+
179
+ /* ================== MARK/FREE FUNC ==================*/
180
+ void curl_postfield_mark(ruby_curl_postfield *rbcpf) {
181
+ rb_gc_mark(rbcpf->name);
182
+ rb_gc_mark(rbcpf->content);
183
+ rb_gc_mark(rbcpf->content_type);
184
+ rb_gc_mark(rbcpf->local_file);
185
+ rb_gc_mark(rbcpf->remote_file);
186
+ rb_gc_mark(rbcpf->buffer_str);
187
+ }
188
+
189
+ void curl_postfield_free(ruby_curl_postfield *rbcpf) {
190
+ free(rbcpf);
191
+ }
192
+
193
+
194
+ /* ================= ALLOC METHODS ====================*/
195
+
196
+ /*
197
+ * call-seq:
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
+ *
202
+ * Create a new Curl::PostField, supplying the field name, content,
203
+ * and, optionally, Content-type (curl will attempt to determine this if
204
+ * not specified).
205
+ *
206
+ * The block form allows a block to supply the content for this field, called
207
+ * during the perform. The block should return a ruby string with the field
208
+ * data.
209
+ */
210
+ static VALUE ruby_curl_postfield_new_content(int argc, VALUE *argv, VALUE klass) {
211
+ ruby_curl_postfield *rbcpf = ALLOC(ruby_curl_postfield);
212
+
213
+ // wierdness - we actually require two args, unless a block is provided, but
214
+ // we have to work that out below.
215
+ rb_scan_args(argc, argv, "12&", &rbcpf->name, &rbcpf->content, &rbcpf->content_type, &rbcpf->content_proc);
216
+
217
+ // special handling if theres a block, second arg is actually content_type
218
+ if (rbcpf->content_proc != Qnil) {
219
+ if (rbcpf->content != Qnil) {
220
+ // we were given a content-type
221
+ rbcpf->content_type = rbcpf->content;
222
+ rbcpf->content = Qnil;
223
+ } else {
224
+ // default content type
225
+ rbcpf->content_type = Qnil;
226
+ }
227
+ } else {
228
+ // no block, so make sure content was provided
229
+ if (rbcpf->content == Qnil) {
230
+ rb_raise(rb_eArgError, "Incorrect number of arguments (expected 2 or 3)");
231
+ }
232
+ }
233
+
234
+ /* assoc objects */
235
+ rbcpf->local_file = Qnil;
236
+ rbcpf->remote_file = Qnil;
237
+ rbcpf->buffer_str = Qnil;
238
+
239
+ return Data_Wrap_Struct(cCurlPostField, curl_postfield_mark, curl_postfield_free, rbcpf);
240
+ }
241
+
242
+ /*
243
+ * call-seq:
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
+ *
248
+ * Create a new Curl::PostField for a file upload field, supplying the local filename
249
+ * to read from, and optionally the remote filename (defaults to the local name).
250
+ *
251
+ * The block form allows a block to supply the content for this field, called
252
+ * during the perform. The block should return a ruby string with the field
253
+ * data.
254
+ */
255
+ static VALUE ruby_curl_postfield_new_file(int argc, VALUE *argv, VALUE klass) {
256
+ // TODO needs to handle content-type too
257
+ ruby_curl_postfield *rbcpf = ALLOC(ruby_curl_postfield);
258
+
259
+ rb_scan_args(argc, argv, "21&", &rbcpf->name, &rbcpf->local_file, &rbcpf->remote_file, &rbcpf->content_proc);
260
+
261
+ // special handling if theres a block, second arg is actually remote name.
262
+ if (rbcpf->content_proc != Qnil) {
263
+ if (rbcpf->local_file != Qnil) {
264
+ // we were given a local file
265
+ if (rbcpf->remote_file == Qnil) {
266
+ // we weren't given a remote, so local is actually remote
267
+ // (correct block call form)
268
+ rbcpf->remote_file = rbcpf->local_file;
269
+ }
270
+
271
+ // Shouldn't get a local file, so can ignore it.
272
+ rbcpf->local_file = Qnil;
273
+ }
274
+ } else {
275
+ if (rbcpf->remote_file == Qnil) {
276
+ rbcpf->remote_file = rbcpf->local_file;
277
+ }
278
+ }
279
+
280
+ /* assoc objects */
281
+ rbcpf->content = Qnil;
282
+ rbcpf->content_type = Qnil;
283
+ rbcpf->buffer_str = Qnil;
284
+
285
+ return Data_Wrap_Struct(cCurlPostField, curl_postfield_mark, curl_postfield_free, rbcpf);
286
+ }
287
+
288
+ /* ================= ATTRIBUTES ====================*/
289
+
290
+ /*
291
+ * call-seq:
292
+ * field.name = "name" => "name"
293
+ *
294
+ * Set the POST field name for this PostField.
295
+ */
296
+ static VALUE ruby_curl_postfield_name_set(VALUE self, VALUE name) {
297
+ CURB_OBJECT_SETTER(ruby_curl_postfield, name);
298
+ }
299
+
300
+ /*
301
+ * call-seq:
302
+ * field.name => "name"
303
+ *
304
+ * Obtain the POST field name for this PostField.
305
+ */
306
+ static VALUE ruby_curl_postfield_name_get(VALUE self) {
307
+ CURB_OBJECT_GETTER(ruby_curl_postfield, name);
308
+ }
309
+
310
+ /*
311
+ * call-seq:
312
+ * field.content = "content" => "content"
313
+ *
314
+ * Set the POST field content for this PostField. Ignored when a
315
+ * content_proc is supplied via either +Curl::PostField.file+ or
316
+ * +set_content_proc+.
317
+ */
318
+ static VALUE ruby_curl_postfield_content_set(VALUE self, VALUE content) {
319
+ CURB_OBJECT_SETTER(ruby_curl_postfield, content);
320
+ }
321
+
322
+ /*
323
+ * call-seq:
324
+ * field.content => "content"
325
+ *
326
+ * Obtain the POST field content for this PostField.
327
+ */
328
+ static VALUE ruby_curl_postfield_content_get(VALUE self) {
329
+ CURB_OBJECT_GETTER(ruby_curl_postfield, content);
330
+ }
331
+
332
+ /*
333
+ * call-seq:
334
+ * field.content_type = "content_type" => "content_type"
335
+ *
336
+ * Set the POST field Content-type for this PostField.
337
+ */
338
+ static VALUE ruby_curl_postfield_content_type_set(VALUE self, VALUE content_type) {
339
+ CURB_OBJECT_SETTER(ruby_curl_postfield, content_type);
340
+ }
341
+
342
+ /*
343
+ * call-seq:
344
+ * field.content_type => "content_type"
345
+ *
346
+ * Get the POST field Content-type for this PostField.
347
+ */
348
+ static VALUE ruby_curl_postfield_content_type_get(VALUE self) {
349
+ CURB_OBJECT_GETTER(ruby_curl_postfield, content_type);
350
+ }
351
+
352
+ /*
353
+ * call-seq:
354
+ * field.local_file = "filename" => "filename"
355
+ *
356
+ * Set the POST field local filename for this PostField (when performing
357
+ * a file upload). Ignored when a content_proc is supplied via either
358
+ * +Curl::PostField.file+ or +set_content_proc+.
359
+ */
360
+ static VALUE ruby_curl_postfield_local_file_set(VALUE self, VALUE local_file) {
361
+ CURB_OBJECT_SETTER(ruby_curl_postfield, local_file);
362
+ }
363
+
364
+ /*
365
+ * call-seq:
366
+ * field.local_file => "filename"
367
+ *
368
+ * Get the POST field local filename for this PostField (when performing
369
+ * a file upload).
370
+ */
371
+ static VALUE ruby_curl_postfield_local_file_get(VALUE self) {
372
+ CURB_OBJECT_GETTER(ruby_curl_postfield, local_file);
373
+ }
374
+
375
+ /*
376
+ * call-seq:
377
+ * field.remote_file = "filename" => "filename"
378
+ *
379
+ * Set the POST field remote filename for this PostField (when performing
380
+ * a file upload). If no remote filename is provided, and no content_proc
381
+ * is supplied, the local filename is used. If no remote filename is
382
+ * specified when a content_proc is used, an exception will be raised
383
+ * during the perform.
384
+ */
385
+ static VALUE ruby_curl_postfield_remote_file_set(VALUE self, VALUE remote_file) {
386
+ CURB_OBJECT_SETTER(ruby_curl_postfield, remote_file);
387
+ }
388
+
389
+ /*
390
+ * call-seq:
391
+ * field.local_file => "filename"
392
+ *
393
+ * Get the POST field remote filename for this PostField (when performing
394
+ * a file upload).
395
+ */
396
+ static VALUE ruby_curl_postfield_remote_file_get(VALUE self) {
397
+ CURB_OBJECT_GETTER(ruby_curl_postfield, remote_file);
398
+ }
399
+
400
+ /*
401
+ * call-seq:
402
+ * field.set_content_proc { |field| ... } => <old proc>
403
+ *
404
+ * Set a content proc for this field. This proc will be called during the
405
+ * perform to supply the content for this field, overriding any setting
406
+ * of +content+ or +local_file+.
407
+ */
408
+ static VALUE ruby_curl_postfield_content_proc_set(int argc, VALUE *argv, VALUE self) {
409
+ CURB_HANDLER_PROC_SETTER(ruby_curl_postfield, content_proc);
410
+ }
411
+
412
+ /*
413
+ * call-seq:
414
+ * field.to_str => "name=value"
415
+ * field.to_s => "name=value"
416
+ *
417
+ * Obtain a String representation of this PostField in url-encoded
418
+ * format. This is used to construct the post data for non-multipart
419
+ * POSTs.
420
+ *
421
+ * Only content fields may be converted to strings.
422
+ */
423
+ static VALUE ruby_curl_postfield_to_str(VALUE self) {
424
+ // FIXME This is using the deprecated curl_escape func
425
+ ruby_curl_postfield *rbcpf;
426
+ VALUE result = Qnil;
427
+
428
+ Data_Get_Struct(self, ruby_curl_postfield, rbcpf);
429
+
430
+ if ((rbcpf->local_file == Qnil) && (rbcpf->remote_file == Qnil)) {
431
+ if (rbcpf->name != Qnil) {
432
+ char *tmpchrs;
433
+
434
+ if ((tmpchrs = curl_escape(StringValuePtr(rbcpf->name), RSTRING_LEN(rbcpf->name))) == NULL) {
435
+ rb_raise(eCurlErrInvalidPostField, "Failed to url-encode name `%s'", tmpchrs);
436
+ } else {
437
+ VALUE tmpcontent = Qnil;
438
+ VALUE escd_name = rb_str_new2(tmpchrs);
439
+ curl_free(tmpchrs);
440
+
441
+ if (rbcpf->content_proc != Qnil) {
442
+ tmpcontent = rb_funcall(rbcpf->content_proc, idCall, 1, self);
443
+ } else if (rbcpf->content != Qnil) {
444
+ tmpcontent = rbcpf->content;
445
+ } else {
446
+ tmpcontent = rb_str_new2("");
447
+ }
448
+
449
+ if ((tmpchrs = curl_escape(StringValuePtr(tmpcontent), RSTRING_LEN(tmpcontent))) == NULL) {
450
+ rb_raise(eCurlErrInvalidPostField, "Failed to url-encode content `%s'", tmpchrs);
451
+ } else {
452
+ VALUE escd_content = rb_str_new2(tmpchrs);
453
+ curl_free(tmpchrs);
454
+
455
+ result = escd_name;
456
+ rb_str_cat(result, "=", 1);
457
+ rb_str_concat(result, escd_content);
458
+ }
459
+ }
460
+ } else {
461
+ rb_raise(eCurlErrInvalidPostField, "Cannot convert unnamed field to string");
462
+ }
463
+ } else {
464
+ rb_raise(eCurlErrInvalidPostField, "Cannot convert non-content field to string");
465
+ }
466
+
467
+ return result;
468
+ }
469
+
470
+
471
+ /* =================== INIT LIB =====================*/
472
+ void init_curb_postfield() {
473
+ idCall = rb_intern("call");
474
+
475
+ cCurlPostField = rb_define_class_under(mCurl, "PostField", rb_cObject);
476
+
477
+ /* Class methods */
478
+ rb_define_singleton_method(cCurlPostField, "content", ruby_curl_postfield_new_content, -1);
479
+ rb_define_singleton_method(cCurlPostField, "file", ruby_curl_postfield_new_file, -1);
480
+
481
+ VALUE sc = rb_singleton_class(cCurlPostField);
482
+ rb_undef(sc, rb_intern("new"));
483
+
484
+ rb_define_method(cCurlPostField, "name=", ruby_curl_postfield_name_set, 1);
485
+ rb_define_method(cCurlPostField, "name", ruby_curl_postfield_name_get, 0);
486
+ rb_define_method(cCurlPostField, "content=", ruby_curl_postfield_content_set, 1);
487
+ rb_define_method(cCurlPostField, "content", ruby_curl_postfield_content_get, 0);
488
+ rb_define_method(cCurlPostField, "content_type=", ruby_curl_postfield_content_type_set, 1);
489
+ rb_define_method(cCurlPostField, "content_type", ruby_curl_postfield_content_type_get, 0);
490
+ rb_define_method(cCurlPostField, "local_file=", ruby_curl_postfield_local_file_set, 1);
491
+ rb_define_method(cCurlPostField, "local_file", ruby_curl_postfield_local_file_get, 0);
492
+ rb_define_method(cCurlPostField, "remote_file=", ruby_curl_postfield_remote_file_set, 1);
493
+ rb_define_method(cCurlPostField, "remote_file", ruby_curl_postfield_remote_file_get, 0);
494
+
495
+ rb_define_method(cCurlPostField, "set_content_proc", ruby_curl_postfield_content_proc_set, -1);
496
+
497
+ rb_define_method(cCurlPostField, "to_str", ruby_curl_postfield_to_str, 0);
498
+ rb_define_alias(cCurlPostField, "to_s", "to_str");
499
+ }
@@ -0,0 +1,40 @@
1
+ /* curb_postfield.h - Field class for POST method
2
+ * Copyright (c)2006 Ross Bamford.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ *
5
+ * $Id: curb_postfield.h 4 2006-11-17 18:35:31Z roscopeco $
6
+ */
7
+ #ifndef __CURB_POSTFIELD_H
8
+ #define __CURB_POSTFIELD_H
9
+
10
+ #include "curb.h"
11
+
12
+ /*
13
+ * postfield doesn't actually wrap a curl_httppost - instead,
14
+ * it just holds together some ruby objects and has a C-side
15
+ * method to add it to a given form list during the perform.
16
+ */
17
+ typedef struct {
18
+ /* Objects we associate */
19
+ VALUE name;
20
+ VALUE content;
21
+ VALUE content_type;
22
+ VALUE content_proc;
23
+ VALUE local_file;
24
+ VALUE remote_file;
25
+
26
+ /* this will sometimes hold a string, which is the result
27
+ * of the content_proc invocation. We need it to hang around.
28
+ */
29
+ VALUE buffer_str;
30
+ } ruby_curl_postfield;
31
+
32
+ extern VALUE cCurlPostField;
33
+
34
+ void append_to_form(VALUE self,
35
+ struct curl_httppost **first,
36
+ struct curl_httppost **last);
37
+
38
+ void init_curb_postfield();
39
+
40
+ #endif
data/ext/curl.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'curb'
2
+
data/ext/extconf.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('curl')
4
+
5
+ if find_executable('curl-config')
6
+ $CFLAGS << " #{`curl-config --cflags`.strip}"
7
+ $LIBS << " #{`curl-config --libs`.strip}"
8
+ elsif !have_library('curl') or !have_header('curl/curl.h')
9
+ fail <<-EOM
10
+ Can't find libcurl or curl/curl.h
11
+
12
+ Try passing --with-curl-dir or --with-curl-lib and --with-curl-include
13
+ options to extconf.
14
+ EOM
15
+ end
16
+
17
+ #install_rb("curb.rb", "$(RUBYLIBDIR)", '../lib')
18
+ #install_rb("curl.rb", "$(RUBYLIBDIR)", '../lib')
19
+ $INSTALLFILES = [["curb.rb", "$(RUBYLIBDIR)", "../ext"], ["curl.rb", "$(RUBYLIBDIR)", "../ext"]]
20
+
21
+ if try_compile('int main() { return 0; }','-Wall')
22
+ $CFLAGS << ' -Wall'
23
+ end
24
+
25
+ create_makefile('curb_core')
data/tests/helper.rb ADDED
@@ -0,0 +1,71 @@
1
+ # DO NOT REMOVE THIS COMMENT - PART OF TESTMODEL.
2
+ # Copyright (c)2006 Ross Bamford. See LICENSE.
3
+ $CURB_TESTING = true
4
+ require 'uri'
5
+
6
+ $TOPDIR = File.expand_path(File.join(File.dirname(__FILE__), '..'))
7
+ $EXTDIR = File.join($TOPDIR, 'ext')
8
+ $LIBDIR = File.join($TOPDIR, 'lib')
9
+ $:.unshift($LIBDIR)
10
+ $:.unshift($EXTDIR)
11
+
12
+ require 'curb'
13
+ require 'test/unit'
14
+
15
+ $TEST_URL = "file://#{URI.escape(File.expand_path(__FILE__).tr('\\','/').tr(':','|'))}"
16
+
17
+ require 'thread'
18
+ require 'webrick'
19
+
20
+ # keep webrick quiet
21
+ class ::WEBrick::HTTPServer
22
+ def access_log(config, req, res)
23
+ # nop
24
+ end
25
+ end
26
+ class ::WEBrick::BasicLog
27
+ def log(level, data)
28
+ # nop
29
+ end
30
+ end
31
+
32
+ #
33
+ # Simple test server to record number of times a request is sent/recieved of a specific
34
+ # request type, e.g. GET,POST,PUT,DELETE
35
+ #
36
+ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
37
+
38
+ def self.port
39
+ 9129
40
+ end
41
+
42
+ def self.path
43
+ '/methods'
44
+ end
45
+
46
+ def self.url
47
+ "http://127.0.0.1:#{port}#{path}"
48
+ end
49
+
50
+ def respond_with(method,req,res)
51
+ res.body = method.to_s
52
+ res['Content-Type'] = "text/plain"
53
+ end
54
+
55
+ def do_GET(req,res)
56
+ respond_with(:GET,req,res)
57
+ end
58
+
59
+ def do_POST(req,res)
60
+ respond_with(:POST,req,res)
61
+ end
62
+
63
+ def do_PUT(req,res)
64
+ respond_with(:PUT,req,res)
65
+ end
66
+
67
+ def do_DELETE(req,res)
68
+ respond_with(:DELETE,req,res)
69
+ end
70
+
71
+ end