rhack 1.1.8 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +6 -14
  2. data/Rakefile +2 -1
  3. data/config/rhack.yml.template +1 -0
  4. data/ext/curb-original/curb.c +977 -977
  5. data/ext/curb-original/curb.h +52 -52
  6. data/ext/curb-original/curb_config.h +238 -238
  7. data/ext/curb-original/curb_easy.c +3404 -3404
  8. data/ext/curb-original/curb_easy.h +90 -90
  9. data/ext/curb-original/curb_errors.c +647 -647
  10. data/ext/curb-original/curb_errors.h +129 -129
  11. data/ext/curb-original/curb_macros.h +159 -159
  12. data/ext/curb-original/curb_multi.c +633 -633
  13. data/ext/curb-original/curb_multi.h +26 -26
  14. data/ext/curb-original/curb_postfield.c +523 -523
  15. data/ext/curb-original/curb_postfield.h +40 -40
  16. data/ext/curb-original/curb_upload.c +80 -80
  17. data/ext/curb-original/curb_upload.h +30 -30
  18. data/ext/curb/curb.c +977 -977
  19. data/ext/curb/curb.h +52 -52
  20. data/ext/curb/curb_config.h +270 -270
  21. data/ext/curb/curb_easy.c +3434 -3434
  22. data/ext/curb/curb_easy.h +94 -94
  23. data/ext/curb/curb_errors.c +647 -647
  24. data/ext/curb/curb_errors.h +129 -129
  25. data/ext/curb/curb_macros.h +162 -162
  26. data/ext/curb/curb_multi.c +702 -702
  27. data/ext/curb/curb_multi.h +26 -26
  28. data/ext/curb/curb_postfield.c +523 -523
  29. data/ext/curb/curb_postfield.h +40 -40
  30. data/ext/curb/curb_upload.c +80 -80
  31. data/ext/curb/curb_upload.h +30 -30
  32. data/lib/rhack.rb +4 -1
  33. data/lib/rhack/clients/oauth.rb +1 -1
  34. data/lib/rhack/js/browser/env.js +697 -697
  35. data/lib/rhack/js/browser/jquery.js +7180 -7180
  36. data/lib/rhack/js/browser/xmlsax.js +1564 -1564
  37. data/lib/rhack/js/browser/xmlw3cdom_1.js +1443 -1443
  38. data/lib/rhack/js/browser/xmlw3cdom_2.js +2744 -2744
  39. data/lib/rhack/page.rb +6 -2
  40. data/lib/rhack/storage.rb +1 -1
  41. data/lib/rhack/version.rb +1 -1
  42. data/rhack.gemspec +1 -1
  43. metadata +16 -16
@@ -1,26 +1,26 @@
1
- /* curb_multi.h - Curl easy mode
2
- * Copyright (c)2008 Todd A. Fisher.
3
- * Licensed under the Ruby License. See LICENSE for details.
4
- *
5
- * $Id$
6
- */
7
- #ifndef __CURB_MULTI_H
8
- #define __CURB_MULTI_H
9
-
10
- #include "curb.h"
11
- #include "curb_easy.h"
12
- #include <curl/multi.h>
13
-
14
- typedef struct {
15
- int active;
16
- int running;
17
- VALUE requests; /* hash of handles currently added */
18
- CURLM *handle;
19
- } ruby_curl_multi;
20
-
21
- extern VALUE cCurlMulti;
22
- void init_curb_multi();
23
- VALUE ruby_curl_multi_new(VALUE klass);
24
-
25
-
26
- #endif
1
+ /* curb_multi.h - Curl easy mode
2
+ * Copyright (c)2008 Todd A. Fisher.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ *
5
+ * $Id$
6
+ */
7
+ #ifndef __CURB_MULTI_H
8
+ #define __CURB_MULTI_H
9
+
10
+ #include "curb.h"
11
+ #include "curb_easy.h"
12
+ #include <curl/multi.h>
13
+
14
+ typedef struct {
15
+ int active;
16
+ int running;
17
+ VALUE requests; /* hash of handles currently added */
18
+ CURLM *handle;
19
+ } ruby_curl_multi;
20
+
21
+ extern VALUE cCurlMulti;
22
+ void init_curb_multi();
23
+ VALUE ruby_curl_multi_new(VALUE klass);
24
+
25
+
26
+ #endif
@@ -1,523 +1,523 @@
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, 1, 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, 1, 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
- const char *reason = NULL;
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) => #&lt;Curl::PostField...&gt;
199
- * Curl::PostField.content(name, content, content_type = nil) => #&lt;Curl::PostField...&gt;
200
- * Curl::PostField.content(name, content_type = nil) { |field| ... } => #&lt;Curl::PostField...&gt;
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) => #&lt;Curl::PostField...&gt;
245
- * Curl::PostField.file(name, local_file_name, remote_file_name = local_file_name) => #&lt;Curl::PostField...&gt;
246
- * Curl::PostField.file(name, remote_file_name) { |field| ... } => #&lt;Curl::PostField...&gt;
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| ... } => &lt;old proc&gt;
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
- VALUE name = Qnil;
428
- char *tmpchrs;
429
-
430
- Data_Get_Struct(self, ruby_curl_postfield, rbcpf);
431
-
432
- if (rbcpf->name != Qnil) {
433
- name = rbcpf->name;
434
- if (rb_type(name) == T_STRING) {
435
- name = rbcpf->name;
436
- } else if (rb_respond_to(name,rb_intern("to_s"))) {
437
- name = rb_funcall(name, rb_intern("to_s"), 0);
438
- }
439
- else {
440
- name = Qnil; // we can't handle this object
441
- }
442
- }
443
- if (name == Qnil) {
444
- rb_raise(eCurlErrInvalidPostField, "Cannot convert unnamed field to string %s:%d, make sure your field name responds_to :to_s", __FILE__, __LINE__);
445
- }
446
-
447
- tmpchrs = curl_escape(StringValuePtr(name), (int)RSTRING_LEN(name));
448
-
449
- if (!tmpchrs) {
450
- rb_raise(eCurlErrInvalidPostField, "Failed to url-encode name `%s'", tmpchrs);
451
- } else {
452
- VALUE tmpcontent = Qnil;
453
- VALUE escd_name = rb_str_new2(tmpchrs);
454
- curl_free(tmpchrs);
455
-
456
- if (rbcpf->content_proc != Qnil) {
457
- tmpcontent = rb_funcall(rbcpf->content_proc, idCall, 1, self);
458
- } else if (rbcpf->content != Qnil) {
459
- tmpcontent = rbcpf->content;
460
- } else if (rbcpf->local_file != Qnil) {
461
- tmpcontent = rbcpf->local_file;
462
- } else if (rbcpf->remote_file != Qnil) {
463
- tmpcontent = rbcpf->remote_file;
464
- } else {
465
- tmpcontent = rb_str_new2("");
466
- }
467
- if (TYPE(tmpcontent) != T_STRING) {
468
- if (rb_respond_to(tmpcontent, rb_intern("to_s"))) {
469
- tmpcontent = rb_funcall(tmpcontent, rb_intern("to_s"), 0);
470
- }
471
- else {
472
- rb_raise(rb_eRuntimeError, "postfield(%s) is not a string and does not respond_to to_s", RSTRING_PTR(escd_name) );
473
- }
474
- }
475
- //fprintf(stderr, "encoding content: %ld - %s\n", RSTRING_LEN(tmpcontent), RSTRING_PTR(tmpcontent) );
476
- tmpchrs = curl_escape(RSTRING_PTR(tmpcontent), (int)RSTRING_LEN(tmpcontent));
477
- if (!tmpchrs) {
478
- rb_raise(eCurlErrInvalidPostField, "Failed to url-encode content `%s'", tmpchrs);
479
- } else {
480
- VALUE escd_content = rb_str_new2(tmpchrs);
481
- curl_free(tmpchrs);
482
-
483
- result = escd_name;
484
- rb_str_cat(result, "=", 1);
485
- rb_str_concat(result, escd_content);
486
- }
487
- }
488
-
489
- return result;
490
- }
491
-
492
-
493
- /* =================== INIT LIB =====================*/
494
- void init_curb_postfield() {
495
- VALUE sc;
496
-
497
- idCall = rb_intern("call");
498
-
499
- cCurlPostField = rb_define_class_under(mCurl, "PostField", rb_cObject);
500
-
501
- /* Class methods */
502
- rb_define_singleton_method(cCurlPostField, "content", ruby_curl_postfield_new_content, -1);
503
- rb_define_singleton_method(cCurlPostField, "file", ruby_curl_postfield_new_file, -1);
504
-
505
- sc = rb_singleton_class(cCurlPostField);
506
- rb_undef(sc, rb_intern("new"));
507
-
508
- rb_define_method(cCurlPostField, "name=", ruby_curl_postfield_name_set, 1);
509
- rb_define_method(cCurlPostField, "name", ruby_curl_postfield_name_get, 0);
510
- rb_define_method(cCurlPostField, "content=", ruby_curl_postfield_content_set, 1);
511
- rb_define_method(cCurlPostField, "content", ruby_curl_postfield_content_get, 0);
512
- rb_define_method(cCurlPostField, "content_type=", ruby_curl_postfield_content_type_set, 1);
513
- rb_define_method(cCurlPostField, "content_type", ruby_curl_postfield_content_type_get, 0);
514
- rb_define_method(cCurlPostField, "local_file=", ruby_curl_postfield_local_file_set, 1);
515
- rb_define_method(cCurlPostField, "local_file", ruby_curl_postfield_local_file_get, 0);
516
- rb_define_method(cCurlPostField, "remote_file=", ruby_curl_postfield_remote_file_set, 1);
517
- rb_define_method(cCurlPostField, "remote_file", ruby_curl_postfield_remote_file_get, 0);
518
-
519
- rb_define_method(cCurlPostField, "set_content_proc", ruby_curl_postfield_content_proc_set, -1);
520
-
521
- rb_define_method(cCurlPostField, "to_str", ruby_curl_postfield_to_str, 0);
522
- rb_define_alias(cCurlPostField, "to_s", "to_str");
523
- }
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, 1, 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, 1, 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
+ const char *reason = NULL;
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) => #&lt;Curl::PostField...&gt;
199
+ * Curl::PostField.content(name, content, content_type = nil) => #&lt;Curl::PostField...&gt;
200
+ * Curl::PostField.content(name, content_type = nil) { |field| ... } => #&lt;Curl::PostField...&gt;
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) => #&lt;Curl::PostField...&gt;
245
+ * Curl::PostField.file(name, local_file_name, remote_file_name = local_file_name) => #&lt;Curl::PostField...&gt;
246
+ * Curl::PostField.file(name, remote_file_name) { |field| ... } => #&lt;Curl::PostField...&gt;
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| ... } => &lt;old proc&gt;
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
+ VALUE name = Qnil;
428
+ char *tmpchrs;
429
+
430
+ Data_Get_Struct(self, ruby_curl_postfield, rbcpf);
431
+
432
+ if (rbcpf->name != Qnil) {
433
+ name = rbcpf->name;
434
+ if (rb_type(name) == T_STRING) {
435
+ name = rbcpf->name;
436
+ } else if (rb_respond_to(name,rb_intern("to_s"))) {
437
+ name = rb_funcall(name, rb_intern("to_s"), 0);
438
+ }
439
+ else {
440
+ name = Qnil; // we can't handle this object
441
+ }
442
+ }
443
+ if (name == Qnil) {
444
+ rb_raise(eCurlErrInvalidPostField, "Cannot convert unnamed field to string %s:%d, make sure your field name responds_to :to_s", __FILE__, __LINE__);
445
+ }
446
+
447
+ tmpchrs = curl_escape(StringValuePtr(name), (int)RSTRING_LEN(name));
448
+
449
+ if (!tmpchrs) {
450
+ rb_raise(eCurlErrInvalidPostField, "Failed to url-encode name `%s'", tmpchrs);
451
+ } else {
452
+ VALUE tmpcontent = Qnil;
453
+ VALUE escd_name = rb_str_new2(tmpchrs);
454
+ curl_free(tmpchrs);
455
+
456
+ if (rbcpf->content_proc != Qnil) {
457
+ tmpcontent = rb_funcall(rbcpf->content_proc, idCall, 1, self);
458
+ } else if (rbcpf->content != Qnil) {
459
+ tmpcontent = rbcpf->content;
460
+ } else if (rbcpf->local_file != Qnil) {
461
+ tmpcontent = rbcpf->local_file;
462
+ } else if (rbcpf->remote_file != Qnil) {
463
+ tmpcontent = rbcpf->remote_file;
464
+ } else {
465
+ tmpcontent = rb_str_new2("");
466
+ }
467
+ if (TYPE(tmpcontent) != T_STRING) {
468
+ if (rb_respond_to(tmpcontent, rb_intern("to_s"))) {
469
+ tmpcontent = rb_funcall(tmpcontent, rb_intern("to_s"), 0);
470
+ }
471
+ else {
472
+ rb_raise(rb_eRuntimeError, "postfield(%s) is not a string and does not respond_to to_s", RSTRING_PTR(escd_name) );
473
+ }
474
+ }
475
+ //fprintf(stderr, "encoding content: %ld - %s\n", RSTRING_LEN(tmpcontent), RSTRING_PTR(tmpcontent) );
476
+ tmpchrs = curl_escape(RSTRING_PTR(tmpcontent), (int)RSTRING_LEN(tmpcontent));
477
+ if (!tmpchrs) {
478
+ rb_raise(eCurlErrInvalidPostField, "Failed to url-encode content `%s'", tmpchrs);
479
+ } else {
480
+ VALUE escd_content = rb_str_new2(tmpchrs);
481
+ curl_free(tmpchrs);
482
+
483
+ result = escd_name;
484
+ rb_str_cat(result, "=", 1);
485
+ rb_str_concat(result, escd_content);
486
+ }
487
+ }
488
+
489
+ return result;
490
+ }
491
+
492
+
493
+ /* =================== INIT LIB =====================*/
494
+ void init_curb_postfield() {
495
+ VALUE sc;
496
+
497
+ idCall = rb_intern("call");
498
+
499
+ cCurlPostField = rb_define_class_under(mCurl, "PostField", rb_cObject);
500
+
501
+ /* Class methods */
502
+ rb_define_singleton_method(cCurlPostField, "content", ruby_curl_postfield_new_content, -1);
503
+ rb_define_singleton_method(cCurlPostField, "file", ruby_curl_postfield_new_file, -1);
504
+
505
+ sc = rb_singleton_class(cCurlPostField);
506
+ rb_undef(sc, rb_intern("new"));
507
+
508
+ rb_define_method(cCurlPostField, "name=", ruby_curl_postfield_name_set, 1);
509
+ rb_define_method(cCurlPostField, "name", ruby_curl_postfield_name_get, 0);
510
+ rb_define_method(cCurlPostField, "content=", ruby_curl_postfield_content_set, 1);
511
+ rb_define_method(cCurlPostField, "content", ruby_curl_postfield_content_get, 0);
512
+ rb_define_method(cCurlPostField, "content_type=", ruby_curl_postfield_content_type_set, 1);
513
+ rb_define_method(cCurlPostField, "content_type", ruby_curl_postfield_content_type_get, 0);
514
+ rb_define_method(cCurlPostField, "local_file=", ruby_curl_postfield_local_file_set, 1);
515
+ rb_define_method(cCurlPostField, "local_file", ruby_curl_postfield_local_file_get, 0);
516
+ rb_define_method(cCurlPostField, "remote_file=", ruby_curl_postfield_remote_file_set, 1);
517
+ rb_define_method(cCurlPostField, "remote_file", ruby_curl_postfield_remote_file_get, 0);
518
+
519
+ rb_define_method(cCurlPostField, "set_content_proc", ruby_curl_postfield_content_proc_set, -1);
520
+
521
+ rb_define_method(cCurlPostField, "to_str", ruby_curl_postfield_to_str, 0);
522
+ rb_define_alias(cCurlPostField, "to_s", "to_str");
523
+ }