rhack 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gemtest +0 -0
  2. data/CURB-LICENSE +51 -0
  3. data/Gemfile +4 -0
  4. data/History.txt +4 -0
  5. data/LICENSE +51 -0
  6. data/License.txt +17 -0
  7. data/Manifest.txt +61 -0
  8. data/README.txt +12 -0
  9. data/Rakefile +34 -0
  10. data/ext/curb-original/curb.c +977 -0
  11. data/ext/curb-original/curb.h +52 -0
  12. data/ext/curb-original/curb_config.h +235 -0
  13. data/ext/curb-original/curb_easy.c +3455 -0
  14. data/ext/curb-original/curb_easy.h +90 -0
  15. data/ext/curb-original/curb_errors.c +647 -0
  16. data/ext/curb-original/curb_errors.h +129 -0
  17. data/ext/curb-original/curb_macros.h +159 -0
  18. data/ext/curb-original/curb_multi.c +704 -0
  19. data/ext/curb-original/curb_multi.h +26 -0
  20. data/ext/curb-original/curb_postfield.c +523 -0
  21. data/ext/curb-original/curb_postfield.h +40 -0
  22. data/ext/curb-original/curb_upload.c +80 -0
  23. data/ext/curb-original/curb_upload.h +30 -0
  24. data/ext/curb/Makefile +157 -0
  25. data/ext/curb/curb.c +977 -0
  26. data/ext/curb/curb.h +52 -0
  27. data/ext/curb/curb_config.h +235 -0
  28. data/ext/curb/curb_easy.c +3430 -0
  29. data/ext/curb/curb_easy.h +94 -0
  30. data/ext/curb/curb_errors.c +647 -0
  31. data/ext/curb/curb_errors.h +129 -0
  32. data/ext/curb/curb_macros.h +159 -0
  33. data/ext/curb/curb_multi.c +710 -0
  34. data/ext/curb/curb_multi.h +26 -0
  35. data/ext/curb/curb_postfield.c +523 -0
  36. data/ext/curb/curb_postfield.h +40 -0
  37. data/ext/curb/curb_upload.c +80 -0
  38. data/ext/curb/curb_upload.h +30 -0
  39. data/ext/curb/extconf.rb +399 -0
  40. data/lib/cache.rb +44 -0
  41. data/lib/curl-global.rb +151 -0
  42. data/lib/extensions/browser/env.js +697 -0
  43. data/lib/extensions/browser/jquery.js +7180 -0
  44. data/lib/extensions/browser/xmlsax.js +1564 -0
  45. data/lib/extensions/browser/xmlw3cdom_1.js +1444 -0
  46. data/lib/extensions/browser/xmlw3cdom_2.js +2744 -0
  47. data/lib/extensions/curb.rb +125 -0
  48. data/lib/extensions/declarative.rb +153 -0
  49. data/lib/extensions/johnson.rb +63 -0
  50. data/lib/frame.rb +766 -0
  51. data/lib/init.rb +36 -0
  52. data/lib/rhack.rb +16 -0
  53. data/lib/rhack.yml.template +19 -0
  54. data/lib/rhack/proxy/checker.rb +226 -0
  55. data/lib/rhack/proxy/list.rb +196 -0
  56. data/lib/rhack/services.rb +445 -0
  57. data/lib/rhack_in.rb +2 -0
  58. data/lib/scout.rb +591 -0
  59. data/lib/words.rb +37 -0
  60. data/test/test_frame.rb +107 -0
  61. data/test/test_rhack.rb +5 -0
  62. data/test/test_scout.rb +53 -0
  63. metadata +195 -0
@@ -0,0 +1,52 @@
1
+ /* Curb - Libcurl(3) bindings for Ruby.
2
+ * Copyright (c)2006 Ross Bamford.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ *
5
+ * $Id: curb.h 39 2006-12-23 15:28:45Z roscopeco $
6
+ */
7
+
8
+ #ifndef __CURB_H
9
+ #define __CURB_H
10
+
11
+ #include <ruby.h>
12
+ #include <curl/curl.h>
13
+
14
+ #include "curb_config.h"
15
+ #include "curb_easy.h"
16
+ #include "curb_errors.h"
17
+ #include "curb_postfield.h"
18
+ #include "curb_multi.h"
19
+
20
+ #include "curb_macros.h"
21
+
22
+ // These should be managed from the Rake 'release' task.
23
+ #define CURB_VERSION "0.8.1"
24
+ #define CURB_VER_NUM 801
25
+ #define CURB_VER_MAJ 0
26
+ #define CURB_VER_MIN 8
27
+ #define CURB_VER_MIC 1
28
+ #define CURB_VER_PATCH 0
29
+
30
+
31
+ // Maybe not yet defined in Ruby
32
+ #ifndef RSTRING_LEN
33
+ #define RSTRING_LEN(x) RSTRING(x)->len
34
+ #endif
35
+
36
+ #ifndef RSTRING_PTR
37
+ #define RSTRING_PTR(x) RSTRING(x)->ptr
38
+ #endif
39
+
40
+ #ifndef RHASH_LEN
41
+ #ifdef HAVE_RUBY19_HASH
42
+ #define RHASH_LEN(hash) RHASH(hash)->ntbl->num_entries
43
+ #else
44
+ #define RHASH_LEN(hash) RHASH(hash)->tbl->num_entries
45
+ #endif
46
+ #endif
47
+
48
+ extern VALUE mCurl;
49
+
50
+ extern void Init_curb_core();
51
+
52
+ #endif
@@ -0,0 +1,235 @@
1
+ #ifndef CURB_CONFIG_H
2
+ #define CURB_CONFIG_H
3
+ #define HAVE_CURL_CONFIG_CA 1
4
+ #define CURL_CONFIG_CA "/etc/ssl/certs/ca-certificates.crt"
5
+ #define HAVE_CURLINFO_REDIRECT_TIME 1
6
+ #define HAVE_CURLINFO_RESPONSE_CODE 1
7
+ #define HAVE_CURLINFO_FILETIME 1
8
+ #define HAVE_CURLINFO_REDIRECT_COUNT 1
9
+ #define HAVE_CURLINFO_OS_ERRNO 1
10
+ #define HAVE_CURLINFO_NUM_CONNECTS 1
11
+ #define HAVE_CURLINFO_FTP_ENTRY_PATH 1
12
+ #define HAVE_CURL_VERSION_SSL 1
13
+ #define HAVE_CURL_VERSION_LIBZ 1
14
+ #define HAVE_CURL_VERSION_NTLM 1
15
+ #define HAVE_CURL_VERSION_GSSNEGOTIATE 1
16
+ #define HAVE_CURL_VERSION_DEBUG 1
17
+ #define HAVE_CURL_VERSION_ASYNCHDNS 1
18
+ #define HAVE_CURL_VERSION_SPNEGO 1
19
+ #define HAVE_CURL_VERSION_LARGEFILE 1
20
+ #define HAVE_CURL_VERSION_IDN 1
21
+ #define HAVE_CURL_VERSION_SSPI 1
22
+ #define HAVE_CURL_VERSION_CONV 1
23
+ #define HAVE_CURLPROXY_HTTP 1
24
+ #define HAVE_CURLPROXY_SOCKS4 1
25
+ #define HAVE_CURLPROXY_SOCKS5 1
26
+ #define HAVE_CURLAUTH_BASIC 1
27
+ #define HAVE_CURLAUTH_DIGEST 1
28
+ #define HAVE_CURLAUTH_GSSNEGOTIATE 1
29
+ #define HAVE_CURLAUTH_NTLM 1
30
+ #define HAVE_CURLAUTH_ANYSAFE 1
31
+ #define HAVE_CURLAUTH_ANY 1
32
+ #define HAVE_CURLE_TFTP_NOTFOUND 1
33
+ #define HAVE_CURLE_TFTP_PERM 1
34
+ #define HAVE_CURLE_TFTP_DISKFULL 1
35
+ #define HAVE_CURLE_TFTP_ILLEGAL 1
36
+ #define HAVE_CURLE_TFTP_UNKNOWNID 1
37
+ #define HAVE_CURLE_TFTP_EXISTS 1
38
+ #define HAVE_CURLE_TFTP_NOSUCHUSER 1
39
+ #define HAVE_CURLE_SEND_FAIL_REWIND 1
40
+ #define HAVE_CURLE_SSL_ENGINE_INITFAILED 1
41
+ #define HAVE_CURLE_LOGIN_DENIED 1
42
+ #define HAVE_CURLMOPT_MAXCONNECTS 1
43
+ #define HAVE_CURLOPT_SEEKFUNCTION 1
44
+ #define HAVE_CURLOPT_SEEKDATA 1
45
+ #define HAVE_CURLOPT_SOCKOPTFUNCTION 1
46
+ #define HAVE_CURLOPT_SOCKOPTDATA 1
47
+ #define HAVE_CURLOPT_OPENSOCKETFUNCTION 1
48
+ #define HAVE_CURLOPT_OPENSOCKETDATA 1
49
+ #define HAVE_CURLE_CONV_FAILED 1
50
+ #define HAVE_CURLE_CONV_REQD 1
51
+ #define HAVE_CURLE_SSL_CACERT_BADFILE 1
52
+ #define HAVE_CURLE_REMOTE_FILE_NOT_FOUND 1
53
+ #define HAVE_CURLE_SSH 1
54
+ #define HAVE_CURLE_SSL_SHUTDOWN_FAILED 1
55
+ #define HAVE_CURLE_AGAIN 1
56
+ #define HAVE_CURLE_SSL_CRL_BADFILE 1
57
+ #define HAVE_CURLE_SSL_ISSUER_ERROR 1
58
+ #define HAVE_CURLINFO_REDIRECT_URL 1
59
+ #define HAVE_CURLOPT_USERNAME 1
60
+ #define HAVE_CURLOPT_PASSWORD 1
61
+ #define HAVE_CURLINFO_PRIMARY_IP 1
62
+ #define HAVE_CURLAUTH_DIGEST_IE 1
63
+ #define HAVE_CURLFTPMETHOD_MULTICWD 1
64
+ #define HAVE_CURLFTPMETHOD_NOCWD 1
65
+ #define HAVE_CURLFTPMETHOD_SINGLECWD 1
66
+ #define HAVE_CURLM_BAD_SOCKET 1
67
+ #define HAVE_CURLM_UNKNOWN_OPTION 1
68
+ #define HAVE_CURL_MULTI_TIMEOUT 1
69
+ #define HAVE_CURL_MULTI_FDSET 1
70
+ #define HAVE_CURL_MULTI_PERFORM 1
71
+ #define HAVE_CURLOPT_ERRORBUFFER 1
72
+ #define HAVE_CURLOPT_STDERR 1
73
+ #define HAVE_CURLOPT_FAILONERROR 1
74
+ #define HAVE_CURLOPT_URL 1
75
+ #define HAVE_CURLOPT_PROTOCOLS 1
76
+ #define HAVE_CURLOPT_REDIR_PROTOCOLS 1
77
+ #define HAVE_CURLOPT_PROXY 1
78
+ #define HAVE_CURLOPT_PROXYPORT 1
79
+ #define HAVE_CURLOPT_PROXYTYPE 1
80
+ #define HAVE_CURLOPT_NOPROXY 1
81
+ #define HAVE_CURLOPT_HTTPPROXYTUNNEL 1
82
+ #define HAVE_CURLOPT_SOCKS5_GSSAPI_SERVICE 1
83
+ #define HAVE_CURLOPT_SOCKS5_GSSAPI_NEC 1
84
+ #define HAVE_CURLOPT_INTERFACE 1
85
+ #define HAVE_CURLOPT_LOCALPORT 1
86
+ #define HAVE_CURLOPT_DNS_CACHE_TIMEOUT 1
87
+ #define HAVE_CURLOPT_DNS_USE_GLOBAL_CACHE 1
88
+ #define HAVE_CURLOPT_BUFFERSIZE 1
89
+ #define HAVE_CURLOPT_PORT 1
90
+ #define HAVE_CURLOPT_TCP_NODELAY 1
91
+ #define HAVE_CURLOPT_ADDRESS_SCOPE 1
92
+ #define HAVE_CURLOPT_NETRC 1
93
+ #define HAVE_CURL_NETRC_OPTIONAL 1
94
+ #define HAVE_CURL_NETRC_IGNORED 1
95
+ #define HAVE_CURL_NETRC_REQUIRED 1
96
+ #define HAVE_CURLOPT_NETRC_FILE 1
97
+ #define HAVE_CURLOPT_USERPWD 1
98
+ #define HAVE_CURLOPT_PROXYUSERPWD 1
99
+ #define HAVE_CURLOPT_USERNAME 1
100
+ #define HAVE_CURLOPT_PASSWORD 1
101
+ #define HAVE_CURLOPT_PASSWORD 1
102
+ #define HAVE_CURLOPT_PASSWORD 1
103
+ #define HAVE_CURLOPT_HTTPAUTH 1
104
+ #define HAVE_CURLAUTH_DIGEST_IE 1
105
+ #define HAVE_CURLOPT_PROXYAUTH 1
106
+ #define HAVE_CURLOPT_AUTOREFERER 1
107
+ #define HAVE_CURLOPT_ENCODING 1
108
+ #define HAVE_CURLOPT_FOLLOWLOCATION 1
109
+ #define HAVE_CURLOPT_UNRESTRICTED_AUTH 1
110
+ #define HAVE_CURLOPT_MAXREDIRS 1
111
+ #define HAVE_CURLOPT_POSTREDIR 1
112
+ #define HAVE_CURLOPT_PUT 1
113
+ #define HAVE_CURLOPT_POST 1
114
+ #define HAVE_CURLOPT_POSTFIELDS 1
115
+ #define HAVE_CURLOPT_POSTFIELDSIZE 1
116
+ #define HAVE_CURLOPT_POSTFIELDSIZE_LARGE 1
117
+ #define HAVE_CURLOPT_COPYPOSTFIELDS 1
118
+ #define HAVE_CURLOPT_HTTPPOST 1
119
+ #define HAVE_CURLOPT_REFERER 1
120
+ #define HAVE_CURLOPT_USERAGENT 1
121
+ #define HAVE_CURLOPT_HTTPHEADER 1
122
+ #define HAVE_CURLOPT_HTTP200ALIASES 1
123
+ #define HAVE_CURLOPT_COOKIE 1
124
+ #define HAVE_CURLOPT_COOKIEFILE 1
125
+ #define HAVE_CURLOPT_COOKIEJAR 1
126
+ #define HAVE_CURLOPT_COOKIESESSION 1
127
+ #define HAVE_CURLOPT_COOKIELIST 1
128
+ #define HAVE_CURLOPT_HTTPGET 1
129
+ #define HAVE_CURLOPT_HTTP_VERSION 1
130
+ #define HAVE_CURL_HTTP_VERSION_NONE 1
131
+ #define HAVE_CURL_HTTP_VERSION_1_0 1
132
+ #define HAVE_CURL_HTTP_VERSION_1_1 1
133
+ #define HAVE_CURLOPT_IGNORE_CONTENT_LENGTH 1
134
+ #define HAVE_CURLOPT_HTTP_CONTENT_DECODING 1
135
+ #define HAVE_CURLOPT_HTTP_TRANSFER_DECODING 1
136
+ #define HAVE_CURLOPT_TFTP_BLKSIZE 1
137
+ #define HAVE_CURLOPT_FTPPORT 1
138
+ #define HAVE_CURLOPT_QUOTE 1
139
+ #define HAVE_CURLOPT_POSTQUOTE 1
140
+ #define HAVE_CURLOPT_PREQUOTE 1
141
+ #define HAVE_CURLOPT_DIRLISTONLY 1
142
+ #define HAVE_CURLOPT_APPEND 1
143
+ #define HAVE_CURLOPT_FTP_USE_EPRT 1
144
+ #define HAVE_CURLOPT_FTP_USE_EPSV 1
145
+ #define HAVE_CURLOPT_FTP_CREATE_MISSING_DIRS 1
146
+ #define HAVE_CURLOPT_FTP_RESPONSE_TIMEOUT 1
147
+ #define HAVE_CURLOPT_FTP_ALTERNATIVE_TO_USER 1
148
+ #define HAVE_CURLOPT_FTP_SKIP_PASV_IP 1
149
+ #define HAVE_CURLOPT_FTPSSLAUTH 1
150
+ #define HAVE_CURLFTPAUTH_DEFAULT 1
151
+ #define HAVE_CURLFTPAUTH_SSL 1
152
+ #define HAVE_CURLFTPAUTH_TLS 1
153
+ #define HAVE_CURLOPT_FTP_SSL_CCC 1
154
+ #define HAVE_CURLFTPSSL_CCC_NONE 1
155
+ #define HAVE_CURLFTPSSL_CCC_PASSIVE 1
156
+ #define HAVE_CURLFTPSSL_CCC_ACTIVE 1
157
+ #define HAVE_CURLOPT_FTP_ACCOUNT 1
158
+ #define HAVE_CURLOPT_FTP_FILEMETHOD 1
159
+ #define HAVE_CURLFTPMETHOD_MULTICWD 1
160
+ #define HAVE_CURLFTPMETHOD_NOCWD 1
161
+ #define HAVE_CURLFTPMETHOD_SINGLECWD 1
162
+ #define HAVE_CURLOPT_TRANSFERTEXT 1
163
+ #define HAVE_CURLOPT_PROXY_TRANSFER_MODE 1
164
+ #define HAVE_CURLOPT_CRLF 1
165
+ #define HAVE_CURLOPT_RANGE 1
166
+ #define HAVE_CURLOPT_RESUME_FROM 1
167
+ #define HAVE_CURLOPT_RESUME_FROM_LARGE 1
168
+ #define HAVE_CURLOPT_CUSTOMREQUEST 1
169
+ #define HAVE_CURLOPT_FILETIME 1
170
+ #define HAVE_CURLOPT_NOBODY 1
171
+ #define HAVE_CURLOPT_INFILESIZE 1
172
+ #define HAVE_CURLOPT_INFILESIZE_LARGE 1
173
+ #define HAVE_CURLOPT_UPLOAD 1
174
+ #define HAVE_CURLOPT_MAXFILESIZE 1
175
+ #define HAVE_CURLOPT_MAXFILESIZE_LARGE 1
176
+ #define HAVE_CURLOPT_TIMECONDITION 1
177
+ #define HAVE_CURLOPT_TIMEVALUE 1
178
+ #define HAVE_CURLOPT_TIMEOUT 1
179
+ #define HAVE_CURLOPT_TIMEOUT_MS 1
180
+ #define HAVE_CURLOPT_LOW_SPEED_LIMIT 1
181
+ #define HAVE_CURLOPT_LOW_SPEED_TIME 1
182
+ #define HAVE_CURLOPT_MAX_SEND_SPEED_LARGE 1
183
+ #define HAVE_CURLOPT_MAX_RECV_SPEED_LARGE 1
184
+ #define HAVE_CURLOPT_MAXCONNECTS 1
185
+ #define HAVE_CURLOPT_CLOSEPOLICY 1
186
+ #define HAVE_CURLOPT_FRESH_CONNECT 1
187
+ #define HAVE_CURLOPT_FORBID_REUSE 1
188
+ #define HAVE_CURLOPT_CONNECTTIMEOUT 1
189
+ #define HAVE_CURLOPT_CONNECTTIMEOUT_MS 1
190
+ #define HAVE_CURLOPT_IPRESOLVE 1
191
+ #define HAVE_CURL_IPRESOLVE_WHATEVER 1
192
+ #define HAVE_CURL_IPRESOLVE_V4 1
193
+ #define HAVE_CURL_IPRESOLVE_V6 1
194
+ #define HAVE_CURLOPT_CONNECT_ONLY 1
195
+ #define HAVE_CURLOPT_USE_SSL 1
196
+ #define HAVE_CURLUSESSL_NONE 1
197
+ #define HAVE_CURLUSESSL_TRY 1
198
+ #define HAVE_CURLUSESSL_CONTROL 1
199
+ #define HAVE_CURLUSESSL_ALL 1
200
+ #define HAVE_CURLOPT_SSLCERT 1
201
+ #define HAVE_CURLOPT_SSLCERTTYPE 1
202
+ #define HAVE_CURLOPT_SSLKEY 1
203
+ #define HAVE_CURLOPT_SSLKEYTYPE 1
204
+ #define HAVE_CURLOPT_KEYPASSWD 1
205
+ #define HAVE_CURLOPT_SSLENGINE 1
206
+ #define HAVE_CURLOPT_SSLENGINE_DEFAULT 1
207
+ #define HAVE_CURLOPT_SSLVERSION 1
208
+ #define HAVE_CURL_SSLVERSION_DEFAULT 1
209
+ #define HAVE_CURL_SSLVERSION_TLSV1 1
210
+ #define HAVE_CURL_SSLVERSION_SSLV2 1
211
+ #define HAVE_CURL_SSLVERSION_SSLV3 1
212
+ #define HAVE_CURLOPT_SSL_VERIFYPEER 1
213
+ #define HAVE_CURLOPT_CAINFO 1
214
+ #define HAVE_CURLOPT_ISSUERCERT 1
215
+ #define HAVE_CURLOPT_CAPATH 1
216
+ #define HAVE_CURLOPT_CRLFILE 1
217
+ #define HAVE_CURLOPT_SSL_VERIFYHOST 1
218
+ #define HAVE_CURLOPT_CERTINFO 1
219
+ #define HAVE_CURLOPT_RANDOM_FILE 1
220
+ #define HAVE_CURLOPT_EGDSOCKET 1
221
+ #define HAVE_CURLOPT_SSL_CIPHER_LIST 1
222
+ #define HAVE_CURLOPT_SSL_SESSIONID_CACHE 1
223
+ #define HAVE_CURLOPT_KRBLEVEL 1
224
+ #define HAVE_CURLOPT_SSH_AUTH_TYPES 1
225
+ #define HAVE_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 1
226
+ #define HAVE_CURLOPT_SSH_PUBLIC_KEYFILE 1
227
+ #define HAVE_CURLOPT_SSH_PRIVATE_KEYFILE 1
228
+ #define HAVE_CURLOPT_PRIVATE 1
229
+ #define HAVE_CURLOPT_SHARE 1
230
+ #define HAVE_CURLOPT_NEW_FILE_PERMS 1
231
+ #define HAVE_CURLOPT_NEW_DIRECTORY_PERMS 1
232
+ #define HAVE_CURLOPT_TELNETOPTIONS 1
233
+ #define HAVE_CURLE_OBSOLETE 1
234
+ #define HAVE_CURL_EASY_ESCAPE 1
235
+ #endif
@@ -0,0 +1,3455 @@
1
+ /* curb_easy.c - Curl easy mode
2
+ * Copyright (c)2006 Ross Bamford.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ *
5
+ * $Id: curb_easy.c 30 2006-12-09 12:30:24Z roscopeco $
6
+ */
7
+ #include "curb_easy.h"
8
+ #include "curb_errors.h"
9
+ #include "curb_postfield.h"
10
+ #include "curb_upload.h"
11
+ #include "curb_multi.h"
12
+
13
+ #include <errno.h>
14
+ #include <string.h>
15
+
16
+ extern VALUE mCurl;
17
+
18
+ static VALUE idCall;
19
+ static VALUE idJoin;
20
+ static VALUE rbstrAmp;
21
+
22
+ #ifdef RDOC_NEVER_DEFINED
23
+ mCurl = rb_define_module("Curl");
24
+ #endif
25
+
26
+ VALUE cCurlEasy;
27
+
28
+
29
+ /* ================== CURL HANDLER FUNCS ==============*/
30
+
31
+ static VALUE callback_exception(VALUE unused) {
32
+ return Qfalse;
33
+ }
34
+
35
+ /* These handle both body and header data */
36
+ static size_t default_data_handler(char *stream,
37
+ size_t size,
38
+ size_t nmemb,
39
+ VALUE out) {
40
+ rb_str_buf_cat(out, stream, size * nmemb);
41
+ return size * nmemb;
42
+ }
43
+
44
+ // size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
45
+ static size_t read_data_handler(void *ptr,
46
+ size_t size,
47
+ size_t nmemb,
48
+ ruby_curl_easy *rbce) {
49
+ VALUE upload = rb_easy_get("upload");
50
+ size_t read_bytes = (size*nmemb);
51
+ VALUE stream = ruby_curl_upload_stream_get(upload);
52
+
53
+ if (rb_respond_to(stream, rb_intern("read"))) {//if (rb_respond_to(stream, rb_intern("to_s"))) {
54
+ /* copy read_bytes from stream into ptr */
55
+ VALUE str = rb_funcall(stream, rb_intern("read"), 1, rb_int_new(read_bytes) );
56
+ if( str != Qnil ) {
57
+ memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str));
58
+ return RSTRING_LEN(str);
59
+ }
60
+ else {
61
+ return 0;
62
+ }
63
+ }
64
+ else if (rb_respond_to(stream, rb_intern("to_s"))) {
65
+ ruby_curl_upload *rbcu;
66
+ VALUE str;
67
+ size_t len;
68
+ size_t remaining;
69
+ char *str_ptr;
70
+ Data_Get_Struct(upload, ruby_curl_upload, rbcu);
71
+ str = rb_funcall(stream, rb_intern("to_s"), 0);
72
+ len = RSTRING_LEN(str);
73
+ remaining = len - rbcu->offset;
74
+ str_ptr = RSTRING_PTR(str);
75
+
76
+ if( remaining < read_bytes ) {
77
+ if( remaining > 0 ) {
78
+ memcpy(ptr, str_ptr+rbcu->offset, remaining);
79
+ read_bytes = remaining;
80
+ rbcu->offset += remaining;
81
+ }
82
+ return remaining;
83
+ }
84
+ else if( remaining > read_bytes ) { // read_bytes <= remaining - send what we can fit in the buffer(ptr)
85
+ memcpy(ptr, str_ptr+rbcu->offset, read_bytes);
86
+ rbcu->offset += read_bytes;
87
+ }
88
+ else { // they're equal
89
+ memcpy(ptr, str_ptr+rbcu->offset, --read_bytes);
90
+ rbcu->offset += read_bytes;
91
+ }
92
+ return read_bytes;
93
+ }
94
+ else {
95
+ return 0;
96
+ }
97
+ }
98
+
99
+ static size_t proc_data_handler(char *stream,
100
+ size_t size,
101
+ size_t nmemb,
102
+ VALUE proc) {
103
+ VALUE procret;
104
+
105
+ procret = rb_funcall(proc, idCall, 1, rb_str_new(stream, size * nmemb));
106
+
107
+ switch (rb_type(procret)) {
108
+ case T_FIXNUM:
109
+ return FIX2LONG(procret);
110
+ case T_BIGNUM:
111
+ return NUM2LONG(procret);
112
+ default:
113
+ rb_warn("Curl data handlers should return the number of bytes read as an Integer");
114
+ return size * nmemb;
115
+ }
116
+ }
117
+
118
+ static size_t proc_data_handler_body(char *stream,
119
+ size_t size,
120
+ size_t nmemb,
121
+ ruby_curl_easy *rbce)
122
+ {
123
+ size_t ret;
124
+ rbce->callback_active = 1;
125
+ ret = proc_data_handler(stream, size, nmemb, rb_easy_get("body_proc"));
126
+ rbce->callback_active = 0;
127
+ return ret;
128
+ }
129
+ static size_t proc_data_handler_header(char *stream,
130
+ size_t size,
131
+ size_t nmemb,
132
+ ruby_curl_easy *rbce)
133
+ {
134
+ size_t ret;
135
+ rbce->callback_active = 1;
136
+ ret = proc_data_handler(stream, size, nmemb, rb_easy_get("header_proc"));
137
+ rbce->callback_active = 0;
138
+ return ret;
139
+ }
140
+
141
+
142
+ static VALUE call_progress_handler(VALUE ary) {
143
+ return rb_funcall(rb_ary_entry(ary, 0), idCall, 4,
144
+ rb_ary_entry(ary, 1), // rb_float_new(dltotal),
145
+ rb_ary_entry(ary, 2), // rb_float_new(dlnow),
146
+ rb_ary_entry(ary, 3), // rb_float_new(ultotal),
147
+ rb_ary_entry(ary, 4)); // rb_float_new(ulnow));
148
+ }
149
+
150
+ static int proc_progress_handler(VALUE proc,
151
+ double dltotal,
152
+ double dlnow,
153
+ double ultotal,
154
+ double ulnow) {
155
+ VALUE procret;
156
+ VALUE callargs = rb_ary_new2(5);
157
+
158
+ rb_ary_store(callargs, 0, proc);
159
+ rb_ary_store(callargs, 1, rb_float_new(dltotal));
160
+ rb_ary_store(callargs, 2, rb_float_new(dlnow));
161
+ rb_ary_store(callargs, 3, rb_float_new(ultotal));
162
+ rb_ary_store(callargs, 4, rb_float_new(ulnow));
163
+
164
+ //v = rb_rescue(range_check, (VALUE)args, range_failed, 0);
165
+ //procret = rb_funcall(proc, idCall, 4, rb_float_new(dltotal),
166
+ // rb_float_new(dlnow),
167
+ // rb_float_new(ultotal),
168
+ // rb_float_new(ulnow));
169
+ procret = rb_rescue(call_progress_handler, callargs, callback_exception, Qnil);
170
+
171
+ return(((procret == Qfalse) || (procret == Qnil)) ? -1 : 0);
172
+ }
173
+
174
+ static VALUE call_debug_handler(VALUE ary) {
175
+ return rb_funcall(rb_ary_entry(ary, 0), idCall, 2,
176
+ rb_ary_entry(ary, 1), // INT2FIX(type),
177
+ rb_ary_entry(ary, 2)); // rb_str_new(data, data_len)
178
+ }
179
+ static int proc_debug_handler(CURL *curl,
180
+ curl_infotype type,
181
+ char *data,
182
+ size_t data_len,
183
+ VALUE proc) {
184
+ VALUE callargs = rb_ary_new2(3);
185
+ rb_ary_store(callargs, 0, proc);
186
+ rb_ary_store(callargs, 1, INT2FIX(type));
187
+ rb_ary_store(callargs, 2, rb_str_new(data, data_len));
188
+ rb_rescue(call_debug_handler, callargs, callback_exception, Qnil);
189
+ /* no way to indicate to libcurl that we should break out given an exception in the on_debug handler...
190
+ * this means exceptions will be swallowed
191
+ */
192
+ //rb_funcall(proc, idCall, 2, INT2FIX(type), rb_str_new(data, data_len));
193
+ return 0;
194
+ }
195
+
196
+ /* ================== MARK/FREE FUNC ==================*/
197
+ void curl_easy_mark(ruby_curl_easy *rbce) {
198
+ if (!NIL_P(rbce->opts)) { rb_gc_mark(rbce->opts); }
199
+ if (!NIL_P(rbce->multi)) { rb_gc_mark(rbce->multi); }
200
+ }
201
+
202
+ static void ruby_curl_easy_free(ruby_curl_easy *rbce) {
203
+ if (rbce->curl_headers) {
204
+ curl_slist_free_all(rbce->curl_headers);
205
+ }
206
+
207
+ if (rbce->curl_ftp_commands) {
208
+ curl_slist_free_all(rbce->curl_ftp_commands);
209
+ }
210
+
211
+ if (rbce->curl) {
212
+ curl_easy_cleanup(rbce->curl);
213
+ }
214
+
215
+ if (rbce->first) {
216
+ curl_formfree(rbce->first);
217
+ }
218
+ }
219
+
220
+ void curl_easy_free(ruby_curl_easy *rbce) {
221
+ ruby_curl_easy_free(rbce);
222
+ free(rbce);
223
+ }
224
+
225
+
226
+ /* ================= ALLOC METHODS ====================*/
227
+
228
+ static void ruby_curl_easy_zero(ruby_curl_easy *rbce) {
229
+ rbce->opts = rb_hash_new();
230
+
231
+ rbce->curl_headers = NULL;
232
+ rbce->curl_ftp_commands = NULL;
233
+
234
+ /* various-typed opts */
235
+ rbce->local_port = 0;
236
+ rbce->local_port_range = 0;
237
+ rbce->proxy_port = 0;
238
+ rbce->proxy_type = -1;
239
+ rbce->http_auth_types = 0;
240
+ rbce->proxy_auth_types = 0;
241
+ rbce->max_redirs = -1;
242
+ rbce->timeout = 0;
243
+ rbce->connect_timeout = 0;
244
+ rbce->dns_cache_timeout = 60;
245
+ rbce->ftp_response_timeout = 0;
246
+ rbce->low_speed_limit = 0;
247
+ rbce->low_speed_time = 0;
248
+ rbce->ssl_version = -1;
249
+ rbce->use_ssl = -1;
250
+ rbce->ftp_filemethod = -1;
251
+ rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
252
+
253
+ /* bool opts */
254
+ rbce->proxy_tunnel = 0;
255
+ rbce->fetch_file_time = 0;
256
+ rbce->ssl_verify_peer = 1;
257
+ rbce->ssl_verify_host = 2;
258
+ rbce->header_in_body = 0;
259
+ rbce->use_netrc = 0;
260
+ rbce->follow_location = 0;
261
+ rbce->unrestricted_auth = 0;
262
+ rbce->verbose = 0;
263
+ rbce->multipart_form_post = 0;
264
+ rbce->enable_cookies = 0;
265
+ rbce->ignore_content_length = 0;
266
+ rbce->callback_active = 0;
267
+ }
268
+
269
+ /*
270
+ * call-seq:
271
+ * Curl::Easy.new => #&lt;Curl::Easy...&gt;
272
+ * Curl::Easy.new(url = nil) => #&lt;Curl::Easy...&gt;
273
+ * Curl::Easy.new(url = nil) { |self| ... } => #&lt;Curl::Easy...&gt;
274
+ *
275
+ * Create a new Curl::Easy instance, optionally supplying the URL.
276
+ * The block form allows further configuration to be supplied before
277
+ * the instance is returned.
278
+ */
279
+ static VALUE ruby_curl_easy_new(int argc, VALUE *argv, VALUE klass) {
280
+ CURLcode ecode;
281
+ VALUE url, blk;
282
+ VALUE new_curl;
283
+ ruby_curl_easy *rbce;
284
+
285
+ rb_scan_args(argc, argv, "01&", &url, &blk);
286
+
287
+ rbce = ALLOC(ruby_curl_easy);
288
+
289
+ /* handler */
290
+ rbce->curl = curl_easy_init();
291
+ if (!rbce->curl) {
292
+ rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
293
+ }
294
+
295
+ new_curl = Data_Wrap_Struct(klass, curl_easy_mark, curl_easy_free, rbce);
296
+
297
+ rbce->multi = Qnil;
298
+ rbce->opts = Qnil;
299
+
300
+ ruby_curl_easy_zero(rbce);
301
+
302
+ rb_easy_set("url", url);
303
+
304
+ /* set the new_curl pointer to the curl handle */
305
+ ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)new_curl);
306
+ if (ecode != CURLE_OK) {
307
+ raise_curl_easy_error_exception(ecode);
308
+ }
309
+
310
+ if (blk != Qnil) {
311
+ rb_funcall(blk, idCall, 1, new_curl);
312
+ }
313
+
314
+ return new_curl;
315
+ }
316
+
317
+ /*
318
+ * call-seq:
319
+ * easy.clone => #&lt;easy clone&gt;
320
+ * easy.dup => #&lt;easy clone&gt;
321
+ *
322
+ * Clone this Curl::Easy instance, creating a new instance.
323
+ * This method duplicates the underlying CURL* handle.
324
+ */
325
+ static VALUE ruby_curl_easy_clone(VALUE self) {
326
+ ruby_curl_easy *rbce, *newrbce;
327
+
328
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
329
+
330
+ newrbce = ALLOC(ruby_curl_easy);
331
+ memcpy(newrbce, rbce, sizeof(ruby_curl_easy));
332
+ newrbce->curl = curl_easy_duphandle(rbce->curl);
333
+ newrbce->curl_headers = NULL;
334
+ newrbce->curl_ftp_commands = NULL;
335
+
336
+ return Data_Wrap_Struct(cCurlEasy, curl_easy_mark, curl_easy_free, newrbce);
337
+ }
338
+
339
+ /*
340
+ * call-seq:
341
+ * easy.close => nil
342
+ *
343
+ * Close the Curl::Easy instance. Any open connections are closed
344
+ * The easy handle is reinitialized. If a previous multi handle was
345
+ * open it is set to nil and will be cleared after a GC.
346
+ */
347
+ static VALUE ruby_curl_easy_close(VALUE self) {
348
+ CURLcode ecode;
349
+ ruby_curl_easy *rbce;
350
+
351
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
352
+
353
+ if (rbce->callback_active) {
354
+ rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
355
+ }
356
+
357
+ ruby_curl_easy_free(rbce);
358
+
359
+ /* reinit the handle */
360
+ rbce->curl = curl_easy_init();
361
+ if (!rbce->curl) {
362
+ rb_raise(eCurlErrFailedInit, "Failed to initialize easy handle");
363
+ }
364
+
365
+ rbce->multi = Qnil;
366
+
367
+ ruby_curl_easy_zero(rbce);
368
+
369
+ /* give the new curl handle a reference back to the ruby object */
370
+ ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
371
+ if (ecode != CURLE_OK) {
372
+ raise_curl_easy_error_exception(ecode);
373
+ }
374
+
375
+ return Qnil;
376
+ }
377
+
378
+ /*
379
+ * call-seq:
380
+ * easy.reset => Hash
381
+ *
382
+ * Reset the Curl::Easy instance, clears out all settings.
383
+ *
384
+ * from http://curl.haxx.se/libcurl/c/curl_easy_reset.html
385
+ * Re-initializes all options previously set on a specified CURL handle to the default values. This puts back the handle to the same state as it was in when it was just created with curl_easy_init(3).
386
+ * It does not change the following information kept in the handle: live connections, the Session ID cache, the DNS cache, the cookies and shares.
387
+ *
388
+ * The return value contains all settings stored.
389
+ */
390
+ static VALUE ruby_curl_easy_reset(VALUE self) {
391
+ CURLcode ecode;
392
+ ruby_curl_easy *rbce;
393
+ VALUE opts_dup;
394
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
395
+
396
+ if (rbce->callback_active) {
397
+ rb_raise(rb_eRuntimeError, "Cannot close an active curl handle within a callback");
398
+ }
399
+
400
+ opts_dup = rb_funcall(rbce->opts, rb_intern("dup"), 0);
401
+
402
+ curl_easy_reset(rbce->curl);
403
+ ruby_curl_easy_zero(rbce);
404
+
405
+ /* rest clobbers the private setting, so reset it to self */
406
+ ecode = curl_easy_setopt(rbce->curl, CURLOPT_PRIVATE, (void*)self);
407
+ if (ecode != CURLE_OK) {
408
+ raise_curl_easy_error_exception(ecode);
409
+ }
410
+
411
+ /* Free everything up */
412
+ if (rbce->curl_headers) {
413
+ curl_slist_free_all(rbce->curl_headers);
414
+ rbce->curl_headers = NULL;
415
+ }
416
+
417
+ return opts_dup;
418
+ }
419
+
420
+
421
+ /* ================ OBJ ATTRIBUTES ==================*/
422
+
423
+ /*
424
+ * call-seq:
425
+ * easy.url => string
426
+ *
427
+ * Obtain the URL that will be used by subsequent calls to +perform+.
428
+ */
429
+ static VALUE ruby_curl_easy_url_get(VALUE self) {
430
+ CURB_OBJECT_HGETTER(ruby_curl_easy, url);
431
+ }
432
+
433
+ /*
434
+ * call-seq:
435
+ * easy.proxy_url => string
436
+ *
437
+ * Obtain the HTTP Proxy URL that will be used by subsequent calls to +perform+.
438
+ */
439
+ static VALUE ruby_curl_easy_proxy_url_get(VALUE self) {
440
+ CURB_OBJECT_HGETTER(ruby_curl_easy, proxy_url);
441
+ }
442
+
443
+ /*
444
+ * call-seq:
445
+ * easy.headers = "Header: val" => "Header: val"
446
+ * easy.headers = {"Header" => "val" ..., "Header" => "val"} => {"Header: val", ...}
447
+ * easy.headers = ["Header: val" ..., "Header: val"] => ["Header: val", ...]
448
+ *
449
+ * Set custom HTTP headers for following requests. This can be used to add
450
+ * custom headers, or override standard headers used by libcurl. It defaults to a
451
+ * Hash.
452
+ *
453
+ * For example to set a standard or custom header:
454
+ *
455
+ * easy.headers["MyHeader"] = "myval"
456
+ *
457
+ * To remove a standard header (this is useful when removing libcurls default
458
+ * 'Expect: 100-Continue' header when using HTTP form posts):
459
+ *
460
+ * easy.headers["Expect"] = ''
461
+ *
462
+ * Anything passed to libcurl as a header will be converted to a string during
463
+ * the perform step.
464
+ */
465
+ static VALUE ruby_curl_easy_headers_set(VALUE self, VALUE headers) {
466
+ CURB_OBJECT_HSETTER(ruby_curl_easy, headers);
467
+ }
468
+
469
+ /*
470
+ * call-seq:
471
+ * easy.headers => Hash, Array or Str
472
+ *
473
+ * Obtain the custom HTTP headers for following requests.
474
+ */
475
+ static VALUE ruby_curl_easy_headers_get(VALUE self) {
476
+ ruby_curl_easy *rbce;
477
+ VALUE headers;
478
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
479
+ headers = rb_easy_get("headers");//rb_hash_aref(rbce->opts, rb_intern("headers"));
480
+ if (headers == Qnil) { headers = rb_easy_set("headers", rb_hash_new()); }
481
+ return headers;
482
+ }
483
+
484
+ /*
485
+ * call-seq:
486
+ * easy.interface => string
487
+ *
488
+ * Obtain the interface name that is used as the outgoing network interface.
489
+ * The name can be an interface name, an IP address or a host name.
490
+ */
491
+ static VALUE ruby_curl_easy_interface_get(VALUE self) {
492
+ CURB_OBJECT_HGETTER(ruby_curl_easy, interface_hm);
493
+ }
494
+
495
+ /*
496
+ * call-seq:
497
+ * easy.userpwd => string
498
+ *
499
+ * Obtain the username/password string that will be used for subsequent
500
+ * calls to +perform+.
501
+ */
502
+ static VALUE ruby_curl_easy_userpwd_get(VALUE self) {
503
+ CURB_OBJECT_HGETTER(ruby_curl_easy, userpwd);
504
+ }
505
+
506
+ /*
507
+ * call-seq:
508
+ * easy.proxypwd => string
509
+ *
510
+ * Obtain the username/password string that will be used for proxy
511
+ * connection during subsequent calls to +perform+. The supplied string
512
+ * should have the form "username:password"
513
+ */
514
+ static VALUE ruby_curl_easy_proxypwd_get(VALUE self) {
515
+ CURB_OBJECT_HGETTER(ruby_curl_easy, proxypwd);
516
+ }
517
+
518
+ /*
519
+ * call-seq:
520
+ * easy.cookies => "name1=content1; name2=content2;"
521
+ *
522
+ * Obtain the cookies for this Curl::Easy instance.
523
+ */
524
+ static VALUE ruby_curl_easy_cookies_get(VALUE self) {
525
+ CURB_OBJECT_HGETTER(ruby_curl_easy, cookies);
526
+ }
527
+
528
+ /*
529
+ * call-seq:
530
+ * easy.cookiefile => string
531
+ *
532
+ * Obtain the cookiefile file for this Curl::Easy instance.
533
+ */
534
+ static VALUE ruby_curl_easy_cookiefile_get(VALUE self) {
535
+ CURB_OBJECT_HGETTER(ruby_curl_easy, cookiefile);
536
+ }
537
+
538
+ /*
539
+ * call-seq:
540
+ * easy.cookiejar => string
541
+ *
542
+ * Obtain the cookiejar file to use for this Curl::Easy instance.
543
+ */
544
+ static VALUE ruby_curl_easy_cookiejar_get(VALUE self) {
545
+ CURB_OBJECT_HGETTER(ruby_curl_easy, cookiejar);
546
+ }
547
+
548
+ /*
549
+ * call-seq:
550
+ * easy.cert = string => ""
551
+ *
552
+ * Set a cert file to use for this Curl::Easy instance. This file
553
+ * will be used to validate SSL connections.
554
+ *
555
+ */
556
+ static VALUE ruby_curl_easy_cert_set(VALUE self, VALUE cert) {
557
+ CURB_OBJECT_HSETTER(ruby_curl_easy, cert);
558
+ }
559
+
560
+ /*
561
+ * call-seq:
562
+ * easy.cert => string
563
+ *
564
+ * Obtain the cert file to use for this Curl::Easy instance.
565
+ */
566
+ static VALUE ruby_curl_easy_cert_get(VALUE self) {
567
+ CURB_OBJECT_HGETTER(ruby_curl_easy, cert);
568
+ }
569
+
570
+ /*
571
+ * call-seq:
572
+ * easy.cert_key = "cert_key.file" => ""
573
+ *
574
+ * Set a cert key to use for this Curl::Easy instance. This file
575
+ * will be used to validate SSL certificates.
576
+ *
577
+ */
578
+ static VALUE ruby_curl_easy_cert_key_set(VALUE self, VALUE cert_key) {
579
+ CURB_OBJECT_HSETTER(ruby_curl_easy, cert_key);
580
+ }
581
+
582
+ /*
583
+ * call-seq:
584
+ * easy.cert_key => "cert_key.file"
585
+ *
586
+ * Obtain the cert key file to use for this Curl::Easy instance.
587
+ */
588
+ static VALUE ruby_curl_easy_cert_key_get(VALUE self) {
589
+ CURB_OBJECT_HGETTER(ruby_curl_easy, cert_key);
590
+ }
591
+
592
+ /*
593
+ * call-seq:
594
+ * easy.cacert = string => ""
595
+ *
596
+ * Set a cacert bundle to use for this Curl::Easy instance. This file
597
+ * will be used to validate SSL certificates.
598
+ *
599
+ */
600
+ static VALUE ruby_curl_easy_cacert_set(VALUE self, VALUE cacert) {
601
+ CURB_OBJECT_HSETTER(ruby_curl_easy, cacert);
602
+ }
603
+
604
+ /*
605
+ * call-seq:
606
+ * easy.cacert => string
607
+ *
608
+ * Obtain the cacert file to use for this Curl::Easy instance.
609
+ */
610
+ static VALUE ruby_curl_easy_cacert_get(VALUE self) {
611
+ CURB_OBJECT_HGETTER(ruby_curl_easy, cacert);
612
+ }
613
+
614
+ /*
615
+ * call-seq:
616
+ * easy.certpassword = string => ""
617
+ *
618
+ * Set a password used to open the specified cert
619
+ */
620
+ static VALUE ruby_curl_easy_certpassword_set(VALUE self, VALUE certpassword) {
621
+ CURB_OBJECT_HSETTER(ruby_curl_easy, certpassword);
622
+ }
623
+
624
+ /*
625
+ * call-seq:
626
+ * easy.certtype = "PEM|DER" => ""
627
+ *
628
+ * Set a cert type to use for this Curl::Easy instance.
629
+ * Default is PEM
630
+ *
631
+ */
632
+ static VALUE ruby_curl_easy_certtype_set(VALUE self, VALUE certtype) {
633
+ CURB_OBJECT_HSETTER(ruby_curl_easy, certtype);
634
+ }
635
+
636
+ /*
637
+ * call-seq:
638
+ * easy.certtype => string
639
+ *
640
+ * Obtain the cert type used for this Curl::Easy instance
641
+ */
642
+ static VALUE ruby_curl_easy_certtype_get(VALUE self) {
643
+ CURB_OBJECT_HGETTER(ruby_curl_easy, certtype);
644
+ }
645
+
646
+ /*
647
+ * call-seq:
648
+ * easy.encoding = string => string
649
+ *
650
+ * Set the accepted encoding types, curl will handle all of the decompression
651
+ *
652
+ */
653
+ static VALUE ruby_curl_easy_encoding_set(VALUE self, VALUE encoding) {
654
+ CURB_OBJECT_HSETTER(ruby_curl_easy, encoding);
655
+ }
656
+ /*
657
+ * call-seq:
658
+ * easy.encoding => string
659
+ *
660
+ * Get the set encoding types
661
+ *
662
+ */
663
+ static VALUE ruby_curl_easy_encoding_get(VALUE self) {
664
+ CURB_OBJECT_HGETTER(ruby_curl_easy, encoding);
665
+ }
666
+
667
+ /*
668
+ * call-seq:
669
+ * easy.useragent = "Ruby/Curb" => ""
670
+ *
671
+ * Set the user agent string for this Curl::Easy instance
672
+ *
673
+ */
674
+ static VALUE ruby_curl_easy_useragent_set(VALUE self, VALUE useragent) {
675
+ CURB_OBJECT_HSETTER(ruby_curl_easy, useragent);
676
+ }
677
+
678
+ /*
679
+ * call-seq:
680
+ * easy.useragent => "Ruby/Curb"
681
+ *
682
+ * Obtain the user agent string used for this Curl::Easy instance
683
+ */
684
+ static VALUE ruby_curl_easy_useragent_get(VALUE self) {
685
+ CURB_OBJECT_HGETTER(ruby_curl_easy, useragent);
686
+ }
687
+
688
+ /*
689
+ * call-seq:
690
+ * easy.post_body = "some=form%20data&to=send" => string or nil
691
+ *
692
+ * Sets the POST body of this Curl::Easy instance. This is expected to be
693
+ * URL encoded; no additional processing or encoding is done on the string.
694
+ * The content-type header will be set to application/x-www-form-urlencoded.
695
+ *
696
+ * This is handy if you want to perform a POST against a Curl::Multi instance.
697
+ */
698
+ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
699
+ ruby_curl_easy *rbce;
700
+ CURL *curl;
701
+
702
+ char *data;
703
+ long len;
704
+
705
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
706
+
707
+ curl = rbce->curl;
708
+ if (rbce->first) {
709
+ curl_formfree(rbce->first);
710
+ rbce->first = NULL;
711
+ rbce->last = NULL;
712
+ }
713
+ rbce->multipart_form_post = 0;
714
+ if ( post_body == Qnil ) {
715
+ //rbce->postdata_buffer = Qnil;
716
+ rb_easy_del("postdata_buffer");
717
+ } else {
718
+ if (rb_type(post_body) == T_STRING) {
719
+ data = StringValuePtr(post_body);
720
+ len = RSTRING_LEN(post_body);
721
+ }
722
+ else if (rb_respond_to(post_body, rb_intern("to_s"))) {
723
+ VALUE str_body = rb_funcall(post_body, rb_intern("to_s"), 0);
724
+ data = StringValuePtr(str_body);
725
+ len = RSTRING_LEN(post_body);
726
+ }
727
+ else {
728
+ rb_raise(rb_eRuntimeError, "post data must respond_to .to_s");
729
+ }
730
+
731
+ // Store the string, since it has to hang around for the duration of the
732
+ // request. See CURLOPT_POSTFIELDS in the libcurl docs.
733
+ //rbce->postdata_buffer = post_body;
734
+ rb_easy_set("postdata_buffer", post_body);
735
+
736
+ curl_easy_setopt(curl, CURLOPT_POST, 1);
737
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
738
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
739
+
740
+ return post_body;
741
+ }
742
+
743
+ return Qnil;
744
+ }
745
+ static VALUE ruby_curl_easy_multipart_post_body_set(VALUE self, VALUE ary) {
746
+ ruby_curl_easy *rbce;
747
+ CURL *curl;
748
+ int i;
749
+
750
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
751
+ curl = rbce->curl;
752
+ if (rbce->first) {
753
+ curl_formfree(rbce->first);
754
+ rbce->first = NULL;
755
+ rbce->last = NULL;
756
+ }
757
+
758
+ // Make the multipart form
759
+ rbce->multipart_form_post = 1;
760
+ for (i=0; i<RARRAY_LEN(ary); i++) {
761
+ if (rb_obj_is_instance_of(RARRAY_PTR(ary)[i], cCurlPostField)) {
762
+ append_to_form(RARRAY_PTR(ary)[i], &(rbce->first), &(rbce->last));
763
+ }
764
+ else {
765
+ if (rbce->first) {
766
+ curl_formfree(rbce->first);
767
+ rbce->first = NULL;
768
+ rbce->last = NULL;
769
+ }
770
+ rb_raise(eCurlErrInvalidPostField, "You must use only PostFields with multipart form posts");
771
+ return Qnil;
772
+ }
773
+ }
774
+ //rbce->postdata_buffer = ary;
775
+ rb_easy_set("postdata_buffer", post_body);
776
+
777
+ curl_easy_setopt(curl, CURLOPT_POST, 0);
778
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, rbce->first);
779
+ return Qnil;
780
+ }
781
+
782
+ /*
783
+ * call-seq:
784
+ * easy.post_body => string or nil
785
+ *
786
+ * Obtain the POST body used in this Curl::Easy instance.
787
+ */
788
+ static VALUE ruby_curl_easy_post_body_get(VALUE self) {
789
+ CURB_OBJECT_HGETTER(ruby_curl_easy, postdata_buffer);
790
+ }
791
+
792
+ /*
793
+ * call-seq:
794
+ * easy.put_data = data => ""
795
+ *
796
+ * Points this Curl::Easy instance to data to be uploaded via PUT. This
797
+ * sets the request to a PUT type request - useful if you want to PUT via
798
+ * a multi handle.
799
+ */
800
+ static VALUE ruby_curl_easy_put_data_set(VALUE self, VALUE data) {
801
+ ruby_curl_easy *rbce;
802
+ CURL *curl;
803
+ VALUE upload;
804
+ VALUE headers;
805
+
806
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
807
+
808
+ upload = ruby_curl_upload_new(cCurlUpload);
809
+ ruby_curl_upload_stream_set(upload,data);
810
+
811
+ curl = rbce->curl;
812
+ rb_easy_set("upload", upload); /* keep the upload object alive as long as
813
+ the easy handle is active or until the upload
814
+ is complete or terminated... */
815
+
816
+ curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
817
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
818
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)read_data_handler);
819
+ curl_easy_setopt(curl, CURLOPT_READDATA, rbce);
820
+
821
+ /*
822
+ * we need to set specific headers for the PUT to work... so
823
+ * convert the internal headers structure to a HASH if one is set
824
+ */
825
+ if (!rb_easy_nil("headers")) {
826
+ if (rb_easy_type_check("headers", T_ARRAY) || rb_easy_type_check("headers", T_STRING)) {
827
+ rb_raise(rb_eRuntimeError, "Must set headers as a HASH to modify the headers in an PUT request");
828
+ }
829
+ }
830
+
831
+ // exit fast if the payload is empty
832
+ if (NIL_P(data)) { return data; }
833
+
834
+ headers = rb_easy_get("headers");
835
+ if( headers == Qnil ) {
836
+ headers = rb_hash_new();
837
+ }
838
+
839
+ if (rb_respond_to(data, rb_intern("read"))) {
840
+ VALUE stat = rb_funcall(data, rb_intern("stat"), 0);
841
+ if( stat && rb_hash_aref(headers, rb_str_new2("Content-Length")) == Qnil) {
842
+ VALUE size;
843
+ if( rb_hash_aref(headers, rb_str_new2("Expect")) == Qnil ) {
844
+ rb_hash_aset(headers, rb_str_new2("Expect"), rb_str_new2(""));
845
+ }
846
+ size = rb_funcall(stat, rb_intern("size"), 0);
847
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2LONG(size));
848
+ }
849
+ else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) == Qnil && rb_hash_aref(headers, rb_str_new2("Transfer-Encoding")) == Qnil ) {
850
+ rb_hash_aset(headers, rb_str_new2("Transfer-Encoding"), rb_str_new2("chunked"));
851
+ }
852
+ else if( rb_hash_aref(headers, rb_str_new2("Content-Length")) ) {
853
+ VALUE size = rb_funcall(rb_hash_aref(headers, rb_str_new2("Content-Length")), rb_intern("to_i"), 0);
854
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, FIX2LONG(size));
855
+ }
856
+ }
857
+ else if (rb_respond_to(data, rb_intern("to_s"))) {
858
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, RSTRING_LEN(data));
859
+ if( rb_hash_aref(headers, rb_str_new2("Expect")) == Qnil ) {
860
+ rb_hash_aset(headers, rb_str_new2("Expect"), rb_str_new2(""));
861
+ }
862
+ }
863
+ else {
864
+ rb_raise(rb_eRuntimeError, "PUT data must respond to read or to_s");
865
+ }
866
+ rb_easy_set("headers",headers);
867
+
868
+ // if we made it this far, all should be well.
869
+ return data;
870
+ }
871
+
872
+ /*
873
+ * call-seq:
874
+ * easy.ftp_commands = ["CWD /", "MKD directory"] => ["CWD /", ...]
875
+ *
876
+ * Explicitly sets the list of commands to execute on the FTP server when calling perform
877
+ */
878
+ static VALUE ruby_curl_easy_ftp_commands_set(VALUE self, VALUE ftp_commands) {
879
+ CURB_OBJECT_HSETTER(ruby_curl_easy, ftp_commands);
880
+ }
881
+
882
+ /*
883
+ * call-seq
884
+ * easy.ftp_commands => array or nil
885
+ */
886
+ static VALUE ruby_curl_easy_ftp_commands_get(VALUE self) {
887
+ CURB_OBJECT_HGETTER(ruby_curl_easy, ftp_commands);
888
+ }
889
+
890
+ /* ================== IMMED ATTRS ==================*/
891
+
892
+ /*
893
+ * call-seq:
894
+ * easy.local_port = fixnum or nil => fixnum or nil
895
+ *
896
+ * Set the local port that will be used for the following +perform+ calls.
897
+ *
898
+ * Passing +nil+ will return to the default behaviour (no local port
899
+ * preference).
900
+ *
901
+ * This option is ignored if compiled against libcurl < 7.15.2.
902
+ */
903
+ static VALUE ruby_curl_easy_local_port_set(VALUE self, VALUE local_port) {
904
+ CURB_IMMED_PORT_SETTER(ruby_curl_easy, local_port, "port");
905
+ }
906
+
907
+ /*
908
+ * call-seq:
909
+ * easy.local_port => fixnum or nil
910
+ *
911
+ * Obtain the local port that will be used for the following +perform+ calls.
912
+ *
913
+ * This option is ignored if compiled against libcurl < 7.15.2.
914
+ */
915
+ static VALUE ruby_curl_easy_local_port_get(VALUE self) {
916
+ CURB_IMMED_PORT_GETTER(ruby_curl_easy, local_port);
917
+ }
918
+
919
+ /*
920
+ * call-seq:
921
+ * easy.local_port_range = fixnum or nil => fixnum or nil
922
+ *
923
+ * Set the local port range that will be used for the following +perform+
924
+ * calls. This is a number (between 0 and 65535) that determines how far
925
+ * libcurl may deviate from the supplied +local_port+ in order to find
926
+ * an available port.
927
+ *
928
+ * If you set +local_port+ it's also recommended that you set this, since
929
+ * it is fairly likely that your specified port will be unavailable.
930
+ *
931
+ * This option is ignored if compiled against libcurl < 7.15.2.
932
+ */
933
+ static VALUE ruby_curl_easy_local_port_range_set(VALUE self, VALUE local_port_range) {
934
+ CURB_IMMED_PORT_SETTER(ruby_curl_easy, local_port_range, "port range");
935
+ }
936
+
937
+ /*
938
+ * call-seq:
939
+ * easy.local_port_range => fixnum or nil
940
+ *
941
+ * Obtain the local port range that will be used for the following +perform+
942
+ * calls.
943
+ *
944
+ * This option is ignored if compiled against libcurl < 7.15.2.
945
+ */
946
+ static VALUE ruby_curl_easy_local_port_range_get(VALUE self) {
947
+ CURB_IMMED_PORT_GETTER(ruby_curl_easy, local_port_range);
948
+ }
949
+
950
+ /*
951
+ * call-seq:
952
+ * easy.proxy_port = fixnum or nil => fixnum or nil
953
+ *
954
+ * Set the proxy port that will be used for the following +perform+ calls.
955
+ */
956
+ static VALUE ruby_curl_easy_proxy_port_set(VALUE self, VALUE proxy_port) {
957
+ CURB_IMMED_PORT_SETTER(ruby_curl_easy, proxy_port, "port");
958
+ }
959
+
960
+ /*
961
+ * call-seq:
962
+ * easy.proxy_port => fixnum or nil
963
+ *
964
+ * Obtain the proxy port that will be used for the following +perform+ calls.
965
+ */
966
+ static VALUE ruby_curl_easy_proxy_port_get(VALUE self) {
967
+ CURB_IMMED_PORT_GETTER(ruby_curl_easy, proxy_port);
968
+ }
969
+
970
+ /*
971
+ * call-seq:
972
+ * easy.proxy_type = fixnum or nil => fixnum or nil
973
+ *
974
+ * Set the proxy type that will be used for the following +perform+ calls.
975
+ * This should be one of the Curl::CURLPROXY constants.
976
+ */
977
+ static VALUE ruby_curl_easy_proxy_type_set(VALUE self, VALUE proxy_type) {
978
+ CURB_IMMED_SETTER(ruby_curl_easy, proxy_type, -1);
979
+ }
980
+
981
+ /*
982
+ * call-seq:
983
+ * easy.proxy_type => fixnum or nil
984
+ *
985
+ * Obtain the proxy type that will be used for the following +perform+ calls.
986
+ */
987
+ static VALUE ruby_curl_easy_proxy_type_get(VALUE self) {
988
+ CURB_IMMED_GETTER(ruby_curl_easy, proxy_type, -1);
989
+ }
990
+
991
+ #if defined(HAVE_CURLAUTH_DIGEST_IE)
992
+ #define CURL_HTTPAUTH_STR_TO_NUM(node) \
993
+ (!strncmp("basic",node,5)) ? CURLAUTH_BASIC : \
994
+ (!strncmp("digest_ie",node,9)) ? CURLAUTH_DIGEST_IE : \
995
+ (!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
996
+ (!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
997
+ (!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
998
+ (!strncmp("any",node,3)) ? CURLAUTH_ANY : \
999
+ (!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : 0
1000
+ #else
1001
+ #define CURL_HTTPAUTH_STR_TO_NUM(node) \
1002
+ (!strncmp("basic",node,5)) ? CURLAUTH_BASIC : \
1003
+ (!strncmp("digest",node,6)) ? CURLAUTH_DIGEST : \
1004
+ (!strncmp("gssnegotiate",node,12)) ? CURLAUTH_GSSNEGOTIATE : \
1005
+ (!strncmp("ntlm",node,4)) ? CURLAUTH_NTLM : \
1006
+ (!strncmp("any",node,3)) ? CURLAUTH_ANY : \
1007
+ (!strncmp("anysafe",node,7)) ? CURLAUTH_ANYSAFE : 0
1008
+ #endif
1009
+ /*
1010
+ * call-seq:
1011
+ * easy.http_auth_types = fixnum or nil => fixnum or nil
1012
+ * easy.http_auth_types = [:basic,:digest,:digest_ie,:gssnegotiate, :ntlm, :any, :anysafe]
1013
+ *
1014
+ * Set the HTTP authentication types that may be used for the following
1015
+ * +perform+ calls. This is a bitmap made by ORing together the
1016
+ * Curl::CURLAUTH constants.
1017
+ */
1018
+ static VALUE ruby_curl_easy_http_auth_types_set(int argc, VALUE *argv, VALUE self) {//VALUE self, VALUE http_auth_types) {
1019
+ ruby_curl_easy *rbce;
1020
+ VALUE args_ary;
1021
+ int i, len;
1022
+ char* node = NULL;
1023
+ long mask = 0x000000;
1024
+
1025
+ rb_scan_args(argc, argv, "*", &args_ary);
1026
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
1027
+
1028
+ len = (int)RARRAY_LEN(args_ary);
1029
+
1030
+ if (len == 1 && (TYPE(rb_ary_entry(args_ary,0)) == T_FIXNUM || rb_ary_entry(args_ary,0) == Qnil)) {
1031
+ if (rb_ary_entry(args_ary,0) == Qnil) {
1032
+ rbce->http_auth_types = 0;
1033
+ }
1034
+ else {
1035
+ rbce->http_auth_types = NUM2INT(rb_ary_entry(args_ary,0));
1036
+ }
1037
+ }
1038
+ else {
1039
+ // we could have multiple values, but they should be symbols
1040
+ node = RSTRING_PTR(rb_funcall(rb_ary_entry(args_ary,0),rb_intern("to_s"),0));
1041
+ mask = CURL_HTTPAUTH_STR_TO_NUM(node);
1042
+ for( i = 1; i < len; ++i ) {
1043
+ node = RSTRING_PTR(rb_funcall(rb_ary_entry(args_ary,i),rb_intern("to_s"),0));
1044
+ mask |= CURL_HTTPAUTH_STR_TO_NUM(node);
1045
+ }
1046
+ rbce->http_auth_types = mask;
1047
+ }
1048
+ return INT2NUM(rbce->http_auth_types);
1049
+ }
1050
+
1051
+ /*
1052
+ * call-seq:
1053
+ * easy.http_auth_types => fixnum or nil
1054
+ *
1055
+ * Obtain the HTTP authentication types that may be used for the following
1056
+ * +perform+ calls.
1057
+ */
1058
+ static VALUE ruby_curl_easy_http_auth_types_get(VALUE self) {
1059
+ CURB_IMMED_GETTER(ruby_curl_easy, http_auth_types, 0);
1060
+ }
1061
+
1062
+ /*
1063
+ * call-seq:
1064
+ * easy.proxy_auth_types = fixnum or nil => fixnum or nil
1065
+ *
1066
+ * Set the proxy authentication types that may be used for the following
1067
+ * +perform+ calls. This is a bitmap made by ORing together the
1068
+ * Curl::CURLAUTH constants.
1069
+ */
1070
+ static VALUE ruby_curl_easy_proxy_auth_types_set(VALUE self, VALUE proxy_auth_types) {
1071
+ CURB_IMMED_SETTER(ruby_curl_easy, proxy_auth_types, 0);
1072
+ }
1073
+
1074
+ /*
1075
+ * call-seq:
1076
+ * easy.proxy_auth_types => fixnum or nil
1077
+ *
1078
+ * Obtain the proxy authentication types that may be used for the following
1079
+ * +perform+ calls.
1080
+ */
1081
+ static VALUE ruby_curl_easy_proxy_auth_types_get(VALUE self) {
1082
+ CURB_IMMED_GETTER(ruby_curl_easy, proxy_auth_types, 0);
1083
+ }
1084
+
1085
+ /*
1086
+ * call-seq:
1087
+ * easy.max_redirects = fixnum or nil => fixnum or nil
1088
+ *
1089
+ * Set the maximum number of redirections to follow in the following +perform+
1090
+ * calls. Set to nil or -1 allow an infinite number (the default). Setting this
1091
+ * option only makes sense if +follow_location+ is also set true.
1092
+ *
1093
+ * With libcurl >= 7.15.1, setting this to 0 will cause libcurl to refuse any
1094
+ * redirect.
1095
+ */
1096
+ static VALUE ruby_curl_easy_max_redirects_set(VALUE self, VALUE max_redirs) {
1097
+ CURB_IMMED_SETTER(ruby_curl_easy, max_redirs, -1);
1098
+ }
1099
+
1100
+ /*
1101
+ * call-seq:
1102
+ * easy.max_redirects => fixnum or nil
1103
+ *
1104
+ * Obtain the maximum number of redirections to follow in the following
1105
+ * +perform+ calls.
1106
+ */
1107
+ static VALUE ruby_curl_easy_max_redirects_get(VALUE self) {
1108
+ CURB_IMMED_GETTER(ruby_curl_easy, max_redirs, -1);
1109
+ }
1110
+
1111
+ /*
1112
+ * call-seq:
1113
+ * easy.timeout = fixnum or nil => fixnum or nil
1114
+ *
1115
+ * Set the maximum time in seconds that you allow the libcurl transfer
1116
+ * operation to take. Normally, name lookups can take a considerable time
1117
+ * and limiting operations to less than a few minutes risk aborting
1118
+ * perfectly normal operations.
1119
+ *
1120
+ * Set to nil (or zero) to disable timeout (it will then only timeout
1121
+ * on the system's internal timeouts).
1122
+ */
1123
+ static VALUE ruby_curl_easy_timeout_set(VALUE self, VALUE timeout) {
1124
+ CURB_IMMED_SETTER(ruby_curl_easy, timeout, 0);
1125
+ }
1126
+
1127
+ /*
1128
+ * call-seq:
1129
+ * easy.timeout => fixnum or nil
1130
+ *
1131
+ * Obtain the maximum time in seconds that you allow the libcurl transfer
1132
+ * operation to take.
1133
+ */
1134
+ static VALUE ruby_curl_easy_timeout_get(VALUE self, VALUE timeout) {
1135
+ CURB_IMMED_GETTER(ruby_curl_easy, timeout, 0);
1136
+ }
1137
+
1138
+ /*
1139
+ * call-seq:
1140
+ * easy.connect_timeout = fixnum or nil => fixnum or nil
1141
+ *
1142
+ * Set the maximum time in seconds that you allow the connection to the
1143
+ * server to take. This only limits the connection phase, once it has
1144
+ * connected, this option is of no more use.
1145
+ *
1146
+ * Set to nil (or zero) to disable connection timeout (it will then only
1147
+ * timeout on the system's internal timeouts).
1148
+ */
1149
+ static VALUE ruby_curl_easy_connect_timeout_set(VALUE self, VALUE connect_timeout) {
1150
+ CURB_IMMED_SETTER(ruby_curl_easy, connect_timeout, 0);
1151
+ }
1152
+
1153
+ /*
1154
+ * call-seq:
1155
+ * easy.connect_timeout => fixnum or nil
1156
+ *
1157
+ * Obtain the maximum time in seconds that you allow the connection to the
1158
+ * server to take.
1159
+ */
1160
+ static VALUE ruby_curl_easy_connect_timeout_get(VALUE self, VALUE connect_timeout) {
1161
+ CURB_IMMED_GETTER(ruby_curl_easy, connect_timeout, 0);
1162
+ }
1163
+
1164
+ /*
1165
+ * call-seq:
1166
+ * easy.dns_cache_timeout = fixnum or nil => fixnum or nil
1167
+ *
1168
+ * Set the dns cache timeout in seconds. Name resolves will be kept in
1169
+ * memory for this number of seconds. Set to zero (0) to completely disable
1170
+ * caching, or set to nil (or -1) to make the cached entries remain forever.
1171
+ * By default, libcurl caches this info for 60 seconds.
1172
+ */
1173
+ static VALUE ruby_curl_easy_dns_cache_timeout_set(VALUE self, VALUE dns_cache_timeout) {
1174
+ CURB_IMMED_SETTER(ruby_curl_easy, dns_cache_timeout, -1);
1175
+ }
1176
+
1177
+ /*
1178
+ * call-seq:
1179
+ * easy.dns_cache_timeout => fixnum or nil
1180
+ *
1181
+ * Obtain the dns cache timeout in seconds.
1182
+ */
1183
+ static VALUE ruby_curl_easy_dns_cache_timeout_get(VALUE self, VALUE dns_cache_timeout) {
1184
+ CURB_IMMED_GETTER(ruby_curl_easy, dns_cache_timeout, -1);
1185
+ }
1186
+
1187
+ /*
1188
+ * call-seq:
1189
+ * easy.ftp_response_timeout = fixnum or nil => fixnum or nil
1190
+ *
1191
+ * Set a timeout period (in seconds) on the amount of time that the server
1192
+ * is allowed to take in order to generate a response message for a command
1193
+ * before the session is considered hung. While curl is waiting for a
1194
+ * response, this value overrides +timeout+. It is recommended that if used
1195
+ * in conjunction with +timeout+, you set +ftp_response_timeout+ to a value
1196
+ * smaller than +timeout+.
1197
+ *
1198
+ * Ignored if libcurl version is < 7.10.8.
1199
+ */
1200
+ static VALUE ruby_curl_easy_ftp_response_timeout_set(VALUE self, VALUE ftp_response_timeout) {
1201
+ CURB_IMMED_SETTER(ruby_curl_easy, ftp_response_timeout, 0);
1202
+ }
1203
+
1204
+ /*
1205
+ * call-seq:
1206
+ * easy.ftp_response_timeout => fixnum or nil
1207
+ *
1208
+ * Obtain the maximum time that libcurl will wait for FTP command responses.
1209
+ */
1210
+ static VALUE ruby_curl_easy_ftp_response_timeout_get(VALUE self, VALUE ftp_response_timeout) {
1211
+ CURB_IMMED_GETTER(ruby_curl_easy, ftp_response_timeout, 0);
1212
+ }
1213
+
1214
+ /*
1215
+ * call-seq:
1216
+ * easy.low_speed_limit = fixnum or nil => fixnum or nil
1217
+ *
1218
+ * Set the transfer speed (in bytes per second) that the transfer should be
1219
+ * below during +low_speed_time+ seconds for the library to consider it too
1220
+ * slow and abort.
1221
+ */
1222
+ static VALUE ruby_curl_easy_low_speed_limit_set(VALUE self, VALUE low_speed_limit) {
1223
+ CURB_IMMED_SETTER(ruby_curl_easy, low_speed_limit, 0);
1224
+ }
1225
+
1226
+ /*
1227
+ * call-seq:
1228
+ * easy.low_speed_limit => fixnum or nil
1229
+ *
1230
+ * Obtain the minimum transfer speed over +low_speed+time+ below which the
1231
+ * transfer will be aborted.
1232
+ */
1233
+ static VALUE ruby_curl_easy_low_speed_limit_get(VALUE self, VALUE low_speed_limit) {
1234
+ CURB_IMMED_GETTER(ruby_curl_easy, low_speed_limit, 0);
1235
+ }
1236
+
1237
+ /*
1238
+ * call-seq:
1239
+ * easy.low_speed_time = fixnum or nil => fixnum or nil
1240
+ *
1241
+ * Set the time (in seconds) that the transfer should be below the
1242
+ * +low_speed_limit+ for the library to consider it too slow and abort.
1243
+ */
1244
+ static VALUE ruby_curl_easy_low_speed_time_set(VALUE self, VALUE low_speed_time) {
1245
+ CURB_IMMED_SETTER(ruby_curl_easy, low_speed_time, 0);
1246
+ }
1247
+
1248
+ /*
1249
+ * call-seq:
1250
+ * easy.low_speed_time => fixnum or nil
1251
+ *
1252
+ * Obtain the time that the transfer should be below +low_speed_limit+ for
1253
+ * the library to abort it.
1254
+ */
1255
+ static VALUE ruby_curl_easy_low_speed_time_get(VALUE self, VALUE low_speed_time) {
1256
+ CURB_IMMED_GETTER(ruby_curl_easy, low_speed_time, 0);
1257
+ }
1258
+
1259
+ /*
1260
+ * call-seq:
1261
+ * easy.username = string => string
1262
+ *
1263
+ * Set the HTTP Authentication username.
1264
+ */
1265
+ static VALUE ruby_curl_easy_username_set(VALUE self, VALUE username) {
1266
+ #if HAVE_CURLOPT_USERNAME
1267
+ CURB_OBJECT_HSETTER(ruby_curl_easy, username);
1268
+ #else
1269
+ return Qnil;
1270
+ #endif
1271
+ }
1272
+
1273
+ /*
1274
+ * call-seq:
1275
+ * easy.username => string
1276
+ *
1277
+ * Get the current username
1278
+ */
1279
+ static VALUE ruby_curl_easy_username_get(VALUE self, VALUE username) {
1280
+ #if HAVE_CURLOPT_USERNAME
1281
+ CURB_OBJECT_HGETTER(ruby_curl_easy, username);
1282
+ #else
1283
+ return Qnil;
1284
+ #endif
1285
+ }
1286
+
1287
+ /*
1288
+ * call-seq:
1289
+ * easy.password = string => string
1290
+ *
1291
+ * Set the HTTP Authentication password.
1292
+ */
1293
+ static VALUE ruby_curl_easy_password_set(VALUE self, VALUE password) {
1294
+ #if HAVE_CURLOPT_PASSWORD
1295
+ CURB_OBJECT_HSETTER(ruby_curl_easy, password);
1296
+ #else
1297
+ return Qnil;
1298
+ #endif
1299
+ }
1300
+
1301
+ /*
1302
+ * call-seq:
1303
+ * easy.password => string
1304
+ *
1305
+ * Get the current password
1306
+ */
1307
+ static VALUE ruby_curl_easy_password_get(VALUE self, VALUE password) {
1308
+ #if HAVE_CURLOPT_PASSWORD
1309
+ CURB_OBJECT_HGETTER(ruby_curl_easy, password);
1310
+ #else
1311
+ return Qnil;
1312
+ #endif
1313
+ }
1314
+
1315
+ /*
1316
+ * call-seq:
1317
+ * easy.ssl_version = value => fixnum or nil
1318
+ *
1319
+ * Sets the version of SSL/TLS that libcurl will attempt to use. Valid
1320
+ * options are Curl::CURL_SSLVERSION_TLSv1, Curl::CURL_SSLVERSION::SSLv2,
1321
+ * Curl::CURL_SSLVERSION_SSLv3 and Curl::CURL_SSLVERSION_DEFAULT
1322
+ */
1323
+ static VALUE ruby_curl_easy_ssl_version_set(VALUE self, VALUE ssl_version) {
1324
+ CURB_IMMED_SETTER(ruby_curl_easy, ssl_version, -1);
1325
+ }
1326
+
1327
+ /*
1328
+ * call-seq:
1329
+ * easy.ssl_version => fixnum
1330
+ *
1331
+ * Get the version of SSL/TLS that libcurl will attempt to use.
1332
+ */
1333
+ static VALUE ruby_curl_easy_ssl_version_get(VALUE self, VALUE ssl_version) {
1334
+ CURB_IMMED_GETTER(ruby_curl_easy, ssl_version, -1);
1335
+ }
1336
+
1337
+ /*
1338
+ * call-seq:
1339
+ * easy.use_ssl = value => fixnum or nil
1340
+ *
1341
+ * Ensure libcurl uses SSL for FTP connections. Valid options are Curl::CURL_USESSL_NONE,
1342
+ * Curl::CURL_USESSL_TRY, Curl::CURL_USESSL_CONTROL, and Curl::CURL_USESSL_ALL.
1343
+ */
1344
+ static VALUE ruby_curl_easy_use_ssl_set(VALUE self, VALUE use_ssl) {
1345
+ CURB_IMMED_SETTER(ruby_curl_easy, use_ssl, -1);
1346
+ }
1347
+
1348
+ /*
1349
+ * call-seq:
1350
+ * easy.use_ssl => fixnum
1351
+ *
1352
+ * Get the desired level for using SSL on FTP connections.
1353
+ */
1354
+ static VALUE ruby_curl_easy_use_ssl_get(VALUE self, VALUE use_ssl) {
1355
+ CURB_IMMED_GETTER(ruby_curl_easy, use_ssl, -1);
1356
+ }
1357
+
1358
+ /*
1359
+ * call-seq:
1360
+ * easy.ftp_filemethod = value => fixnum or nil
1361
+ *
1362
+ * Controls how libcurl reaches files on the server. Valid options are Curl::CURL_MULTICWD,
1363
+ * Curl::CURL_NOCWD, and Curl::CURL_SINGLECWD (see libcurl docs for CURLOPT_FTP_METHOD).
1364
+ */
1365
+ static VALUE ruby_curl_easy_ftp_filemethod_set(VALUE self, VALUE ftp_filemethod) {
1366
+ CURB_IMMED_SETTER(ruby_curl_easy, ftp_filemethod, -1);
1367
+ }
1368
+
1369
+ /*
1370
+ * call-seq
1371
+ * easy.ftp_filemethod => fixnum
1372
+ *
1373
+ * Get the configuration for how libcurl will reach files on the server.
1374
+ */
1375
+ static VALUE ruby_curl_easy_ftp_filemethod_get(VALUE self, VALUE ftp_filemethod) {
1376
+ CURB_IMMED_GETTER(ruby_curl_easy, ftp_filemethod, -1);
1377
+ }
1378
+
1379
+ /* ================== BOOL ATTRS ===================*/
1380
+
1381
+ /*
1382
+ * call-seq:
1383
+ * easy.proxy_tunnel = boolean => boolean
1384
+ *
1385
+ * Configure whether this Curl instance will use proxy tunneling.
1386
+ */
1387
+ static VALUE ruby_curl_easy_proxy_tunnel_set(VALUE self, VALUE proxy_tunnel) {
1388
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, proxy_tunnel);
1389
+ }
1390
+
1391
+ /*
1392
+ * call-seq:
1393
+ * easy.proxy_tunnel? => boolean
1394
+ *
1395
+ * Determine whether this Curl instance will use proxy tunneling.
1396
+ */
1397
+ static VALUE ruby_curl_easy_proxy_tunnel_q(VALUE self) {
1398
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, proxy_tunnel);
1399
+ }
1400
+
1401
+ /*
1402
+ * call-seq:
1403
+ * easy.fetch_file_time = boolean => boolean
1404
+ *
1405
+ * Configure whether this Curl instance will fetch remote file
1406
+ * times, if available.
1407
+ */
1408
+ static VALUE ruby_curl_easy_fetch_file_time_set(VALUE self, VALUE fetch_file_time) {
1409
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, fetch_file_time);
1410
+ }
1411
+
1412
+ /*
1413
+ * call-seq:
1414
+ * easy.fetch_file_time? => boolean
1415
+ *
1416
+ * Determine whether this Curl instance will fetch remote file
1417
+ * times, if available.
1418
+ */
1419
+ static VALUE ruby_curl_easy_fetch_file_time_q(VALUE self) {
1420
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, fetch_file_time);
1421
+ }
1422
+
1423
+ /*
1424
+ * call-seq:
1425
+ * easy.ssl_verify_peer = boolean => boolean
1426
+ *
1427
+ * Configure whether this Curl instance will verify the SSL peer
1428
+ * certificate. When true (the default), and the verification fails to
1429
+ * prove that the certificate is authentic, the connection fails. When
1430
+ * false, the connection succeeds regardless.
1431
+ *
1432
+ * Authenticating the certificate is not by itself very useful. You
1433
+ * typically want to ensure that the server, as authentically identified
1434
+ * by its certificate, is the server you mean to be talking to.
1435
+ * The ssl_verify_host? options controls that.
1436
+ */
1437
+ static VALUE ruby_curl_easy_ssl_verify_peer_set(VALUE self, VALUE ssl_verify_peer) {
1438
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, ssl_verify_peer);
1439
+ }
1440
+
1441
+ /*
1442
+ * call-seq:
1443
+ * easy.ssl_verify_peer? => boolean
1444
+ *
1445
+ * Determine whether this Curl instance will verify the SSL peer
1446
+ * certificate.
1447
+ */
1448
+ static VALUE ruby_curl_easy_ssl_verify_peer_q(VALUE self) {
1449
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, ssl_verify_peer);
1450
+ }
1451
+
1452
+ /*
1453
+ * call-seq:
1454
+ * easy.ssl_verify_host = [0, 1, 2] => [0, 1, 2]
1455
+ *
1456
+ * Configure whether this Curl instance will verify that the server cert
1457
+ * is for the server it is known as. When true (the default) the server
1458
+ * certificate must indicate that the server is the server to which you
1459
+ * meant to connect, or the connection fails. When false, the connection
1460
+ * will succeed regardless of the names in the certificate.
1461
+ *
1462
+ * this option controls is of the identity that the server claims.
1463
+ * The server could be lying. To control lying, see ssl_verify_peer? .
1464
+ */
1465
+ static VALUE ruby_curl_easy_ssl_verify_host_set(VALUE self, VALUE ssl_verify_host) {
1466
+ CURB_IMMED_SETTER(ruby_curl_easy, ssl_verify_host, 0);
1467
+ }
1468
+
1469
+ /*
1470
+ * call-seq:
1471
+ * easy.ssl_verify_host => number
1472
+ *
1473
+ * Determine whether this Curl instance will verify that the server cert
1474
+ * is for the server it is known as.
1475
+ */
1476
+ static VALUE ruby_curl_easy_ssl_verify_host_get(VALUE self) {
1477
+ CURB_IMMED_GETTER(ruby_curl_easy, ssl_verify_host, 0);
1478
+ }
1479
+
1480
+ /*
1481
+ * call-seq:
1482
+ * easy.header_in_body = boolean => boolean
1483
+ *
1484
+ * Configure whether this Curl instance will return HTTP headers
1485
+ * combined with body data. If this option is set true, both header
1486
+ * and body data will go to +body_str+ (or the configured +on_body+ handler).
1487
+ */
1488
+ static VALUE ruby_curl_easy_header_in_body_set(VALUE self, VALUE header_in_body) {
1489
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, header_in_body);
1490
+ }
1491
+
1492
+ /*
1493
+ * call-seq:
1494
+ * easy.header_in_body? => boolean
1495
+ *
1496
+ * Determine whether this Curl instance will return HTTP headers
1497
+ * combined with body data.
1498
+ */
1499
+ static VALUE ruby_curl_easy_header_in_body_q(VALUE self) {
1500
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, header_in_body);
1501
+ }
1502
+
1503
+ /*
1504
+ * call-seq:
1505
+ * easy.use_netrc = boolean => boolean
1506
+ *
1507
+ * Configure whether this Curl instance will use data from the user's
1508
+ * .netrc file for FTP connections.
1509
+ */
1510
+ static VALUE ruby_curl_easy_use_netrc_set(VALUE self, VALUE use_netrc) {
1511
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, use_netrc);
1512
+ }
1513
+
1514
+ /*
1515
+ * call-seq:
1516
+ * easy.use_netrc? => boolean
1517
+ *
1518
+ * Determine whether this Curl instance will use data from the user's
1519
+ * .netrc file for FTP connections.
1520
+ */
1521
+ static VALUE ruby_curl_easy_use_netrc_q(VALUE self) {
1522
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, use_netrc);
1523
+ }
1524
+
1525
+ /*
1526
+ * call-seq:
1527
+ *
1528
+ * easy = Curl::Easy.new
1529
+ * easy.autoreferer=true
1530
+ */
1531
+ static VALUE ruby_curl_easy_autoreferer_set(VALUE self, VALUE autoreferer) {
1532
+ ruby_curl_easy *rbce;
1533
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
1534
+
1535
+ if (Qtrue == autoreferer) {
1536
+ curl_easy_setopt(rbce->curl, CURLOPT_AUTOREFERER, 1);
1537
+ }
1538
+ else {
1539
+ curl_easy_setopt(rbce->curl, CURLOPT_AUTOREFERER, 0);
1540
+ }
1541
+
1542
+ return autoreferer;
1543
+ }
1544
+
1545
+ /*
1546
+ * call-seq:
1547
+ * easy.follow_location? => boolean
1548
+ *
1549
+ * Determine whether this Curl instance will follow Location: headers
1550
+ * in HTTP responses.
1551
+ */
1552
+ static VALUE ruby_curl_easy_follow_location_q(VALUE self) {
1553
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, follow_location);
1554
+ }
1555
+
1556
+ /*
1557
+ * call-seq:
1558
+ * easy.unrestricted_auth = boolean => boolean
1559
+ *
1560
+ * Configure whether this Curl instance may use any HTTP authentication
1561
+ * method available when necessary.
1562
+ */
1563
+ static VALUE ruby_curl_easy_unrestricted_auth_set(VALUE self, VALUE unrestricted_auth) {
1564
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, unrestricted_auth);
1565
+ }
1566
+
1567
+ /*
1568
+ * call-seq:
1569
+ * easy.unrestricted_auth? => boolean
1570
+ *
1571
+ * Determine whether this Curl instance may use any HTTP authentication
1572
+ * method available when necessary.
1573
+ */
1574
+ static VALUE ruby_curl_easy_unrestricted_auth_q(VALUE self) {
1575
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, unrestricted_auth);
1576
+ }
1577
+
1578
+ /*
1579
+ * call-seq:
1580
+ * easy.verbose = boolean => boolean
1581
+ *
1582
+ * Configure whether this Curl instance gives verbose output to STDERR
1583
+ * during transfers. Ignored if this instance has an on_debug handler.
1584
+ */
1585
+ static VALUE ruby_curl_easy_verbose_set(VALUE self, VALUE verbose) {
1586
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, verbose);
1587
+ }
1588
+
1589
+ /*
1590
+ * call-seq:
1591
+ * easy.verbose? => boolean
1592
+ *
1593
+ * Determine whether this Curl instance gives verbose output to STDERR
1594
+ * during transfers.
1595
+ */
1596
+ static VALUE ruby_curl_easy_verbose_q(VALUE self) {
1597
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, verbose);
1598
+ }
1599
+
1600
+ /*
1601
+ * call-seq:
1602
+ * easy.multipart_form_post = boolean => boolean
1603
+ *
1604
+ * Configure whether this Curl instance uses multipart/formdata content
1605
+ * type for HTTP POST requests. If this is false (the default), then the
1606
+ * application/x-www-form-urlencoded content type is used for the form
1607
+ * data.
1608
+ *
1609
+ * If this is set true, you must pass one or more PostField instances
1610
+ * to the http_post method - no support for posting multipart forms from
1611
+ * a string is provided.
1612
+ */
1613
+ static VALUE ruby_curl_easy_multipart_form_post_set(VALUE self, VALUE multipart_form_post)
1614
+ {
1615
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, multipart_form_post);
1616
+ }
1617
+
1618
+ /*
1619
+ * call-seq:
1620
+ * easy.multipart_form_post? => boolean
1621
+ *
1622
+ * Determine whether this Curl instance uses multipart/formdata content
1623
+ * type for HTTP POST requests.
1624
+ */
1625
+ static VALUE ruby_curl_easy_multipart_form_post_q(VALUE self) {
1626
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, multipart_form_post);
1627
+ }
1628
+
1629
+ /*
1630
+ * call-seq:
1631
+ * easy.enable_cookies = boolean => boolean
1632
+ *
1633
+ * Configure whether the libcurl cookie engine is enabled for this Curl::Easy
1634
+ * instance.
1635
+ */
1636
+ static VALUE ruby_curl_easy_enable_cookies_set(VALUE self, VALUE enable_cookies)
1637
+ {
1638
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, enable_cookies);
1639
+ }
1640
+
1641
+ /*
1642
+ * call-seq:
1643
+ * easy.enable_cookies? => boolean
1644
+ *
1645
+ * Determine whether the libcurl cookie engine is enabled for this
1646
+ * Curl::Easy instance.
1647
+ */
1648
+ static VALUE ruby_curl_easy_enable_cookies_q(VALUE self) {
1649
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, enable_cookies);
1650
+ }
1651
+
1652
+ /*
1653
+ * call-seq:
1654
+ * easy.ignore_content_length = boolean
1655
+ *
1656
+ * Configure whether this Curl::Easy instance should ignore the content
1657
+ * length header.
1658
+ */
1659
+ static VALUE ruby_curl_easy_ignore_content_length_set(VALUE self, VALUE ignore_content_length)
1660
+ {
1661
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, ignore_content_length);
1662
+ }
1663
+
1664
+ /*
1665
+ * call-seq:
1666
+ * easy.ignore_content_length? => boolean
1667
+ *
1668
+ * Determine whether this Curl::Easy instance ignores the content
1669
+ * length header.
1670
+ */
1671
+ static VALUE ruby_curl_easy_ignore_content_length_q(VALUE self) {
1672
+ CURB_BOOLEAN_GETTER(ruby_curl_easy, ignore_content_length);
1673
+ }
1674
+
1675
+ /*
1676
+ * call-seq:
1677
+ * easy.resolve_mode => symbol
1678
+ *
1679
+ * Determines what type of IP address this Curl::Easy instance
1680
+ * resolves DNS names to.
1681
+ */
1682
+ static VALUE ruby_curl_easy_resolve_mode(VALUE self) {
1683
+ ruby_curl_easy *rbce;
1684
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
1685
+
1686
+ unsigned short rm = rbce->resolve_mode;
1687
+
1688
+ switch(rm) {
1689
+ case CURL_IPRESOLVE_V4:
1690
+ return rb_easy_sym("ipv4");
1691
+ case CURL_IPRESOLVE_V6:
1692
+ return rb_easy_sym("ipv6");
1693
+ default:
1694
+ return rb_easy_sym("auto");
1695
+ }
1696
+ }
1697
+
1698
+ /*
1699
+ * call-seq:
1700
+ * easy.resolve_mode = symbol => symbol
1701
+ *
1702
+ * Configures what type of IP address this Curl::Easy instance
1703
+ * resolves DNS names to. Valid options are:
1704
+ *
1705
+ * [:auto] resolves DNS names to all IP versions your system allows
1706
+ * [:ipv4] resolves DNS names to IPv4 only
1707
+ * [:ipv6] resolves DNS names to IPv6 only
1708
+ */
1709
+ static VALUE ruby_curl_easy_resolve_mode_set(VALUE self, VALUE resolve_mode) {
1710
+ if (TYPE(resolve_mode) != T_SYMBOL) {
1711
+ rb_raise(rb_eTypeError, "Must pass a symbol");
1712
+ return Qnil;
1713
+ } else {
1714
+ ruby_curl_easy *rbce;
1715
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
1716
+
1717
+ ID resolve_mode_id = rb_to_id(resolve_mode);
1718
+
1719
+ if (resolve_mode_id == rb_intern("auto")) {
1720
+ rbce->resolve_mode = CURL_IPRESOLVE_WHATEVER;
1721
+ return resolve_mode;
1722
+ } else if (resolve_mode_id == rb_intern("ipv4")) {
1723
+ rbce->resolve_mode = CURL_IPRESOLVE_V4;
1724
+ return resolve_mode;
1725
+ } else if (resolve_mode_id == rb_intern("ipv6")) {
1726
+ rbce->resolve_mode = CURL_IPRESOLVE_V6;
1727
+ return resolve_mode;
1728
+ } else {
1729
+ rb_raise(rb_eArgError, "Must set to one of :auto, :ipv4, :ipv6");
1730
+ return Qnil;
1731
+ }
1732
+ }
1733
+ }
1734
+
1735
+
1736
+ /* ================= EVENT PROCS ================== */
1737
+
1738
+ /*
1739
+ * call-seq:
1740
+ * easy.on_body { |body_data| ... } => &lt;old handler&gt;
1741
+ *
1742
+ * Assign or remove the +on_body+ handler for this Curl::Easy instance.
1743
+ * To remove a previously-supplied handler, call this method with no
1744
+ * attached block.
1745
+ *
1746
+ * The +on_body+ handler is called for each chunk of response body passed back
1747
+ * by libcurl during +perform+. It should perform any processing necessary,
1748
+ * and return the actual number of bytes handled. Normally, this will
1749
+ * equal the length of the data string, and CURL will continue processing.
1750
+ * If the returned length does not equal the input length, CURL will abort
1751
+ * the processing with a Curl::Err::AbortedByCallbackError.
1752
+ */
1753
+ static VALUE ruby_curl_easy_on_body_set(int argc, VALUE *argv, VALUE self) {
1754
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, body_proc);
1755
+ }
1756
+
1757
+ /*
1758
+ * call-seq:
1759
+ * easy.on_success { |easy| ... } => &lt;old handler&gt;
1760
+ *
1761
+ * Assign or remove the +on_success+ handler for this Curl::Easy instance.
1762
+ * To remove a previously-supplied handler, call this method with no
1763
+ * attached block.
1764
+ *
1765
+ * The +on_success+ handler is called when the request is finished with a
1766
+ * status of 20x
1767
+ */
1768
+ static VALUE ruby_curl_easy_on_success_set(int argc, VALUE *argv, VALUE self) {
1769
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, success_proc);
1770
+ }
1771
+
1772
+ /*
1773
+ * call-seq:
1774
+ * easy.on_failure {|easy,code| ... } => &lt;old handler&gt;
1775
+ *
1776
+ * Assign or remove the +on_failure+ handler for this Curl::Easy instance.
1777
+ * To remove a previously-supplied handler, call this method with no
1778
+ * attached block.
1779
+ *
1780
+ * The +on_failure+ handler is called when the request is finished with a
1781
+ * status of 50x
1782
+ */
1783
+ static VALUE ruby_curl_easy_on_failure_set(int argc, VALUE *argv, VALUE self) {
1784
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, failure_proc);
1785
+ }
1786
+
1787
+ /*
1788
+ * call-seq:
1789
+ * easy.on_missing {|easy,code| ... } => &lt;old handler;&gt;
1790
+ *
1791
+ * Assign or remove the on_missing handler for this Curl::Easy instance.
1792
+ * To remove a previously-supplied handler, call this method with no attached
1793
+ * block.
1794
+ *
1795
+ * The +on_missing+ handler is called when request is finished with a
1796
+ * status of 40x
1797
+ */
1798
+ static VALUE ruby_curl_easy_on_missing_set(int argc, VALUE *argv, VALUE self) {
1799
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, missing_proc);
1800
+ }
1801
+
1802
+ /*
1803
+ * call-seq:
1804
+ * easy.on_redirect {|easy,code| ... } => &lt;old handler;&gt;
1805
+ *
1806
+ * Assign or remove the on_redirect handler for this Curl::Easy instance.
1807
+ * To remove a previously-supplied handler, call this method with no attached
1808
+ * block.
1809
+ *
1810
+ * The +on_redirect+ handler is called when request is finished with a
1811
+ * status of 30x
1812
+ */
1813
+ static VALUE ruby_curl_easy_on_redirect_set(int argc, VALUE *argv, VALUE self) {
1814
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, redirect_proc);
1815
+ }
1816
+
1817
+ /*
1818
+ * call-seq:
1819
+ * easy.on_complete {|easy| ... } => &lt;old handler&gt;
1820
+ *
1821
+ * Assign or remove the +on_complete+ handler for this Curl::Easy instance.
1822
+ * To remove a previously-supplied handler, call this method with no
1823
+ * attached block.
1824
+ *
1825
+ * The +on_complete+ handler is called when the request is finished.
1826
+ */
1827
+ static VALUE ruby_curl_easy_on_complete_set(int argc, VALUE *argv, VALUE self) {
1828
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, complete_proc);
1829
+ }
1830
+
1831
+ /*
1832
+ * call-seq:
1833
+ * easy.on_header { |header_data| ... } => &lt;old handler&gt;
1834
+ *
1835
+ * Assign or remove the +on_header+ handler for this Curl::Easy instance.
1836
+ * To remove a previously-supplied handler, call this method with no
1837
+ * attached block.
1838
+ *
1839
+ * The +on_header+ handler is called for each chunk of response header passed
1840
+ * back by libcurl during +perform+. The semantics are the same as for the
1841
+ * block supplied to +on_body+.
1842
+ */
1843
+ static VALUE ruby_curl_easy_on_header_set(int argc, VALUE *argv, VALUE self) {
1844
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, header_proc);
1845
+ }
1846
+
1847
+ /*
1848
+ * call-seq:
1849
+ * easy.on_progress { |dl_total, dl_now, ul_total, ul_now| ... } => &lt;old handler&gt;
1850
+ *
1851
+ * Assign or remove the +on_progress+ handler for this Curl::Easy instance.
1852
+ * To remove a previously-supplied handler, call this method with no
1853
+ * attached block.
1854
+ *
1855
+ * The +on_progress+ handler is called regularly by libcurl (approximately once
1856
+ * per second) during transfers to allow the application to receive progress
1857
+ * information. There is no guarantee that the reported progress will change
1858
+ * between calls.
1859
+ *
1860
+ * The result of the block call determines whether libcurl continues the transfer.
1861
+ * Returning a non-true value (i.e. nil or false) will cause the transfer to abort,
1862
+ * throwing a Curl::Err::AbortedByCallbackError.
1863
+ */
1864
+ static VALUE ruby_curl_easy_on_progress_set(int argc, VALUE *argv, VALUE self) {
1865
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, progress_proc);
1866
+ }
1867
+
1868
+ /*
1869
+ * call-seq:
1870
+ * easy.on_debug { |type, data| ... } => &lt;old handler&gt;
1871
+ *
1872
+ * Assign or remove the +on_debug+ handler for this Curl::Easy instance.
1873
+ * To remove a previously-supplied handler, call this method with no
1874
+ * attached block.
1875
+ *
1876
+ * The +on_debug+ handler, if configured, will receive detailed information
1877
+ * from libcurl during the perform call. This can be useful for debugging.
1878
+ * Setting a debug handler overrides libcurl's internal handler, disabling
1879
+ * any output from +verbose+, if set.
1880
+ *
1881
+ * The type argument will match one of the Curl::Easy::CURLINFO_XXXX
1882
+ * constants, and specifies the kind of information contained in the
1883
+ * data. The data is passed as a String.
1884
+ */
1885
+ static VALUE ruby_curl_easy_on_debug_set(int argc, VALUE *argv, VALUE self) {
1886
+ CURB_HANDLER_PROC_HSETTER(ruby_curl_easy, debug_proc);
1887
+ }
1888
+
1889
+
1890
+ /* =================== PERFORM =====================*/
1891
+
1892
+ /***********************************************
1893
+ * This is an rb_iterate callback used to set up http headers.
1894
+ */
1895
+ static VALUE cb_each_http_header(VALUE header, VALUE wrap) {
1896
+ struct curl_slist **list;
1897
+ Data_Get_Struct(wrap, struct curl_slist *, list);
1898
+
1899
+ VALUE header_str = Qnil;
1900
+
1901
+ //rb_p(header);
1902
+
1903
+ if (rb_type(header) == T_ARRAY) {
1904
+ // we're processing a hash, header is [name, val]
1905
+ VALUE name, value;
1906
+
1907
+ name = rb_obj_as_string(rb_ary_entry(header, 0));
1908
+ value = rb_obj_as_string(rb_ary_entry(header, 1));
1909
+
1910
+ // This is a bit inefficient, but we don't want to be modifying
1911
+ // the actual values in the original hash.
1912
+ header_str = rb_str_plus(name, rb_str_new2(": "));
1913
+ header_str = rb_str_plus(header_str, value);
1914
+ } else {
1915
+ header_str = rb_obj_as_string(header);
1916
+ }
1917
+
1918
+ //rb_p(header_str);
1919
+
1920
+ *list = curl_slist_append(*list, StringValuePtr(header_str));
1921
+ return header_str;
1922
+ }
1923
+
1924
+ /***********************************************
1925
+ * This is an rb_iterate callback used to set up ftp commands.
1926
+ */
1927
+ static VALUE cb_each_ftp_command(VALUE ftp_command, VALUE wrap) {
1928
+ struct curl_slist **list;
1929
+ Data_Get_Struct(wrap, struct curl_slist *, list);
1930
+
1931
+ VALUE ftp_command_string = rb_obj_as_string(ftp_command);
1932
+ *list = curl_slist_append(*list, StringValuePtr(ftp_command));
1933
+
1934
+ return ftp_command_string;
1935
+ }
1936
+
1937
+ /***********************************************
1938
+ *
1939
+ * Setup a connection
1940
+ *
1941
+ * Always returns Qtrue, rb_raise on error.
1942
+ */
1943
+ VALUE ruby_curl_easy_setup(ruby_curl_easy *rbce) {
1944
+ // TODO this could do with a bit of refactoring...
1945
+ CURL *curl;
1946
+ VALUE url, _url = rb_easy_get("url");
1947
+ struct curl_slist **hdrs = &(rbce->curl_headers);
1948
+ struct curl_slist **cmds = &(rbce->curl_ftp_commands);
1949
+
1950
+ curl = rbce->curl;
1951
+
1952
+ if (_url == Qnil) {
1953
+ rb_raise(eCurlErrError, "No URL supplied");
1954
+ }
1955
+
1956
+ url = rb_check_string_type(_url);
1957
+
1958
+ curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
1959
+
1960
+ // network stuff and auth
1961
+ if (!rb_easy_nil("interface_hm")) {
1962
+ curl_easy_setopt(curl, CURLOPT_INTERFACE, rb_easy_get_str("interface_hm"));
1963
+ } else {
1964
+ curl_easy_setopt(curl, CURLOPT_INTERFACE, NULL);
1965
+ }
1966
+
1967
+ #if HAVE_CURLOPT_USERNAME == 1 && HAVE_CURLOPT_PASSWORD == 1
1968
+ if (!rb_easy_nil("username")) {
1969
+ curl_easy_setopt(curl, CURLOPT_USERNAME, rb_easy_get_str("username"));
1970
+ } else {
1971
+ curl_easy_setopt(curl, CURLOPT_USERNAME, NULL);
1972
+ }
1973
+ if (!rb_easy_nil("password")) {
1974
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, rb_easy_get_str("password"));
1975
+ }
1976
+ else {
1977
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, NULL);
1978
+ }
1979
+ #endif
1980
+
1981
+ if (!rb_easy_nil("userpwd")) {
1982
+ curl_easy_setopt(curl, CURLOPT_USERPWD, rb_easy_get_str("userpwd"));
1983
+ #if HAVE_CURLOPT_USERNAME == 1
1984
+ } else if (rb_easy_nil("username") && rb_easy_nil("password")) { /* don't set this even to NULL if we have set username and password */
1985
+ #else
1986
+ } else {
1987
+ #endif
1988
+ curl_easy_setopt(curl, CURLOPT_USERPWD, NULL);
1989
+ }
1990
+
1991
+ if (rb_easy_nil("proxy_url")) {
1992
+ curl_easy_setopt(curl, CURLOPT_PROXY, NULL);
1993
+ } else {
1994
+ curl_easy_setopt(curl, CURLOPT_PROXY, rb_easy_get_str("proxy_url"));
1995
+ }
1996
+
1997
+ if (rb_easy_nil("proxypwd")) {
1998
+ curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, NULL);
1999
+ } else {
2000
+ curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, rb_easy_get_str("proxypwd"));
2001
+ }
2002
+
2003
+ // body/header procs
2004
+ if (!rb_easy_nil("body_proc")) {
2005
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)&proc_data_handler_body);
2006
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, rbce);
2007
+ /* clear out the body_data if it was set */
2008
+ rb_easy_del("body_data");
2009
+ } else {
2010
+ VALUE body_buffer = rb_easy_set("body_data", rb_str_buf_new(32768));
2011
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)&default_data_handler);
2012
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, body_buffer);
2013
+ }
2014
+
2015
+ if (!rb_easy_nil("header_proc")) {
2016
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)&proc_data_handler_header);
2017
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, rbce);
2018
+ /* clear out the header_data if it was set */
2019
+ rb_easy_del("header_data");
2020
+ } else {
2021
+ VALUE header_buffer = rb_easy_set("header_data", rb_str_buf_new(16384));
2022
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)&default_data_handler);
2023
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, header_buffer);
2024
+ }
2025
+
2026
+ /* encoding */
2027
+ if (!rb_easy_nil("encoding")) {
2028
+ curl_easy_setopt(curl, CURLOPT_ENCODING, rb_easy_get_str("encoding"));
2029
+ }
2030
+
2031
+ // progress and debug procs
2032
+ if (!rb_easy_nil("progress_proc")) {
2033
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, (curl_progress_callback)&proc_progress_handler);
2034
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, rb_easy_get("progress_proc"));
2035
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
2036
+ } else {
2037
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
2038
+ }
2039
+
2040
+ if (!rb_easy_nil("debug_proc")) {
2041
+ curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, (curl_debug_callback)&proc_debug_handler);
2042
+ curl_easy_setopt(curl, CURLOPT_DEBUGDATA, rb_easy_get("debug_proc"));
2043
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
2044
+ } else {
2045
+ // have to remove handler to re-enable standard verbosity
2046
+ curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, NULL);
2047
+ curl_easy_setopt(curl, CURLOPT_DEBUGDATA, NULL);
2048
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, rbce->verbose);
2049
+ }
2050
+
2051
+ /* general opts */
2052
+
2053
+ curl_easy_setopt(curl, CURLOPT_HEADER, rbce->header_in_body);
2054
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, rbce->follow_location);
2055
+ curl_easy_setopt(curl, CURLOPT_MAXREDIRS, rbce->max_redirs);
2056
+
2057
+ curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, rbce->proxy_tunnel);
2058
+ curl_easy_setopt(curl, CURLOPT_FILETIME, rbce->fetch_file_time);
2059
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, rbce->ssl_verify_peer);
2060
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, rbce->ssl_verify_host);
2061
+
2062
+ if ((rbce->use_netrc != Qnil) && (rbce->use_netrc != Qfalse)) {
2063
+ curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
2064
+ } else {
2065
+ curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
2066
+ }
2067
+
2068
+ curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, rbce->unrestricted_auth);
2069
+
2070
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, rbce->timeout);
2071
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, rbce->connect_timeout);
2072
+ curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, rbce->dns_cache_timeout);
2073
+
2074
+ curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, rbce->ignore_content_length);
2075
+
2076
+ curl_easy_setopt(curl, CURLOPT_IPRESOLVE, rbce->resolve_mode);
2077
+
2078
+
2079
+ #if LIBCURL_VERSION_NUM >= 0x070a08
2080
+ curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, rbce->ftp_response_timeout);
2081
+ #else
2082
+ if (rbce->ftp_response_timeout > 0) {
2083
+ rb_warn("Installed libcurl is too old to support ftp_response_timeout");
2084
+ }
2085
+ #endif
2086
+
2087
+ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, rbce->low_speed_limit);
2088
+ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, rbce->low_speed_time);
2089
+
2090
+ // Set up localport / proxy port
2091
+ // FIXME these won't get returned to default if they're unset Ruby
2092
+ if (rbce->proxy_port > 0) {
2093
+ curl_easy_setopt(curl, CURLOPT_PROXYPORT, rbce->proxy_port);
2094
+ }
2095
+
2096
+ if (rbce->local_port > 0) {
2097
+ #if LIBCURL_VERSION_NUM >= 0x070f02
2098
+ curl_easy_setopt(curl, CURLOPT_LOCALPORT, rbce->local_port);
2099
+
2100
+ if (rbce->local_port_range > 0) {
2101
+ curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, rbce->local_port_range);
2102
+ }
2103
+ #else
2104
+ rb_warn("Installed libcurl is too old to support local_port");
2105
+ #endif
2106
+ }
2107
+
2108
+ if (rbce->proxy_type != -1) {
2109
+ #if LIBCURL_VERSION_NUM >= 0x070a00
2110
+ if (rbce->proxy_type == -2) {
2111
+ rb_warn("Installed libcurl is too old to support the selected proxy type");
2112
+ } else {
2113
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, rbce->proxy_type);
2114
+ }
2115
+ } else {
2116
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
2117
+ #else
2118
+ rb_warn("Installed libcurl is too old to support proxy_type");
2119
+ #endif
2120
+ }
2121
+
2122
+ if (rbce->http_auth_types > 0) {
2123
+ #if LIBCURL_VERSION_NUM >= 0x070a06
2124
+ curl_easy_setopt(curl, CURLOPT_HTTPAUTH, rbce->http_auth_types);
2125
+ } else {
2126
+ curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
2127
+ #else
2128
+ rb_warn("Installed libcurl is too old to support http_auth_types");
2129
+ #endif
2130
+ }
2131
+
2132
+ if (rbce->proxy_auth_types > 0) {
2133
+ #if LIBCURL_VERSION_NUM >= 0x070a07
2134
+ curl_easy_setopt(curl, CURLOPT_PROXYAUTH, rbce->proxy_auth_types);
2135
+ } else {
2136
+ curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
2137
+ #else
2138
+ rb_warn("Installed libcurl is too old to support proxy_auth_types");
2139
+ #endif
2140
+ }
2141
+
2142
+ /* Set up HTTP cookie handling if necessary
2143
+ FIXME this may not get disabled if it's enabled, the disabled again from ruby.
2144
+ */
2145
+ if (rbce->enable_cookies) {
2146
+ if (!rb_easy_nil("cookiejar")) {
2147
+ curl_easy_setopt(curl, CURLOPT_COOKIEJAR, rb_easy_get_str("cookiejar"));
2148
+ }
2149
+
2150
+ if (!rb_easy_nil("cookiefile")) {
2151
+ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, rb_easy_get_str("cookiefile"));
2152
+ } else {
2153
+ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* "" = magic to just enable */
2154
+ }
2155
+ }
2156
+
2157
+ if (!rb_easy_nil("cookies")) {
2158
+ curl_easy_setopt(curl, CURLOPT_COOKIE, rb_easy_get_str("cookies"));
2159
+ }
2160
+
2161
+ /* Set up HTTPS cert handling if necessary */
2162
+ if (!rb_easy_nil("cert")) {
2163
+ if (!rb_easy_nil("certtype")) {
2164
+ curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, rb_easy_get_str("certtype"));
2165
+ }
2166
+ curl_easy_setopt(curl, CURLOPT_SSLCERT, rb_easy_get_str("cert"));
2167
+ if (!rb_easy_nil("certpassword")) {
2168
+ curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, rb_easy_get_str("certpassword"));
2169
+ }
2170
+ if (!rb_easy_nil("cert_key")) {
2171
+ curl_easy_setopt(curl, CURLOPT_SSLKEY, rb_easy_get_str("cert_key"));
2172
+ }
2173
+ }
2174
+
2175
+ if (!rb_easy_nil("cacert")) {
2176
+ curl_easy_setopt(curl, CURLOPT_CAINFO, rb_easy_get_str("cacert"));
2177
+ }
2178
+ #ifdef HAVE_CURL_CONFIG_CA
2179
+ else {
2180
+ curl_easy_setopt(curl, CURLOPT_CAINFO, CURL_CONFIG_CA);
2181
+ }
2182
+ #endif
2183
+
2184
+ #ifdef CURL_VERSION_SSL
2185
+ if (rbce->ssl_version > 0) {
2186
+ curl_easy_setopt(curl, CURLOPT_SSLVERSION, rbce->ssl_version);
2187
+ }
2188
+
2189
+ if (rbce->use_ssl > 0) {
2190
+ curl_easy_setopt(curl, CURB_FTPSSL, rbce->use_ssl);
2191
+ }
2192
+ #else
2193
+ if (rbce->ssl_version > 0 || rbce->use_ssl > 0) {
2194
+ rb_warn("libcurl is not configured with SSL support");
2195
+ }
2196
+ #endif
2197
+
2198
+ if (rbce->ftp_filemethod > 0) {
2199
+ curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, rbce->ftp_filemethod);
2200
+ }
2201
+
2202
+ /* Set the user-agent string if specified */
2203
+ if (!rb_easy_nil("useragent")) {
2204
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, rb_easy_get_str("useragent"));
2205
+ }
2206
+
2207
+ /* Setup HTTP headers if necessary */
2208
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); // XXX: maybe we shouldn't be clearing this?
2209
+
2210
+ if (!rb_easy_nil("headers")) {
2211
+ if (rb_easy_type_check("headers", T_ARRAY) || rb_easy_type_check("headers", T_HASH)) {
2212
+ VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, hdrs);
2213
+ rb_iterate(rb_each, rb_easy_get("headers"), cb_each_http_header, wrap);
2214
+ } else {
2215
+ VALUE headers_str = rb_obj_as_string(rb_easy_get("headers"));
2216
+ *hdrs = curl_slist_append(*hdrs, StringValuePtr(headers_str));
2217
+ }
2218
+
2219
+ if (*hdrs) {
2220
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, *hdrs);
2221
+ }
2222
+ }
2223
+
2224
+ /* Setup FTP commands if necessary */
2225
+ if (!rb_easy_nil("ftp_commands")) {
2226
+ if (rb_easy_type_check("ftp_commands", T_ARRAY)) {
2227
+ VALUE wrap = Data_Wrap_Struct(rb_cObject, 0, 0, cmds);
2228
+ rb_iterate(rb_each, rb_easy_get("ftp_commands"), cb_each_ftp_command, wrap);
2229
+ }
2230
+
2231
+ if (*cmds) {
2232
+ curl_easy_setopt(curl, CURLOPT_QUOTE, *cmds);
2233
+ }
2234
+ }
2235
+
2236
+ return Qnil;
2237
+ }
2238
+ /***********************************************
2239
+ *
2240
+ * Clean up a connection
2241
+ *
2242
+ * Always returns Qtrue.
2243
+ */
2244
+ VALUE ruby_curl_easy_cleanup( VALUE self, ruby_curl_easy *rbce ) {
2245
+
2246
+ CURL *curl = rbce->curl;
2247
+ struct curl_slist *ftp_commands;
2248
+
2249
+ /* Free everything up */
2250
+ if (rbce->curl_headers) {
2251
+ curl_slist_free_all(rbce->curl_headers);
2252
+ rbce->curl_headers = NULL;
2253
+ }
2254
+
2255
+ ftp_commands = rbce->curl_ftp_commands;
2256
+ if (ftp_commands) {
2257
+ curl_slist_free_all(ftp_commands);
2258
+ rbce->curl_ftp_commands = NULL;
2259
+ }
2260
+
2261
+ /* clean up a PUT request's curl options. */
2262
+ if (!rb_easy_nil("upload")) {
2263
+ rb_easy_del("upload"); // set the upload object to Qnil to let the GC clean up
2264
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 0);
2265
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
2266
+ curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
2267
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, 0);
2268
+ }
2269
+
2270
+ return Qnil;
2271
+ }
2272
+
2273
+ /*
2274
+ * Common implementation of easy.http(verb) and easy.http_delete
2275
+ */
2276
+ static VALUE ruby_curl_easy_perform_verb_str(VALUE self, const char *verb) {
2277
+ ruby_curl_easy *rbce;
2278
+ CURL *curl;
2279
+ VALUE retval;
2280
+
2281
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2282
+ curl = rbce->curl;
2283
+
2284
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb);
2285
+
2286
+ retval = rb_funcall(self, rb_intern("perform"), 0);
2287
+
2288
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
2289
+
2290
+ return retval;
2291
+ }
2292
+
2293
+ /*
2294
+ * call-seq:
2295
+ * easy.http(verb)
2296
+ *
2297
+ * Send an HTTP request with method set to verb, using the current options set for this Curl::Easy instance.
2298
+ * This method always returns true or raises an exception (defined under Curl::Err) on error.
2299
+ */
2300
+ static VALUE ruby_curl_easy_perform_verb(VALUE self, VALUE verb) {
2301
+ VALUE str_verb;
2302
+ if (rb_type(verb) == T_STRING) {
2303
+ return ruby_curl_easy_perform_verb_str(self, StringValueCStr(verb));
2304
+ }
2305
+ else if (rb_respond_to(verb,rb_intern("to_s"))) {
2306
+ str_verb = rb_funcall(verb, rb_intern("to_s"), 0);
2307
+ return ruby_curl_easy_perform_verb_str(self, StringValueCStr(str_verb));
2308
+ }
2309
+ else {
2310
+ rb_raise(rb_eRuntimeError, "Invalid HTTP VERB, must response to 'to_s'");
2311
+ }
2312
+ }
2313
+
2314
+ /*
2315
+ * call-seq:
2316
+ * easy.http_post("url=encoded%20form%20data;and=so%20on") => true
2317
+ * easy.http_post("url=encoded%20form%20data", "and=so%20on", ...) => true
2318
+ * easy.http_post("url=encoded%20form%20data", Curl::PostField, "and=so%20on", ...) => true
2319
+ * easy.http_post(Curl::PostField, Curl::PostField ..., Curl::PostField) => true
2320
+ *
2321
+ * POST the specified formdata to the currently configured URL using
2322
+ * the current options set for this Curl::Easy instance. This method
2323
+ * always returns true, or raises an exception (defined under
2324
+ * Curl::Err) on error.
2325
+ *
2326
+ * The Content-type of the POST is determined by the current setting
2327
+ * of multipart_form_post? , according to the following rules:
2328
+ * * When false (the default): the form will be POSTed with a
2329
+ * content-type of 'application/x-www-form-urlencoded', and any of the
2330
+ * four calling forms may be used.
2331
+ * * When true: the form will be POSTed with a content-type of
2332
+ * 'multipart/formdata'. Only the last calling form may be used,
2333
+ * i.e. only PostField instances may be POSTed. In this mode,
2334
+ * individual fields' content-types are recognised, and file upload
2335
+ * fields are supported.
2336
+ *
2337
+ */
2338
+ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
2339
+ ruby_curl_easy *rbce;
2340
+ CURL *curl;
2341
+ int i;
2342
+ VALUE args_ary;
2343
+
2344
+ rb_scan_args(argc, argv, "*", &args_ary);
2345
+
2346
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2347
+ curl = rbce->curl;
2348
+
2349
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
2350
+
2351
+ if (rbce->multipart_form_post) {
2352
+ VALUE ret;
2353
+ struct curl_httppost *first = NULL, *last = NULL;
2354
+
2355
+ // Make the multipart form
2356
+ for (i = 0; i < argc; i++) {
2357
+ if (rb_obj_is_instance_of(argv[i], cCurlPostField)) {
2358
+ append_to_form(argv[i], &first, &last);
2359
+ } else if (rb_type(argv[i]) == T_ARRAY) {
2360
+ // see: https://github.com/rvanlieshout/curb/commit/8bcdefddc0162484681ebd1a92d52a642666a445
2361
+ int c = 0, argv_len = (int)RARRAY_LEN(argv[i]);
2362
+ for (; c < argv_len; ++c) {
2363
+ if (rb_obj_is_instance_of(rb_ary_entry(argv[i],c), cCurlPostField)) {
2364
+ append_to_form(rb_ary_entry(argv[i],c), &first, &last);
2365
+ } else {
2366
+ rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
2367
+ return Qnil;
2368
+ }
2369
+ }
2370
+ } else {
2371
+ rb_raise(eCurlErrInvalidPostField, "You must use PostFields only with multipart form posts");
2372
+ return Qnil;
2373
+ }
2374
+ }
2375
+
2376
+ curl_easy_setopt(curl, CURLOPT_POST, 0);
2377
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, first);
2378
+ ret = rb_funcall(self, rb_intern("perform"), 0);
2379
+ curl_formfree(first);
2380
+
2381
+ return ret;
2382
+ } else {
2383
+ VALUE post_body = Qnil;
2384
+ /* TODO: check for PostField.file and raise error before to_s fails */
2385
+ if ((post_body = rb_funcall(args_ary, idJoin, 1, rbstrAmp)) == Qnil) {
2386
+ rb_raise(eCurlErrError, "Failed to join arguments");
2387
+ return Qnil;
2388
+ } else {
2389
+ /* if the function call above returns an empty string because no additional arguments were passed this makes sure
2390
+ a previously set easy.post_body = "arg=foo&bar=bin" will be honored */
2391
+ if( post_body != Qnil && rb_type(post_body) == T_STRING && RSTRING_LEN(post_body) > 0 ) {
2392
+ ruby_curl_easy_post_body_set(self, post_body);
2393
+ }
2394
+
2395
+ /* if post body is not defined, set it so we enable POST header, even though the request body is empty */
2396
+ if( rb_easy_nil("postdata_buffer") ) {
2397
+ ruby_curl_easy_post_body_set(self, post_body);
2398
+ }
2399
+
2400
+ return rb_funcall(self, rb_intern("perform"), 0);
2401
+ }
2402
+ }
2403
+ }
2404
+ static VALUE ruby_curl_easy_set_method_get(VALUE self, VALUE onoff) {
2405
+ ruby_curl_easy *rbce;
2406
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2407
+ curl_easy_setopt(rbce->curl, CURLOPT_HTTPGET, RTEST(onoff));
2408
+ return onoff;
2409
+ }
2410
+
2411
+ /*
2412
+ * call-seq:
2413
+ * easy.http_put(data) => true
2414
+ *
2415
+ * PUT the supplied data to the currently configured URL using the
2416
+ * current options set for this Curl::Easy instance. This method always
2417
+ * returns true, or raises an exception (defined under Curl::Err) on error.
2418
+ */
2419
+ static VALUE ruby_curl_easy_perform_put(VALUE self, VALUE data) {
2420
+ ruby_curl_easy *rbce;
2421
+ CURL *curl;
2422
+
2423
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2424
+ curl = rbce->curl;
2425
+
2426
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, NULL);
2427
+ ruby_curl_easy_put_data_set(self, data);
2428
+
2429
+ return rb_funcall(self, rb_intern("perform"), 0);
2430
+ }
2431
+
2432
+
2433
+ /* =================== DATA FUNCS =============== */
2434
+
2435
+ /*
2436
+ * call-seq:
2437
+ * easy.body_str => "response body"
2438
+ *
2439
+ * Return the response body from the previous call to +perform+. This
2440
+ * is populated by the default +on_body+ handler - if you supply
2441
+ * your own body handler, this string will be empty.
2442
+ */
2443
+ static VALUE ruby_curl_easy_body_str_get(VALUE self) {
2444
+ CURB_OBJECT_HGETTER(ruby_curl_easy, body_data);
2445
+ }
2446
+
2447
+ /*
2448
+ * call-seq:
2449
+ * easy.header_str => "response header"
2450
+ *
2451
+ * Return the response header from the previous call to +perform+. This
2452
+ * is populated by the default +on_header+ handler - if you supply
2453
+ * your own header handler, this string will be empty.
2454
+ */
2455
+ static VALUE ruby_curl_easy_header_str_get(VALUE self) {
2456
+ CURB_OBJECT_HGETTER(ruby_curl_easy, header_data);
2457
+ }
2458
+
2459
+
2460
+ /* ============== LASTCONN INFO FUNCS ============ */
2461
+
2462
+ /*
2463
+ * call-seq:
2464
+ * easy.last_effective_url => "http://some.url" or nil
2465
+ *
2466
+ * Retrieve the last effective URL used by this instance.
2467
+ * This is the URL used in the last +perform+ call,
2468
+ * and may differ from the value of easy.url.
2469
+ */
2470
+ static VALUE ruby_curl_easy_last_effective_url_get(VALUE self) {
2471
+ ruby_curl_easy *rbce;
2472
+ char* url;
2473
+
2474
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2475
+ curl_easy_getinfo(rbce->curl, CURLINFO_EFFECTIVE_URL, &url);
2476
+
2477
+ if (url && url[0]) { // curl returns empty string if none
2478
+ return rb_str_new2(url);
2479
+ } else {
2480
+ return Qnil;
2481
+ }
2482
+ }
2483
+
2484
+ /*
2485
+ * call-seq:
2486
+ * easy.response_code => fixnum
2487
+ *
2488
+ * Retrieve the last received HTTP or FTP code. This will be zero
2489
+ * if no server response code has been received. Note that a proxy's
2490
+ * CONNECT response should be read with +http_connect_code+
2491
+ * and not this method.
2492
+ */
2493
+ static VALUE ruby_curl_easy_response_code_get(VALUE self) {
2494
+ ruby_curl_easy *rbce;
2495
+ long code;
2496
+
2497
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2498
+ #ifdef HAVE_CURLINFO_RESPONSE_CODE
2499
+ curl_easy_getinfo(rbce->curl, CURLINFO_RESPONSE_CODE, &code);
2500
+ #else
2501
+ // old libcurl
2502
+ curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CODE, &code);
2503
+ #endif
2504
+
2505
+ return LONG2NUM(code);
2506
+ }
2507
+
2508
+ #if defined(HAVE_CURLINFO_PRIMARY_IP)
2509
+ /*
2510
+ * call-seq:
2511
+ * easy.primary_ip => "xx.xx.xx.xx" or nil
2512
+ *
2513
+ * Retrieve the resolved IP of the most recent connection
2514
+ * done with this curl handle. This string may be IPv6 if
2515
+ * that's enabled. This feature requires curl 7.19.x and above
2516
+ */
2517
+ static VALUE ruby_curl_easy_primary_ip_get(VALUE self) {
2518
+ ruby_curl_easy *rbce;
2519
+ char* ip;
2520
+
2521
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2522
+ curl_easy_getinfo(rbce->curl, CURLINFO_PRIMARY_IP, &ip);
2523
+
2524
+ if (ip && ip[0]) { // curl returns empty string if none
2525
+ return rb_str_new2(ip);
2526
+ } else {
2527
+ return Qnil;
2528
+ }
2529
+ }
2530
+ #endif
2531
+
2532
+ /*
2533
+ * call-seq:
2534
+ * easy.http_connect_code => fixnum
2535
+ *
2536
+ * Retrieve the last received proxy response code to a CONNECT request.
2537
+ */
2538
+ static VALUE ruby_curl_easy_http_connect_code_get(VALUE self) {
2539
+ ruby_curl_easy *rbce;
2540
+ long code;
2541
+
2542
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2543
+ curl_easy_getinfo(rbce->curl, CURLINFO_HTTP_CONNECTCODE, &code);
2544
+
2545
+ return LONG2NUM(code);
2546
+ }
2547
+
2548
+ /*
2549
+ * call-seq:
2550
+ * easy.file_time => fixnum
2551
+ *
2552
+ * Retrieve the remote time of the retrieved document (in number of
2553
+ * seconds since 1 jan 1970 in the GMT/UTC time zone). If you get -1,
2554
+ * it can be because of many reasons (unknown, the server hides it
2555
+ * or the server doesn't support the command that tells document time
2556
+ * etc) and the time of the document is unknown.
2557
+ *
2558
+ * Note that you must tell the server to collect this information
2559
+ * before the transfer is made, by setting +fetch_file_time?+ to true,
2560
+ * or you will unconditionally get a -1 back.
2561
+ *
2562
+ * This requires libcurl 7.5 or higher - otherwise -1 is unconditionally
2563
+ * returned.
2564
+ */
2565
+ static VALUE ruby_curl_easy_file_time_get(VALUE self) {
2566
+ #ifdef HAVE_CURLINFO_FILETIME
2567
+ ruby_curl_easy *rbce;
2568
+ long time;
2569
+
2570
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2571
+ curl_easy_getinfo(rbce->curl, CURLINFO_FILETIME, &time);
2572
+
2573
+ return LONG2NUM(time);
2574
+ #else
2575
+ rb_warn("Installed libcurl is too old to support file_time");
2576
+ return INT2FIX(0);
2577
+ #endif
2578
+ }
2579
+
2580
+ /*
2581
+ * call-seq:
2582
+ * easy.total_time => float
2583
+ *
2584
+ * Retrieve the total time in seconds for the previous transfer,
2585
+ * including name resolving, TCP connect etc.
2586
+ */
2587
+ static VALUE ruby_curl_easy_total_time_get(VALUE self) {
2588
+ ruby_curl_easy *rbce;
2589
+ double time;
2590
+
2591
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2592
+ curl_easy_getinfo(rbce->curl, CURLINFO_TOTAL_TIME, &time);
2593
+
2594
+ return rb_float_new(time);
2595
+ }
2596
+
2597
+ /*
2598
+ * call-seq:
2599
+ * easy.name_lookup_time => float
2600
+ *
2601
+ * Retrieve the time, in seconds, it took from the start until the
2602
+ * name resolving was completed.
2603
+ */
2604
+ static VALUE ruby_curl_easy_name_lookup_time_get(VALUE self) {
2605
+ ruby_curl_easy *rbce;
2606
+ double time;
2607
+
2608
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2609
+ curl_easy_getinfo(rbce->curl, CURLINFO_NAMELOOKUP_TIME, &time);
2610
+
2611
+ return rb_float_new(time);
2612
+ }
2613
+
2614
+ /*
2615
+ * call-seq:
2616
+ * easy.connect_time => float
2617
+ *
2618
+ * Retrieve the time, in seconds, it took from the start until the
2619
+ * connect to the remote host (or proxy) was completed.
2620
+ */
2621
+ static VALUE ruby_curl_easy_connect_time_get(VALUE self) {
2622
+ ruby_curl_easy *rbce;
2623
+ double time;
2624
+
2625
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2626
+ curl_easy_getinfo(rbce->curl, CURLINFO_CONNECT_TIME, &time);
2627
+
2628
+ return rb_float_new(time);
2629
+ }
2630
+
2631
+ /*
2632
+ * call-seq:
2633
+ * easy.pre_transfer_time => float
2634
+ *
2635
+ * Retrieve the time, in seconds, it took from the start until the
2636
+ * file transfer is just about to begin. This includes all pre-transfer
2637
+ * commands and negotiations that are specific to the particular protocol(s)
2638
+ * involved.
2639
+ */
2640
+ static VALUE ruby_curl_easy_pre_transfer_time_get(VALUE self) {
2641
+ ruby_curl_easy *rbce;
2642
+ double time;
2643
+
2644
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2645
+ curl_easy_getinfo(rbce->curl, CURLINFO_PRETRANSFER_TIME, &time);
2646
+
2647
+ return rb_float_new(time);
2648
+ }
2649
+
2650
+ /*
2651
+ * call-seq:
2652
+ * easy.start_transfer_time => float
2653
+ *
2654
+ * Retrieve the time, in seconds, it took from the start until the first byte
2655
+ * is just about to be transferred. This includes the +pre_transfer_time+ and
2656
+ * also the time the server needs to calculate the result.
2657
+ */
2658
+ static VALUE ruby_curl_easy_start_transfer_time_get(VALUE self) {
2659
+ ruby_curl_easy *rbce;
2660
+ double time;
2661
+
2662
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2663
+ curl_easy_getinfo(rbce->curl, CURLINFO_STARTTRANSFER_TIME, &time);
2664
+
2665
+ return rb_float_new(time);
2666
+ }
2667
+
2668
+ /*
2669
+ * call-seq:
2670
+ * easy.redirect_time => float
2671
+ *
2672
+ * Retrieve the total time, in seconds, it took for all redirection steps
2673
+ * include name lookup, connect, pretransfer and transfer before final
2674
+ * transaction was started. +redirect_time+ contains the complete
2675
+ * execution time for multiple redirections.
2676
+ *
2677
+ * Requires libcurl 7.9.7 or higher, otherwise -1 is always returned.
2678
+ */
2679
+ static VALUE ruby_curl_easy_redirect_time_get(VALUE self) {
2680
+ #ifdef HAVE_CURLINFO_REDIRECT_TIME
2681
+ ruby_curl_easy *rbce;
2682
+ double time;
2683
+
2684
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2685
+ curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_TIME, &time);
2686
+
2687
+ return rb_float_new(time);
2688
+ #else
2689
+ rb_warn("Installed libcurl is too old to support redirect_time");
2690
+ return rb_float_new(-1);
2691
+ #endif
2692
+ }
2693
+
2694
+ /*
2695
+ * call-seq:
2696
+ * easy.redirect_count => integer
2697
+ *
2698
+ * Retrieve the total number of redirections that were actually followed.
2699
+ *
2700
+ * Requires libcurl 7.9.7 or higher, otherwise -1 is always returned.
2701
+ */
2702
+ static VALUE ruby_curl_easy_redirect_count_get(VALUE self) {
2703
+ #ifdef HAVE_CURLINFO_REDIRECT_COUNT
2704
+ ruby_curl_easy *rbce;
2705
+ long count;
2706
+
2707
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2708
+ curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_COUNT, &count);
2709
+
2710
+ return LONG2NUM(count);
2711
+ #else
2712
+ rb_warn("Installed libcurl is too old to support redirect_count");
2713
+ return INT2FIX(-1);
2714
+ #endif
2715
+
2716
+ }
2717
+
2718
+ /*
2719
+ * call-seq:
2720
+ * easy.redirect_url => "http://some.url" or nil
2721
+ *
2722
+ * Retrieve the URL a redirect would take you to if you
2723
+ * would enable CURLOPT_FOLLOWLOCATION.
2724
+ *
2725
+ * Requires libcurl 7.18.2 or higher, otherwise -1 is always returned.
2726
+ */
2727
+ static VALUE ruby_curl_easy_redirect_url_get(VALUE self) {
2728
+ #ifdef HAVE_CURLINFO_REDIRECT_URL
2729
+ ruby_curl_easy *rbce;
2730
+ char* url;
2731
+
2732
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2733
+ curl_easy_getinfo(rbce->curl, CURLINFO_REDIRECT_URL, &url);
2734
+
2735
+ if (url && url[0]) { // curl returns empty string if none
2736
+ return rb_str_new2(url);
2737
+ } else {
2738
+ return Qnil;
2739
+ }
2740
+ #else
2741
+ rb_warn("Installed libcurl is too old to support redirect_url");
2742
+ return INT2FIX(-1);
2743
+ #endif
2744
+ }
2745
+
2746
+
2747
+
2748
+ /*
2749
+ * call-seq:
2750
+ * easy.uploaded_bytes => float
2751
+ *
2752
+ * Retrieve the total amount of bytes that were uploaded in the
2753
+ * preceeding transfer.
2754
+ */
2755
+ static VALUE ruby_curl_easy_uploaded_bytes_get(VALUE self) {
2756
+ ruby_curl_easy *rbce;
2757
+ double bytes;
2758
+
2759
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2760
+ curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_UPLOAD, &bytes);
2761
+
2762
+ return rb_float_new(bytes);
2763
+ }
2764
+
2765
+ /*
2766
+ * call-seq:
2767
+ * easy.downloaded_bytes => float
2768
+ *
2769
+ * Retrieve the total amount of bytes that were downloaded in the
2770
+ * preceeding transfer.
2771
+ */
2772
+ static VALUE ruby_curl_easy_downloaded_bytes_get(VALUE self) {
2773
+ ruby_curl_easy *rbce;
2774
+ double bytes;
2775
+
2776
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2777
+ curl_easy_getinfo(rbce->curl, CURLINFO_SIZE_DOWNLOAD, &bytes);
2778
+
2779
+ return rb_float_new(bytes);
2780
+ }
2781
+
2782
+ /*
2783
+ * call-seq:
2784
+ * easy.upload_speed => float
2785
+ *
2786
+ * Retrieve the average upload speed that curl measured for the
2787
+ * preceeding complete upload.
2788
+ */
2789
+ static VALUE ruby_curl_easy_upload_speed_get(VALUE self) {
2790
+ ruby_curl_easy *rbce;
2791
+ double bytes;
2792
+
2793
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2794
+ curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_UPLOAD, &bytes);
2795
+
2796
+ return rb_float_new(bytes);
2797
+ }
2798
+
2799
+ /*
2800
+ * call-seq:
2801
+ * easy.download_speed => float
2802
+ *
2803
+ * Retrieve the average download speed that curl measured for
2804
+ * the preceeding complete download.
2805
+ */
2806
+ static VALUE ruby_curl_easy_download_speed_get(VALUE self) {
2807
+ ruby_curl_easy *rbce;
2808
+ double bytes;
2809
+
2810
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2811
+ curl_easy_getinfo(rbce->curl, CURLINFO_SPEED_DOWNLOAD, &bytes);
2812
+
2813
+ return rb_float_new(bytes);
2814
+ }
2815
+
2816
+ /*
2817
+ * call-seq:
2818
+ * easy.header_size => fixnum
2819
+ *
2820
+ * Retrieve the total size of all the headers received in the
2821
+ * preceeding transfer.
2822
+ */
2823
+ static VALUE ruby_curl_easy_header_size_get(VALUE self) {
2824
+ ruby_curl_easy *rbce;
2825
+ long size;
2826
+
2827
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2828
+ curl_easy_getinfo(rbce->curl, CURLINFO_HEADER_SIZE, &size);
2829
+
2830
+ return LONG2NUM(size);
2831
+ }
2832
+
2833
+ /*
2834
+ * call-seq:
2835
+ * easy.request_size => fixnum
2836
+ *
2837
+ * Retrieve the total size of the issued requests. This is so far
2838
+ * only for HTTP requests. Note that this may be more than one request
2839
+ * if +follow_location?+ is true.
2840
+ */
2841
+ static VALUE ruby_curl_easy_request_size_get(VALUE self) {
2842
+ ruby_curl_easy *rbce;
2843
+ long size;
2844
+
2845
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2846
+ curl_easy_getinfo(rbce->curl, CURLINFO_REQUEST_SIZE, &size);
2847
+
2848
+ return LONG2NUM(size);
2849
+ }
2850
+
2851
+ /*
2852
+ * call-seq:
2853
+ * easy.ssl_verify_result => integer
2854
+ *
2855
+ * Retrieve the result of the certification verification that was requested
2856
+ * (by setting +ssl_verify_peer?+ to +true+).
2857
+ */
2858
+ static VALUE ruby_curl_easy_ssl_verify_result_get(VALUE self) {
2859
+ ruby_curl_easy *rbce;
2860
+ long result;
2861
+
2862
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2863
+ curl_easy_getinfo(rbce->curl, CURLINFO_SSL_VERIFYRESULT, &result);
2864
+
2865
+ return LONG2NUM(result);
2866
+ }
2867
+
2868
+ /* TODO CURLINFO_SSL_ENGINES
2869
+
2870
+ Pass the address of a 'struct curl_slist *' to receive a linked-list of OpenSSL crypto-engines supported.
2871
+ Note that engines are normally implemented in separate dynamic libraries.
2872
+ Hence not all the returned engines may be available at run-time.
2873
+ NOTE: you must call curl_slist_free_all(3) on the list pointer once you're done with it, as libcurl will not free the data for you. (Added in 7.12.3)
2874
+ */
2875
+
2876
+ /*
2877
+ * call-seq:
2878
+ * easy.downloaded_content_length => float
2879
+ *
2880
+ * Retrieve the content-length of the download. This is the value read
2881
+ * from the Content-Length: field.
2882
+ */
2883
+ static VALUE ruby_curl_easy_downloaded_content_length_get(VALUE self) {
2884
+ ruby_curl_easy *rbce;
2885
+ double bytes;
2886
+
2887
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2888
+ curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &bytes);
2889
+
2890
+ return rb_float_new(bytes);
2891
+ }
2892
+
2893
+ /*
2894
+ * call-seq:
2895
+ * easy.uploaded_content_length => float
2896
+ *
2897
+ * Retrieve the content-length of the upload.
2898
+ */
2899
+ static VALUE ruby_curl_easy_uploaded_content_length_get(VALUE self) {
2900
+ ruby_curl_easy *rbce;
2901
+ double bytes;
2902
+
2903
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2904
+ curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_LENGTH_UPLOAD, &bytes);
2905
+
2906
+ return rb_float_new(bytes);
2907
+ }
2908
+
2909
+ /*
2910
+ * call-seq:
2911
+ * easy.content_type => "content/type" or nil
2912
+ *
2913
+ * Retrieve the content-type of the downloaded object. This is the value read
2914
+ * from the Content-Type: field. If you get +nil+, it means that the server
2915
+ * didn't send a valid Content-Type header or that the protocol used doesn't
2916
+ * support this.
2917
+ */
2918
+ static VALUE ruby_curl_easy_content_type_get(VALUE self) {
2919
+ ruby_curl_easy *rbce;
2920
+ char* type;
2921
+
2922
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2923
+ curl_easy_getinfo(rbce->curl, CURLINFO_CONTENT_TYPE, &type);
2924
+
2925
+ if (type && type[0]) { // curl returns empty string if none
2926
+ return rb_str_new2(type);
2927
+ } else {
2928
+ return Qnil;
2929
+ }
2930
+ }
2931
+
2932
+
2933
+ /* NOT REQUIRED?
2934
+ CURLINFO_PRIVATE
2935
+
2936
+ Pass a pointer to a 'char *' to receive the pointer to the private data associated with the curl handle (set with the CURLOPT_PRIVATE option to curl_easy_setopt(3)). (Added in 7.10.3)
2937
+ */
2938
+
2939
+ /* TODO these will need constants setting up too for checking the bits.
2940
+ *
2941
+ * Alternatively, could return an object that wraps the long, and has
2942
+ * question methods to query the auth types. Could return long from to_i(nt)
2943
+ *
2944
+ CURLINFO_HTTPAUTH_AVAIL
2945
+
2946
+ Pass a pointer to a long to receive a bitmask indicating the authentication method(s) available. The meaning of the bits is explained in the CURLOPT_HTTPAUTH option for curl_easy_setopt(3). (Added in 7.10.8)
2947
+
2948
+ CURLINFO_PROXYAUTH_AVAIL
2949
+
2950
+ Pass a pointer to a long to receive a bitmask indicating the authentication method(s) available for your proxy authentication. (Added in 7.10.8)
2951
+ */
2952
+
2953
+ /*
2954
+ * call-seq:
2955
+ * easy.os_errno => integer
2956
+ *
2957
+ * Retrieve the errno variable from a connect failure (requires
2958
+ * libcurl 7.12.2 or higher, otherwise 0 is always returned).
2959
+ */
2960
+ static VALUE ruby_curl_easy_os_errno_get(VALUE self) {
2961
+ #ifdef HAVE_CURLINFO_OS_ERRNO
2962
+ ruby_curl_easy *rbce;
2963
+ long result;
2964
+
2965
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2966
+ curl_easy_getinfo(rbce->curl, CURLINFO_OS_ERRNO, &result);
2967
+
2968
+ return LONG2NUM(result);
2969
+ #else
2970
+ rb_warn("Installed libcurl is too old to support os_errno");
2971
+ return INT2FIX(0);
2972
+ #endif
2973
+ }
2974
+
2975
+ /*
2976
+ * call-seq:
2977
+ * easy.num_connects => integer
2978
+ *
2979
+ * Retrieve the number of new connections libcurl had to create to achieve
2980
+ * the previous transfer (only the successful connects are counted).
2981
+ * Combined with +redirect_count+ you are able to know how many times libcurl
2982
+ * successfully reused existing connection(s) or not.
2983
+ *
2984
+ * See the Connection Options of curl_easy_setopt(3) to see how libcurl tries
2985
+ * to make persistent connections to save time.
2986
+ *
2987
+ * (requires libcurl 7.12.3 or higher, otherwise -1 is always returned).
2988
+ */
2989
+ static VALUE ruby_curl_easy_num_connects_get(VALUE self) {
2990
+ #ifdef HAVE_CURLINFO_NUM_CONNECTS
2991
+ ruby_curl_easy *rbce;
2992
+ long result;
2993
+
2994
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
2995
+ curl_easy_getinfo(rbce->curl, CURLINFO_NUM_CONNECTS, &result);
2996
+
2997
+ return LONG2NUM(result);
2998
+ #else
2999
+ rb_warn("Installed libcurl is too old to support num_connects");
3000
+ return INT2FIX(-1);
3001
+ #endif
3002
+ }
3003
+
3004
+
3005
+ /* TODO this needs to be implemented.
3006
+
3007
+ CURLINFO_COOKIELIST
3008
+
3009
+ Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all cookies cURL knows (expired ones, too). Don't forget to curl_slist_free_all(3) the list after it has been used. If there are no cookies (cookies for the handle have not been enabled or simply none have been received) 'struct curl_slist *' will be set to point to NULL. (Added in 7.14.1)
3010
+ */
3011
+
3012
+ /* TODO this needs to be implemented. Could probably support CONNECT_ONLY by having this
3013
+ * return an open Socket or something.
3014
+ *
3015
+ CURLINFO_LASTSOCKET
3016
+
3017
+ Pass a pointer to a long to receive the last socket used by this curl session. If the socket is no longer valid, -1 is returned. When you finish working with the socket, you must call curl_easy_cleanup() as usual and let libcurl close the socket and cleanup other resources associated with the handle. This is typically used in combination with CURLOPT_CONNECT_ONLY. (Added in 7.15.2)
3018
+ */
3019
+
3020
+ /*
3021
+ * call-seq:
3022
+ * easy.ftp_entry_path => "C:\ftp\root\" or nil
3023
+ *
3024
+ * Retrieve the path of the entry path. That is the initial path libcurl ended
3025
+ * up in when logging on to the remote FTP server. This returns +nil+ if
3026
+ * something is wrong.
3027
+ *
3028
+ * (requires libcurl 7.15.4 or higher, otherwise +nil+ is always returned).
3029
+ */
3030
+ static VALUE ruby_curl_easy_ftp_entry_path_get(VALUE self) {
3031
+ #ifdef HAVE_CURLINFO_FTP_ENTRY_PATH
3032
+ ruby_curl_easy *rbce;
3033
+ char* path = NULL;
3034
+
3035
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3036
+ curl_easy_getinfo(rbce->curl, CURLINFO_FTP_ENTRY_PATH, &path);
3037
+
3038
+ if (path && path[0]) { // curl returns NULL or empty string if none
3039
+ return rb_str_new2(path);
3040
+ } else {
3041
+ return Qnil;
3042
+ }
3043
+ #else
3044
+ rb_warn("Installed libcurl is too old to support num_connects");
3045
+ return Qnil;
3046
+ #endif
3047
+ }
3048
+
3049
+ /*
3050
+ * call-seq:
3051
+ * easy.multi => "#<Curl::Multi>"
3052
+ */
3053
+ static VALUE ruby_curl_easy_multi_get(VALUE self) {
3054
+ ruby_curl_easy *rbce;
3055
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3056
+ return rbce->multi;
3057
+ }
3058
+
3059
+ /*
3060
+ * call-seq:
3061
+ * easy.multi=multi => "#<Curl::Multi>"
3062
+ */
3063
+ static VALUE ruby_curl_easy_multi_set(VALUE self, VALUE multi) {
3064
+ ruby_curl_easy *rbce;
3065
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3066
+ rbce->multi = multi;
3067
+ return rbce->multi;
3068
+ }
3069
+
3070
+ /*
3071
+ * call-seq:
3072
+ * easy.last_result => 0
3073
+ */
3074
+ static VALUE ruby_curl_easy_last_result(VALUE self) {
3075
+ ruby_curl_easy *rbce;
3076
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3077
+ return INT2FIX(rbce->last_result);
3078
+ }
3079
+
3080
+ /*
3081
+ * call-seq:
3082
+ * easy.setopt Fixnum, value => value
3083
+ *
3084
+ * Iniital access to libcurl curl_easy_setopt
3085
+ */
3086
+ static VALUE ruby_curl_easy_set_opt(VALUE self, VALUE opt, VALUE val) {
3087
+ ruby_curl_easy *rbce;
3088
+ long option = FIX2LONG(opt);
3089
+
3090
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3091
+
3092
+ switch (option) {
3093
+ /* BEHAVIOR OPTIONS */
3094
+ case CURLOPT_VERBOSE: {
3095
+ VALUE verbose = val;
3096
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, verbose);
3097
+ } break;
3098
+ case CURLOPT_FOLLOWLOCATION: {
3099
+ VALUE follow_location = val;
3100
+ CURB_BOOLEAN_SETTER(ruby_curl_easy, follow_location);
3101
+ } break;
3102
+ /* TODO: CALLBACK OPTIONS */
3103
+ /* TODO: ERROR OPTIONS */
3104
+ /* NETWORK OPTIONS */
3105
+ case CURLOPT_URL: {
3106
+ VALUE url = val;
3107
+ CURB_OBJECT_HSETTER(ruby_curl_easy, url);
3108
+ } break;
3109
+ case CURLOPT_CUSTOMREQUEST:
3110
+ curl_easy_setopt(rbce->curl, CURLOPT_CUSTOMREQUEST, NIL_P(val) ? NULL : StringValueCStr(val));
3111
+ break;
3112
+ case CURLOPT_HTTP_VERSION:
3113
+ curl_easy_setopt(rbce->curl, CURLOPT_HTTP_VERSION, FIX2INT(val));
3114
+ break;
3115
+ case CURLOPT_PROXY: {
3116
+ VALUE proxy_url = val;
3117
+ CURB_OBJECT_HSETTER(ruby_curl_easy, proxy_url);
3118
+ } break;
3119
+ case CURLOPT_INTERFACE: {
3120
+ VALUE interface_hm = val;
3121
+ CURB_OBJECT_HSETTER(ruby_curl_easy, interface_hm);
3122
+ } break;
3123
+ case CURLOPT_HEADER:
3124
+ case CURLOPT_NOPROGRESS:
3125
+ case CURLOPT_NOSIGNAL:
3126
+ case CURLOPT_HTTPGET:
3127
+ case CURLOPT_NOBODY: {
3128
+ int type = rb_type(val);
3129
+ VALUE value;
3130
+ if (type == T_TRUE) {
3131
+ value = rb_int_new(1);
3132
+ } else if (type == T_FALSE) {
3133
+ value = rb_int_new(0);
3134
+ } else {
3135
+ value = rb_funcall(val, rb_intern("to_i"), 0);
3136
+ }
3137
+ curl_easy_setopt(rbce->curl, option, FIX2INT(value));
3138
+ } break;
3139
+ case CURLOPT_USERPWD: {
3140
+ VALUE userpwd = val;
3141
+ CURB_OBJECT_HSETTER(ruby_curl_easy, userpwd);
3142
+ } break;
3143
+ case CURLOPT_PROXYUSERPWD: {
3144
+ VALUE proxypwd = val;
3145
+ CURB_OBJECT_HSETTER(ruby_curl_easy, proxypwd);
3146
+ } break;
3147
+ case CURLOPT_COOKIE: {
3148
+ VALUE cookies = val;
3149
+ CURB_OBJECT_HSETTER(ruby_curl_easy, cookies);
3150
+ } break;
3151
+ case CURLOPT_COOKIEFILE: {
3152
+ VALUE cookiefile = val;
3153
+ CURB_OBJECT_HSETTER(ruby_curl_easy, cookiefile);
3154
+ } break;
3155
+ case CURLOPT_COOKIEJAR: {
3156
+ VALUE cookiejar = val;
3157
+ CURB_OBJECT_HSETTER(ruby_curl_easy, cookiejar);
3158
+ } break;
3159
+ case CURLOPT_RESUME_FROM: {
3160
+ curl_easy_setopt(rbce->curl, CURLOPT_RESUME_FROM, FIX2LONG(val));
3161
+ } break;
3162
+ case CURLOPT_FAILONERROR: {
3163
+ curl_easy_setopt(rbce->curl, CURLOPT_FAILONERROR, FIX2LONG(val));
3164
+ } break;
3165
+ default:
3166
+ break;
3167
+ }
3168
+
3169
+ return val;
3170
+ }
3171
+
3172
+ /*
3173
+ * call-seq:
3174
+ * easy.getinfo Fixnum => value
3175
+ *
3176
+ * Iniital access to libcurl curl_easy_getinfo, remember getinfo doesn't return the same values as setopt
3177
+ */
3178
+ static VALUE ruby_curl_easy_get_opt(VALUE self, VALUE opt) {
3179
+ return Qnil;
3180
+ }
3181
+
3182
+ /*
3183
+ * call-seq:
3184
+ * easy.inspect => "#<Curl::Easy http://google.com/>"
3185
+ */
3186
+ static VALUE ruby_curl_easy_inspect(VALUE self) {
3187
+ char buf[64];
3188
+ ruby_curl_easy *rbce;
3189
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3190
+ /* if we don't have a url set... we'll crash... */
3191
+ if( !rb_easy_nil("url") && rb_easy_type_check("url", T_STRING)) {
3192
+ VALUE url = rb_easy_get("url");
3193
+ size_t len = 13+((RSTRING_LEN(url) > 50) ? 50 : RSTRING_LEN(url));
3194
+ /* "#<Net::HTTP http://www.google.com/:80 open=false>" */
3195
+ memcpy(buf,"#<Curl::Easy ", 13);
3196
+ memcpy(buf+13,StringValueCStr(url), (len - 13));
3197
+ buf[len++] = '>';
3198
+ return rb_str_new(buf,len);
3199
+ }
3200
+ return rb_str_new2("#<Curl::Easy>");
3201
+ }
3202
+
3203
+
3204
+ /* ================== ESCAPING FUNCS ==============*/
3205
+
3206
+ /*
3207
+ * call-seq:
3208
+ * easy.escape("some text") => "some%20text"
3209
+ *
3210
+ * Convert the given input string to a URL encoded string and return
3211
+ * the result. All input characters that are not a-z, A-Z or 0-9 are
3212
+ * converted to their "URL escaped" version (%NN where NN is a
3213
+ * two-digit hexadecimal number).
3214
+ */
3215
+ static VALUE ruby_curl_easy_escape(VALUE self, VALUE svalue) {
3216
+ ruby_curl_easy *rbce;
3217
+ char *result;
3218
+ VALUE rresult;
3219
+ VALUE str = svalue;
3220
+
3221
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3222
+
3223
+ /* NOTE: make sure the value is a string, if not call to_s */
3224
+ if( rb_type(str) != T_STRING ) { str = rb_funcall(str,rb_intern("to_s"),0); }
3225
+
3226
+ #if (LIBCURL_VERSION_NUM >= 0x070f04)
3227
+ result = (char*)curl_easy_escape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str));
3228
+ #else
3229
+ result = (char*)curl_escape(StringValuePtr(str), (int)RSTRING_LEN(str));
3230
+ #endif
3231
+
3232
+ rresult = rb_str_new2(result);
3233
+ curl_free(result);
3234
+
3235
+ return rresult;
3236
+ }
3237
+
3238
+ /*
3239
+ * call-seq:
3240
+ * easy.unescape("some%20text") => "some text"
3241
+ *
3242
+ * Convert the given URL encoded input string to a "plain string" and return
3243
+ * the result. All input characters that are URL encoded (%XX where XX is a
3244
+ * two-digit hexadecimal number) are converted to their binary versions.
3245
+ */
3246
+ static VALUE ruby_curl_easy_unescape(VALUE self, VALUE str) {
3247
+ ruby_curl_easy *rbce;
3248
+ int rlen;
3249
+ char *result;
3250
+ VALUE rresult;
3251
+
3252
+ Data_Get_Struct(self, ruby_curl_easy, rbce);
3253
+
3254
+ #if (LIBCURL_VERSION_NUM >= 0x070f04)
3255
+ result = (char*)curl_easy_unescape(rbce->curl, StringValuePtr(str), (int)RSTRING_LEN(str), &rlen);
3256
+ #else
3257
+ result = (char*)curl_unescape(StringValuePtr(str), RSTRING_LEN(str));
3258
+ rlen = strlen(result);
3259
+ #endif
3260
+
3261
+ rresult = rb_str_new(result, rlen);
3262
+ curl_free(result);
3263
+
3264
+ return rresult;
3265
+ }
3266
+
3267
+
3268
+ /* ================= CLASS METHODS ==================*/
3269
+
3270
+ /*
3271
+ * call-seq:
3272
+ * Curl::Easy.error(code) => String
3273
+ *
3274
+ * translate an internal libcurl error to ruby error class
3275
+ */
3276
+ static VALUE ruby_curl_easy_error_message(VALUE klass, VALUE code) {
3277
+ return rb_curl_easy_error(FIX2INT(code));
3278
+ }
3279
+
3280
+ /* =================== INIT LIB =====================*/
3281
+ void init_curb_easy() {
3282
+ idCall = rb_intern("call");
3283
+ idJoin = rb_intern("join");
3284
+
3285
+ rbstrAmp = rb_str_new2("&");
3286
+ rb_global_variable(&rbstrAmp);
3287
+
3288
+ cCurlEasy = rb_define_class_under(mCurl, "Easy", rb_cObject);
3289
+
3290
+ /* Class methods */
3291
+ rb_define_singleton_method(cCurlEasy, "new", ruby_curl_easy_new, -1);
3292
+ rb_define_singleton_method(cCurlEasy, "error", ruby_curl_easy_error_message, 1);
3293
+
3294
+ /* Attributes for config next perform */
3295
+ rb_define_method(cCurlEasy, "url", ruby_curl_easy_url_get, 0);
3296
+ rb_define_method(cCurlEasy, "proxy_url", ruby_curl_easy_proxy_url_get, 0);
3297
+ rb_define_method(cCurlEasy, "headers=", ruby_curl_easy_headers_set, 1);
3298
+ rb_define_method(cCurlEasy, "headers", ruby_curl_easy_headers_get, 0);
3299
+ rb_define_method(cCurlEasy, "interface", ruby_curl_easy_interface_get, 0);
3300
+ rb_define_method(cCurlEasy, "userpwd", ruby_curl_easy_userpwd_get, 0);
3301
+ rb_define_method(cCurlEasy, "proxypwd", ruby_curl_easy_proxypwd_get, 0);
3302
+ rb_define_method(cCurlEasy, "cookies", ruby_curl_easy_cookies_get, 0);
3303
+ rb_define_method(cCurlEasy, "cookiefile", ruby_curl_easy_cookiefile_get, 0);
3304
+ rb_define_method(cCurlEasy, "cookiejar", ruby_curl_easy_cookiejar_get, 0);
3305
+ rb_define_method(cCurlEasy, "cert=", ruby_curl_easy_cert_set, 1);
3306
+ rb_define_method(cCurlEasy, "cert", ruby_curl_easy_cert_get, 0);
3307
+ rb_define_method(cCurlEasy, "cert_key=", ruby_curl_easy_cert_key_set, 1);
3308
+ rb_define_method(cCurlEasy, "cert_key", ruby_curl_easy_cert_key_get, 0);
3309
+ rb_define_method(cCurlEasy, "cacert=", ruby_curl_easy_cacert_set, 1);
3310
+ rb_define_method(cCurlEasy, "cacert", ruby_curl_easy_cacert_get, 0);
3311
+ rb_define_method(cCurlEasy, "certpassword=", ruby_curl_easy_certpassword_set, 1);
3312
+ rb_define_method(cCurlEasy, "certtype=", ruby_curl_easy_certtype_set, 1);
3313
+ rb_define_method(cCurlEasy, "certtype", ruby_curl_easy_certtype_get, 0);
3314
+ rb_define_method(cCurlEasy, "encoding=", ruby_curl_easy_encoding_set, 1);
3315
+ rb_define_method(cCurlEasy, "encoding", ruby_curl_easy_encoding_get, 0);
3316
+ rb_define_method(cCurlEasy, "useragent=", ruby_curl_easy_useragent_set, 1);
3317
+ rb_define_method(cCurlEasy, "useragent", ruby_curl_easy_useragent_get, 0);
3318
+ rb_define_method(cCurlEasy, "multipart_post_body=", ruby_curl_easy_multipart_post_body_set, 1);
3319
+ rb_define_method(cCurlEasy, "post_body=", ruby_curl_easy_post_body_set, 1);
3320
+ rb_define_method(cCurlEasy, "post_body", ruby_curl_easy_post_body_get, 0);
3321
+ rb_define_method(cCurlEasy, "put_data=", ruby_curl_easy_put_data_set, 1);
3322
+ rb_define_method(cCurlEasy, "ftp_commands=", ruby_curl_easy_ftp_commands_set, 1);
3323
+ rb_define_method(cCurlEasy, "ftp_commands", ruby_curl_easy_ftp_commands_get, 0);
3324
+
3325
+ rb_define_method(cCurlEasy, "local_port=", ruby_curl_easy_local_port_set, 1);
3326
+ rb_define_method(cCurlEasy, "local_port", ruby_curl_easy_local_port_get, 0);
3327
+ rb_define_method(cCurlEasy, "local_port_range=", ruby_curl_easy_local_port_range_set, 1);
3328
+ rb_define_method(cCurlEasy, "local_port_range", ruby_curl_easy_local_port_range_get, 0);
3329
+ rb_define_method(cCurlEasy, "proxy_port=", ruby_curl_easy_proxy_port_set, 1);
3330
+ rb_define_method(cCurlEasy, "proxy_port", ruby_curl_easy_proxy_port_get, 0);
3331
+ rb_define_method(cCurlEasy, "proxy_type=", ruby_curl_easy_proxy_type_set, 1);
3332
+ rb_define_method(cCurlEasy, "proxy_type", ruby_curl_easy_proxy_type_get, 0);
3333
+ rb_define_method(cCurlEasy, "http_auth_types=", ruby_curl_easy_http_auth_types_set, -1);
3334
+ rb_define_method(cCurlEasy, "http_auth_types", ruby_curl_easy_http_auth_types_get, 0);
3335
+ rb_define_method(cCurlEasy, "proxy_auth_types=", ruby_curl_easy_proxy_auth_types_set, 1);
3336
+ rb_define_method(cCurlEasy, "proxy_auth_types", ruby_curl_easy_proxy_auth_types_get, 0);
3337
+ rb_define_method(cCurlEasy, "max_redirects=", ruby_curl_easy_max_redirects_set, 1);
3338
+ rb_define_method(cCurlEasy, "max_redirects", ruby_curl_easy_max_redirects_get, 0);
3339
+ rb_define_method(cCurlEasy, "timeout=", ruby_curl_easy_timeout_set, 1);
3340
+ rb_define_method(cCurlEasy, "timeout", ruby_curl_easy_timeout_get, 0);
3341
+ rb_define_method(cCurlEasy, "connect_timeout=", ruby_curl_easy_connect_timeout_set, 1);
3342
+ rb_define_method(cCurlEasy, "connect_timeout", ruby_curl_easy_connect_timeout_get, 0);
3343
+ rb_define_method(cCurlEasy, "dns_cache_timeout=", ruby_curl_easy_dns_cache_timeout_set, 1);
3344
+ rb_define_method(cCurlEasy, "dns_cache_timeout", ruby_curl_easy_dns_cache_timeout_get, 0);
3345
+ rb_define_method(cCurlEasy, "ftp_response_timeout=", ruby_curl_easy_ftp_response_timeout_set, 1);
3346
+ rb_define_method(cCurlEasy, "ftp_response_timeout", ruby_curl_easy_ftp_response_timeout_get, 0);
3347
+ rb_define_method(cCurlEasy, "low_speed_limit=", ruby_curl_easy_low_speed_limit_set, 1);
3348
+ rb_define_method(cCurlEasy, "low_speed_limit", ruby_curl_easy_low_speed_limit_get, 0);
3349
+ rb_define_method(cCurlEasy, "low_speed_time=", ruby_curl_easy_low_speed_time_set, 1);
3350
+ rb_define_method(cCurlEasy, "low_speed_time", ruby_curl_easy_low_speed_time_get, 0);
3351
+ rb_define_method(cCurlEasy, "ssl_version=", ruby_curl_easy_ssl_version_set, 1);
3352
+ rb_define_method(cCurlEasy, "ssl_version", ruby_curl_easy_ssl_version_get, 0);
3353
+ rb_define_method(cCurlEasy, "use_ssl=", ruby_curl_easy_use_ssl_set, 1);
3354
+ rb_define_method(cCurlEasy, "use_ssl", ruby_curl_easy_use_ssl_get, 0);
3355
+ rb_define_method(cCurlEasy, "ftp_filemethod=", ruby_curl_easy_ftp_filemethod_set, 1);
3356
+ rb_define_method(cCurlEasy, "ftp_filemethod", ruby_curl_easy_ftp_filemethod_get, 0);
3357
+
3358
+ rb_define_method(cCurlEasy, "username=", ruby_curl_easy_username_set, 1);
3359
+ rb_define_method(cCurlEasy, "username", ruby_curl_easy_username_get, 0);
3360
+ rb_define_method(cCurlEasy, "password=", ruby_curl_easy_password_set, 1);
3361
+ rb_define_method(cCurlEasy, "password", ruby_curl_easy_password_get, 0);
3362
+
3363
+ rb_define_method(cCurlEasy, "proxy_tunnel=", ruby_curl_easy_proxy_tunnel_set, 1);
3364
+ rb_define_method(cCurlEasy, "proxy_tunnel?", ruby_curl_easy_proxy_tunnel_q, 0);
3365
+ rb_define_method(cCurlEasy, "fetch_file_time=", ruby_curl_easy_fetch_file_time_set, 1);
3366
+ rb_define_method(cCurlEasy, "fetch_file_time?", ruby_curl_easy_fetch_file_time_q, 0);
3367
+ rb_define_method(cCurlEasy, "ssl_verify_peer=", ruby_curl_easy_ssl_verify_peer_set, 1);
3368
+ rb_define_method(cCurlEasy, "ssl_verify_peer?", ruby_curl_easy_ssl_verify_peer_q, 0);
3369
+ rb_define_method(cCurlEasy, "ssl_verify_host_integer=", ruby_curl_easy_ssl_verify_host_set, 1);
3370
+ rb_define_method(cCurlEasy, "ssl_verify_host", ruby_curl_easy_ssl_verify_host_get, 0);
3371
+ rb_define_method(cCurlEasy, "header_in_body=", ruby_curl_easy_header_in_body_set, 1);
3372
+ rb_define_method(cCurlEasy, "header_in_body?", ruby_curl_easy_header_in_body_q, 0);
3373
+ rb_define_method(cCurlEasy, "use_netrc=", ruby_curl_easy_use_netrc_set, 1);
3374
+ rb_define_method(cCurlEasy, "use_netrc?", ruby_curl_easy_use_netrc_q, 0);
3375
+ rb_define_method(cCurlEasy, "follow_location?", ruby_curl_easy_follow_location_q, 0);
3376
+ rb_define_method(cCurlEasy, "autoreferer=", ruby_curl_easy_autoreferer_set, 1);
3377
+ rb_define_method(cCurlEasy, "unrestricted_auth=", ruby_curl_easy_unrestricted_auth_set, 1);
3378
+ rb_define_method(cCurlEasy, "unrestricted_auth?", ruby_curl_easy_unrestricted_auth_q, 0);
3379
+ rb_define_method(cCurlEasy, "verbose=", ruby_curl_easy_verbose_set, 1);
3380
+ rb_define_method(cCurlEasy, "verbose?", ruby_curl_easy_verbose_q, 0);
3381
+ rb_define_method(cCurlEasy, "multipart_form_post=", ruby_curl_easy_multipart_form_post_set, 1);
3382
+ rb_define_method(cCurlEasy, "multipart_form_post?", ruby_curl_easy_multipart_form_post_q, 0);
3383
+ rb_define_method(cCurlEasy, "enable_cookies=", ruby_curl_easy_enable_cookies_set, 1);
3384
+ rb_define_method(cCurlEasy, "enable_cookies?", ruby_curl_easy_enable_cookies_q, 0);
3385
+ rb_define_method(cCurlEasy, "ignore_content_length=", ruby_curl_easy_ignore_content_length_set, 1);
3386
+ rb_define_method(cCurlEasy, "ignore_content_length?", ruby_curl_easy_ignore_content_length_q, 0);
3387
+ rb_define_method(cCurlEasy, "resolve_mode", ruby_curl_easy_resolve_mode, 0);
3388
+ rb_define_method(cCurlEasy, "resolve_mode=", ruby_curl_easy_resolve_mode_set, 1);
3389
+
3390
+ rb_define_method(cCurlEasy, "on_body", ruby_curl_easy_on_body_set, -1);
3391
+ rb_define_method(cCurlEasy, "on_header", ruby_curl_easy_on_header_set, -1);
3392
+ rb_define_method(cCurlEasy, "on_progress", ruby_curl_easy_on_progress_set, -1);
3393
+ rb_define_method(cCurlEasy, "on_debug", ruby_curl_easy_on_debug_set, -1);
3394
+ rb_define_method(cCurlEasy, "on_success", ruby_curl_easy_on_success_set, -1);
3395
+ rb_define_method(cCurlEasy, "on_failure", ruby_curl_easy_on_failure_set, -1);
3396
+ rb_define_method(cCurlEasy, "on_missing", ruby_curl_easy_on_missing_set, -1);
3397
+ rb_define_method(cCurlEasy, "on_redirect", ruby_curl_easy_on_redirect_set, -1);
3398
+ rb_define_method(cCurlEasy, "on_complete", ruby_curl_easy_on_complete_set, -1);
3399
+
3400
+ rb_define_method(cCurlEasy, "http", ruby_curl_easy_perform_verb, 1);
3401
+ rb_define_method(cCurlEasy, "http_post", ruby_curl_easy_perform_post, -1);
3402
+ rb_define_method(cCurlEasy, "http_put", ruby_curl_easy_perform_put, 1);
3403
+
3404
+ /* Post-perform info methods */
3405
+ rb_define_method(cCurlEasy, "body_str", ruby_curl_easy_body_str_get, 0);
3406
+ rb_define_method(cCurlEasy, "header_str", ruby_curl_easy_header_str_get, 0);
3407
+
3408
+ rb_define_method(cCurlEasy, "last_effective_url", ruby_curl_easy_last_effective_url_get, 0);
3409
+ rb_define_method(cCurlEasy, "response_code", ruby_curl_easy_response_code_get, 0);
3410
+ #if defined(HAVE_CURLINFO_PRIMARY_IP)
3411
+ rb_define_method(cCurlEasy, "primary_ip", ruby_curl_easy_primary_ip_get, 0);
3412
+ #endif
3413
+ rb_define_method(cCurlEasy, "http_connect_code", ruby_curl_easy_http_connect_code_get, 0);
3414
+ rb_define_method(cCurlEasy, "file_time", ruby_curl_easy_file_time_get, 0);
3415
+ rb_define_method(cCurlEasy, "total_time", ruby_curl_easy_total_time_get, 0);
3416
+ rb_define_method(cCurlEasy, "name_lookup_time", ruby_curl_easy_name_lookup_time_get, 0);
3417
+ rb_define_method(cCurlEasy, "connect_time", ruby_curl_easy_connect_time_get, 0);
3418
+ rb_define_method(cCurlEasy, "pre_transfer_time", ruby_curl_easy_pre_transfer_time_get, 0);
3419
+ rb_define_method(cCurlEasy, "start_transfer_time", ruby_curl_easy_start_transfer_time_get, 0);
3420
+ rb_define_method(cCurlEasy, "redirect_time", ruby_curl_easy_redirect_time_get, 0);
3421
+ rb_define_method(cCurlEasy, "redirect_count", ruby_curl_easy_redirect_count_get, 0);
3422
+ rb_define_method(cCurlEasy, "redirect_url", ruby_curl_easy_redirect_url_get, 0);
3423
+ rb_define_method(cCurlEasy, "downloaded_bytes", ruby_curl_easy_downloaded_bytes_get, 0);
3424
+ rb_define_method(cCurlEasy, "uploaded_bytes", ruby_curl_easy_uploaded_bytes_get, 0);
3425
+ rb_define_method(cCurlEasy, "download_speed", ruby_curl_easy_download_speed_get, 0);
3426
+ rb_define_method(cCurlEasy, "upload_speed", ruby_curl_easy_upload_speed_get, 0);
3427
+ rb_define_method(cCurlEasy, "header_size", ruby_curl_easy_header_size_get, 0);
3428
+ rb_define_method(cCurlEasy, "request_size", ruby_curl_easy_request_size_get, 0);
3429
+ rb_define_method(cCurlEasy, "ssl_verify_result", ruby_curl_easy_ssl_verify_result_get, 0);
3430
+ rb_define_method(cCurlEasy, "downloaded_content_length", ruby_curl_easy_downloaded_content_length_get, 0);
3431
+ rb_define_method(cCurlEasy, "uploaded_content_length", ruby_curl_easy_uploaded_content_length_get, 0);
3432
+ rb_define_method(cCurlEasy, "content_type", ruby_curl_easy_content_type_get, 0);
3433
+ rb_define_method(cCurlEasy, "os_errno", ruby_curl_easy_os_errno_get, 0);
3434
+ rb_define_method(cCurlEasy, "num_connects", ruby_curl_easy_num_connects_get, 0);
3435
+ rb_define_method(cCurlEasy, "ftp_entry_path", ruby_curl_easy_ftp_entry_path_get, 0);
3436
+
3437
+ rb_define_method(cCurlEasy, "close", ruby_curl_easy_close, 0);
3438
+ rb_define_method(cCurlEasy, "reset", ruby_curl_easy_reset, 0);
3439
+
3440
+ /* Curl utils */
3441
+ rb_define_method(cCurlEasy, "escape", ruby_curl_easy_escape, 1);
3442
+ rb_define_method(cCurlEasy, "unescape", ruby_curl_easy_unescape, 1);
3443
+
3444
+ /* Runtime support */
3445
+ rb_define_method(cCurlEasy, "clone", ruby_curl_easy_clone, 0);
3446
+ rb_define_alias(cCurlEasy, "dup", "clone");
3447
+ rb_define_method(cCurlEasy, "inspect", ruby_curl_easy_inspect, 0);
3448
+
3449
+ rb_define_method(cCurlEasy, "multi", ruby_curl_easy_multi_get, 0);
3450
+ rb_define_method(cCurlEasy, "multi=", ruby_curl_easy_multi_set, 1);
3451
+ rb_define_method(cCurlEasy, "last_result", ruby_curl_easy_last_result, 0);
3452
+
3453
+ rb_define_method(cCurlEasy, "setopt", ruby_curl_easy_set_opt, 2);
3454
+ rb_define_method(cCurlEasy, "getinfo", ruby_curl_easy_get_opt, 1);
3455
+ }