+ CURLOPT_RESOLVE CURLOPT_DNS_SERVERS
[ocurl.git] / curl-helper.c
blob0b95ba9d2b27525b93838437f4fdfc992b3a2966
1 /***
2 *** curl-helper.c
3 ***
4 *** Copyright (c) 2003-2008, Lars Nilsson, <lars@quantumchamaeleon.com>
5 *** Copyright (c) 2009, ygrek, <ygrek@autistici.org>
6 ***/
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <curl/curl.h>
14 #include <caml/alloc.h>
15 #include <caml/memory.h>
16 #include <caml/mlvalues.h>
17 #include <caml/callback.h>
18 #include <caml/fail.h>
19 #include <caml/custom.h>
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #else
24 #warning "No config file given."
25 #endif
27 #if defined(_MSC_VER)
28 #ifdef interface
29 #undef interface
30 #endif
31 #endif
33 void leave_blocking_section(void);
34 void enter_blocking_section(void);
36 #define Val_none Val_int(0)
38 static __inline value
39 Val_some( value v )
41 CAMLparam1( v );
42 CAMLlocal1( some );
43 some = caml_alloc(1, 0);
44 Store_field( some, 0, v );
45 CAMLreturn( some );
48 static value Val_pair(value v1, value v2)
50 CAMLparam2(v1,v2);
51 CAMLlocal1(pair);
52 pair = caml_alloc_small(2,0);
53 Field(pair,0) = v1;
54 Field(pair,1) = v2;
55 CAMLreturn(pair);
58 static value Val_cons(value list, value v) { return Val_pair(v,list); }
60 typedef struct Connection Connection;
61 typedef struct ConnectionList ConnectionList;
63 #define Connection_val(v) ((Connection *)Field(v, 0))
65 enum OcamlValues
67 OcamlWriteCallback,
68 OcamlReadCallback,
69 OcamlErrorBuffer,
70 OcamlPostFields,
71 OcamlHTTPHeader,
72 OcamlHTTPPost,
73 OcamlQuote,
74 OcamlPostQuote,
75 OcamlHeaderCallback,
76 OcamlProgressCallback,
77 OcamlDebugCallback,
78 OcamlHTTP200Aliases,
79 OcamlIOCTLCallback,
80 OcamlSeekFunctionCallback,
81 OcamlOpenSocketFunctionCallback,
83 OcamlURL,
84 OcamlProxy,
85 OcamlUserPWD,
86 OcamlProxyUserPWD,
87 OcamlRange,
88 OcamlReferer,
89 OcamlUserAgent,
90 OcamlFTPPort,
91 OcamlCookie,
92 OcamlHTTPPostStrings,
93 OcamlSSLCert,
94 OcamlSSLCertType,
95 OcamlSSLCertPasswd,
96 OcamlSSLKey,
97 OcamlSSLKeyType,
98 OcamlSSLKeyPasswd,
99 OcamlSSLEngine,
100 OcamlCookieFile,
101 OcamlCustomRequest,
102 OcamlInterface,
103 OcamlCAInfo,
104 OcamlCAPath,
105 OcamlRandomFile,
106 OcamlEGDSocket,
107 OcamlCookieJar,
108 OcamlSSLCipherList,
109 OcamlPrivate,
110 OcamlNETRCFile,
111 OcamlFTPAccount,
112 OcamlCookieList,
113 OcamlFTPAlternativeToUser,
114 OcamlSSHPublicKeyFile,
115 OcamlSSHPrivateKeyFile,
116 OcamlSSHHostPublicKeyMD5,
117 OcamlCopyPostFields,
119 /* Not used, last for size */
120 OcamlValuesSize
123 struct Connection
125 CURL *connection;
126 Connection *next;
127 Connection *prev;
129 value ocamlValues;
131 char *url;
132 char *proxy;
133 char *userPwd;
134 char *proxyUserPwd;
135 char *range;
136 char *errorBuffer;
137 char *postFields;
138 int postFieldSize;
139 char *referer;
140 char *userAgent;
141 char *ftpPort;
142 char *cookie;
143 struct curl_slist *httpHeader;
144 struct curl_httppost *httpPostFirst;
145 struct curl_httppost *httpPostLast;
146 struct curl_slist *httpPostStrings;
147 struct curl_slist *resolve;
148 char *sslCert;
149 char *sslCertType;
150 char *sslCertPasswd;
151 char *sslKey;
152 char *sslKeyType;
153 char *sslKeyPasswd;
154 char *sslEngine;
155 struct curl_slist *quote;
156 struct curl_slist *postQuote;
157 char *cookieFile;
158 char *customRequest;
159 char *interface;
160 char *caInfo;
161 char *caPath;
162 char *randomFile;
163 char *egdSocket;
164 char *cookieJar;
165 char *sslCipherList;
166 char *private;
167 struct curl_slist *http200Aliases;
168 char *netrcFile;
169 char *ftpaccount;
170 char *cookielist;
171 char *ftpAlternativeToUser;
172 char *sshPublicKeyFile;
173 char *sshPrivateKeyFile;
174 char *sshHostPublicKeyMD5;
175 char *copyPostFields;
176 char *dns_servers;
179 struct ConnectionList
181 Connection *head;
182 Connection *tail;
185 static ConnectionList connectionList = {NULL, NULL};
187 typedef struct CURLErrorMapping CURLErrorMapping;
189 struct CURLErrorMapping
191 char *name;
192 CURLcode error;
195 CURLErrorMapping errorMap[] =
197 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
198 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL},
199 #else
200 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
201 #endif
202 #if HAVE_DECL_CURLE_FAILED_INIT
203 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT},
204 #else
205 {"CURLE_FAILED_INIT", -1},
206 #endif
207 #if HAVE_DECL_CURLE_URL_MALFORMAT
208 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT},
209 #else
210 {"CURLE_URL_MALFORMAT", -1},
211 #endif
212 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
213 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER},
214 #else
215 {"CURLE_URL_MALFORMAT_USER", -1},
216 #endif
217 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
218 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY},
219 #else
220 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
221 #endif
222 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
223 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST},
224 #else
225 {"CURLE_COULDNT_RESOLVE_HOST", -1},
226 #endif
227 #if HAVE_DECL_CURLE_COULDNT_CONNECT
228 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT},
229 #else
230 {"CURLE_COULDNT_CONNECT", -1},
231 #endif
232 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
233 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY},
234 #else
235 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
236 #endif
237 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
238 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED},
239 #else
240 {"CURLE_FTP_ACCESS_DENIED", -1},
241 #endif
242 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
243 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT},
244 #else
245 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
246 #endif
247 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
248 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY},
249 #else
250 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
251 #endif
252 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
253 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY},
254 #else
255 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
256 #endif
257 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
258 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY},
259 #else
260 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
261 #endif
262 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
263 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT},
264 #else
265 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
266 #endif
267 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
268 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST},
269 #else
270 {"CURLE_FTP_CANT_GET_HOST", -1},
271 #endif
272 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
273 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT},
274 #else
275 {"CURLE_FTP_CANT_RECONNECT", -1},
276 #endif
277 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
278 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY},
279 #else
280 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
281 #endif
282 #if HAVE_DECL_CURLE_PARTIAL_FILE
283 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE},
284 #else
285 {"CURLE_PARTIAL_FILE", -1},
286 #endif
287 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
288 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE},
289 #else
290 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
291 #endif
292 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
293 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR},
294 #else
295 {"CURLE_FTP_WRITE_ERROR", -1},
296 #endif
297 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
298 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR},
299 #else
300 {"CURLE_FTP_QUOTE_ERROR", -1},
301 #endif
302 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
303 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND},
304 #else
305 {"CURLE_HTTP_NOT_FOUND", -1},
306 #endif
307 #if HAVE_DECL_CURLE_WRITE_ERROR
308 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR},
309 #else
310 {"CURLE_WRITE_ERROR", -1},
311 #endif
312 #if HAVE_DECL_CURLE_MALFORMAT_USER
313 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER},
314 #else
315 {"CURLE_MALFORMAT_USER", -1},
316 #endif
317 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
318 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE},
319 #else
320 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
321 #endif
322 #if HAVE_DECL_CURLE_READ_ERROR
323 {"CURLE_READ_ERROR", CURLE_READ_ERROR},
324 #else
325 {"CURLE_READ_ERROR", -1},
326 #endif
327 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
328 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY},
329 #else
330 {"CURLE_OUT_OF_MEMORY", -1},
331 #endif
332 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
333 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED},
334 #else
335 {"CURLE_OPERATION_TIMEOUTED", -1},
336 #endif
337 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
338 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII},
339 #else
340 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
341 #endif
342 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
343 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED},
344 #else
345 {"CURLE_FTP_PORT_FAILED", -1},
346 #endif
347 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
348 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST},
349 #else
350 {"CURLE_FTP_COULDNT_USE_REST", -1},
351 #endif
352 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
353 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE},
354 #else
355 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
356 #endif
357 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
358 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR},
359 #else
360 {"CURLE_HTTP_RANGE_ERROR", -1},
361 #endif
362 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
363 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR},
364 #else
365 {"CURLE_HTTP_POST_ERROR", -1},
366 #endif
367 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
368 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR},
369 #else
370 {"CURLE_SSL_CONNECT_ERROR", -1},
371 #endif
372 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
373 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME},
374 #else
375 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
376 #endif
377 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
378 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE},
379 #else
380 {"CURLE_FILE_COULDNT_READ_FILE", -1},
381 #endif
382 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
383 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND},
384 #else
385 {"CURLE_LDAP_CANNOT_BIND", -1},
386 #endif
387 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
388 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED},
389 #else
390 {"CURLE_LDAP_SEARCH_FAILED", -1},
391 #endif
392 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
393 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND},
394 #else
395 {"CURLE_LIBRARY_NOT_FOUND", -1},
396 #endif
397 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
398 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND},
399 #else
400 {"CURLE_FUNCTION_NOT_FOUND", -1},
401 #endif
402 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
403 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK},
404 #else
405 {"CURLE_ABORTED_BY_CALLBACK", -1},
406 #endif
407 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
408 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT},
409 #else
410 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
411 #endif
412 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
413 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER},
414 #else
415 {"CURLE_BAD_CALLING_ORDER", -1},
416 #endif
417 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
418 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED},
419 #else
420 {"CURLE_HTTP_PORT_FAILED", -1},
421 #endif
422 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
423 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED},
424 #else
425 {"CURLE_BAD_PASSWORD_ENTERED", -1},
426 #endif
427 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
428 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS},
429 #else
430 {"CURLE_TOO_MANY_REDIRECTS", -1},
431 #endif
432 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
433 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION},
434 #else
435 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
436 #endif
437 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
438 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX},
439 #else
440 {"CURLE_TELNET_OPTION_SYNTAX", -1},
441 #endif
442 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
443 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE},
444 #else
445 {"CURLE_SSL_PEER_CERTIFICATE", -1},
446 #endif
447 #if HAVE_DECL_CURLE_GOT_NOTHING
448 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING},
449 #else
450 {"CURLE_GOT_NOTHING", -1},
451 #endif
452 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
453 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND},
454 #else
455 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
456 #endif
457 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
458 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED},
459 #else
460 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
461 #endif
462 #if HAVE_DECL_CURLE_SEND_ERROR
463 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR},
464 #else
465 {"CURLE_SEND_ERROR", -1},
466 #endif
467 #if HAVE_DECL_CURLE_RECV_ERROR
468 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR},
469 #else
470 {"CURLE_RECV_ERROR", -1},
471 #endif
472 #if HAVE_DECL_CURLE_SHARE_IN_USE
473 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE},
474 #else
475 {"CURLE_SHARE_IN_USE", -1},
476 #endif
477 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
478 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM},
479 #else
480 {"CURLE_SSL_CERTPROBLEN", -1},
481 #endif
482 #if HAVE_DECL_CURLE_SSL_CIPHER
483 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER},
484 #else
485 {"CURLE_SSL_CIPHER", -1},
486 #endif
487 #if HAVE_DECL_CURLE_SSL_CACERT
488 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT},
489 #else
490 {"CURLE_SSL_CACERT", -1},
491 #endif
492 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
493 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING},
494 #else
495 {"CURLE_BAD_CONTENT_ENCODING", -1},
496 #endif
497 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
498 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL},
499 #else
500 {"CURLE_LDAP_INVALID_URL", -1},
501 #endif
502 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
503 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED},
504 #else
505 {"CURLE_FILESIZE_EXCEEDED", -1},
506 #endif
507 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
508 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED},
509 #else
510 {"CURLE_FTP_SSL_FAILED", -1},
511 #endif
512 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
513 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND},
514 #else
515 {"CURLE_SEND_FAIL_REWIND", -1},
516 #endif
517 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
518 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED},
519 #else
520 {"CURLE_SSL_ENGINE_INITFAILED", -1},
521 #endif
522 #if HAVE_DECL_CURLE_LOGIN_DENIED
523 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED},
524 #else
525 {"CURLE_LOGIN_DENIED", -1},
526 #endif
527 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
528 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND},
529 #else
530 {"CURLE_TFTP_NOTFOUND", -1},
531 #endif
532 #if HAVE_DECL_CURLE_TFTP_PERM
533 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM},
534 #else
535 {"CURLE_TFTP_PERM", -1},
536 #endif
537 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
538 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL},
539 #else
540 {"CURLE_REMOTE_DISK_FULL", -1},
541 #endif
542 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
543 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL},
544 #else
545 {"CURLE_TFTP_ILLEGAL", -1},
546 #endif
547 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
548 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID},
549 #else
550 {"CURLE_TFTP_UNKNOWNID", -1},
551 #endif
552 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
553 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS},
554 #else
555 {"CURLE_REMOTE_FILE_EXISTS", -1},
556 #endif
557 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
558 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER},
559 #else
560 {"CURLE_TFTP_NOSUCHUSER", -1},
561 #endif
562 #if HAVE_DECL_CURLE_CONV_FAILED
563 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED},
564 #else
565 {"CURLE_CONV_FAILED", -1},
566 #endif
567 #if HAVE_DECL_CURLE_CONV_REQUIRED
568 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED},
569 #else
570 {"CURLE_CONV_REQUIRED", -1},
571 #endif
572 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
573 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE},
574 #else
575 {"CURLE_SSL_CACERT_BADFILE", -1},
576 #endif
577 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
578 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND},
579 #else
580 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
581 #endif
582 #if HAVE_DECL_CURLE_SSH
583 {"CURLE_SSH", CURLE_SSH},
584 #else
585 {"CURLE_SSH", -1},
586 #endif
587 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
588 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED},
589 #else
590 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
591 #endif
592 #if HAVE_DECL_CURLE_AGAIN
593 {"CURLE_AGAIN", CURLE_AGAIN},
594 #else
595 {"CURLE_AGAIN", -1},
596 #endif
597 {"CURLE_OK", CURLE_OK},
598 {NULL, 0}
601 typedef struct CURLOptionMapping CURLOptionMapping;
603 struct CURLOptionMapping
605 void (*optionHandler)(Connection *, value);
606 char *name;
607 CURLoption option;
610 CURLOptionMapping unimplementedOptionMap[] =
612 {NULL, "CURLOPT_STDERR", CURLOPT_STDERR},
613 {NULL, NULL, 0}
616 static void handleWriteFunction(Connection *, value);
617 static void handleReadFunction(Connection *, value);
618 static void handleInFileSize(Connection *, value);
619 static void handleURL(Connection *, value);
620 static void handleProxy(Connection *, value);
621 static void handleProxyPort(Connection *, value);
622 static void handleHTTPProxyTunnel(Connection *, value);
623 static void handleVerbose(Connection *, value);
624 static void handleHeader(Connection *, value);
625 static void handleNoProgress(Connection *, value);
626 static void handleNoSignal(Connection *, value);
627 static void handleNoBody(Connection *, value);
628 static void handleFailOnError(Connection *, value);
629 static void handleUpload(Connection *, value);
630 static void handlePost(Connection *, value);
631 static void handleFTPListOnly(Connection *, value);
632 static void handleFTPAppend(Connection *, value);
633 static void handleNETRC(Connection *, value);
634 static void handleEncoding(Connection *, value);
635 static void handleFollowLocation(Connection *, value);
636 static void handleTransferText(Connection *, value);
637 static void handlePut(Connection *, value);
638 static void handleUserPwd(Connection *, value);
639 static void handleProxyUserPwd(Connection *, value);
640 static void handleRange(Connection *, value);
641 static void handleErrorBuffer(Connection *, value);
642 static void handleTimeout(Connection *, value);
643 static void handlePostFields(Connection *, value);
644 static void handlePostFieldSize(Connection *, value);
645 static void handleReferer(Connection *, value);
646 static void handleUserAgent(Connection *, value);
647 static void handleFTPPort(Connection *, value);
648 static void handleLowSpeedLimit(Connection *, value);
649 static void handleLowSpeedTime(Connection *, value);
650 static void handleResumeFrom(Connection *, value);
651 static void handleCookie(Connection *, value);
652 static void handleHTTPHeader(Connection *, value);
653 static void handleHTTPPost(Connection *, value);
654 static void handleSSLCert(Connection *, value);
655 static void handleSSLCertType(Connection *, value);
656 static void handleSSLCertPasswd(Connection *, value);
657 static void handleSSLKey(Connection *, value);
658 static void handleSSLKeyType(Connection *, value);
659 static void handleSSLKeyPasswd(Connection *, value);
660 static void handleSSLEngine(Connection *, value);
661 static void handleSSLEngineDefault(Connection *, value);
662 static void handleCRLF(Connection *, value);
663 static void handleQuote(Connection *, value);
664 static void handlePostQuote(Connection *, value);
665 static void handleHeaderFunction(Connection *, value);
666 static void handleCookieFile(Connection *, value);
667 static void handleSSLVersion(Connection *, value);
668 static void handleTimeCondition(Connection *, value);
669 static void handleTimeValue(Connection *, value);
670 static void handleCustomRequest(Connection *, value);
671 static void handleInterface(Connection *, value);
672 static void handleKRB4Level(Connection *, value);
673 static void handleProgressFunction(Connection *, value);
674 static void handleSSLVerifyPeer(Connection *, value);
675 static void handleCAInfo(Connection *, value);
676 static void handleCAPath(Connection *, value);
677 static void handleFileTime(Connection *, value);
678 static void handleMaxRedirs(Connection *, value);
679 static void handleMaxConnects(Connection *, value);
680 static void handleClosePolicy(Connection *, value);
681 static void handleFreshConnect(Connection *, value);
682 static void handleForbidReuse(Connection *, value);
683 static void handleRandomFile(Connection *, value);
684 static void handleEGDSocket(Connection *, value);
685 static void handleConnectTimeout(Connection *, value);
686 static void handleHTTPGet(Connection *, value);
687 static void handleSSLVerifyHost(Connection *, value);
688 static void handleCookieJar(Connection *, value);
689 static void handleSSLCipherList(Connection *, value);
690 static void handleHTTPVersion(Connection *, value);
691 static void handleFTPUseEPSV(Connection *, value);
692 static void handleDNSCacheTimeout(Connection *, value);
693 static void handleDNSUseGlobalCache(Connection *, value);
694 static void handleDebugFunction(Connection *, value);
695 static void handlePrivate(Connection *, value);
696 static void handleHTTP200Aliases(Connection *, value);
697 static void handleUnrestrictedAuth(Connection *, value);
698 static void handleFTPUseEPRT(Connection *, value);
699 static void handleHTTPAuth(Connection *, value);
700 static void handleFTPCreateMissingDirs(Connection *, value);
701 static void handleProxyAuth(Connection *, value);
702 static void handleFTPResponseTimeout(Connection *, value);
703 static void handleIPResolve(Connection *, value);
704 static void handleMaxFileSize(Connection *, value);
705 static void handleInFileSizeLarge(Connection *, value);
706 static void handleResumeFromLarge(Connection *, value);
707 static void handleMaxFileSizeLarge(Connection *, value);
708 static void handleNETRCFile(Connection *, value);
709 static void handleFTPSSL(Connection *, value);
710 static void handlePostFieldSizeLarge(Connection *, value);
711 static void handleTCPNoDelay(Connection *, value);
712 static void handleFTPSSLAuth(Connection *, value);
713 static void handleIOCTLFunction(Connection *, value);
714 static void handleFTPAccount(Connection *, value);
715 static void handleCookieList(Connection *, value);
716 static void handleIgnoreContentLength(Connection *, value);
717 static void handleFTPSkipPASVIP(Connection *, value);
718 static void handleFTPFileMethod(Connection *, value);
719 static void handleLocalPort(Connection *, value);
720 static void handleLocalPortRange(Connection *, value);
721 static void handleConnectOnly(Connection *, value);
722 static void handleMaxSendSpeedLarge(Connection *, value);
723 static void handleMaxRecvSpeedLarge(Connection *, value);
724 static void handleFTPAlternativeToUser(Connection *, value);
725 static void handleSSLSessionIdCache(Connection *, value);
726 static void handleSSHAuthTypes(Connection *, value);
727 static void handleSSHPublicKeyFile(Connection *, value);
728 static void handleSSHPrivateKeyFile(Connection *, value);
729 static void handleFTPSSLCCC(Connection *, value);
730 static void handleTimeoutMS(Connection *, value);
731 static void handleConnectTimeoutMS(Connection *, value);
732 static void handleHTTPTransferDecoding(Connection *, value);
733 static void handleHTTPContentDecoding(Connection *, value);
734 static void handleNewFilePerms(Connection *, value);
735 static void handleNewDirectoryPerms(Connection *, value);
736 static void handlePost301(Connection *, value);
737 static void handleSSHHostPublicKeyMD5(Connection *, value);
738 static void handleCopyPostFields(Connection *, value);
739 static void handleProxyTransferMode(Connection *, value);
740 static void handleSeekFunction(Connection *, value);
741 static void handleAutoReferer(Connection *, value);
742 static void handleOpenSocketFunction(Connection *, value);
743 static void handleProxyType(Connection *, value);
744 static void handleProtocols(Connection *, value);
745 static void handleRedirProtocols(Connection *, value);
746 static void handleResolve(Connection *, value);
747 static void handleDnsServers(Connection *, value);
749 CURLOptionMapping implementedOptionMap[] =
751 {handleWriteFunction, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION},
752 {handleReadFunction, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION},
753 {handleInFileSize, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE},
754 {handleURL, "CURLOPT_URL", CURLOPT_URL},
755 {handleProxy, "CURLOPT_PROXY", CURLOPT_PROXY},
756 {handleProxyPort, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT},
757 {handleHTTPProxyTunnel, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL},
758 {handleVerbose, "CURLOPT_VERBOSE", CURLOPT_VERBOSE},
759 {handleHeader, "CURLOPT_HEADER", CURLOPT_HEADER},
760 {handleNoProgress, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS},
761 #if HAVE_DECL_CURLOPT_NOSIGNAL
762 {handleNoSignal, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL},
763 #else
764 {handleNoSignal, "CURLOPT_NOSIGNAL", 0},
765 #endif
766 {handleNoBody, "CURLOPT_NOBODY", CURLOPT_NOBODY},
767 {handleFailOnError, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR},
768 {handleUpload, "CURLOPT_UPLOAD", CURLOPT_UPLOAD},
769 {handlePost, "CURLOPT_POST", CURLOPT_POST},
770 {handleFTPListOnly, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY},
771 {handleFTPAppend, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND},
772 {handleNETRC, "CURLOPT_NETRC", CURLOPT_NETRC},
773 #if HAVE_DECL_CURLOPT_ENCODING
774 {handleEncoding, "CURLOPT_ENCODING", CURLOPT_ENCODING},
775 #else
776 {handleEncoding, "CURLOPT_ENCODING", 0},
777 #endif
778 {handleFollowLocation, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION},
779 {handleTransferText, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT},
780 {handlePut, "CURLOPT_PUT", CURLOPT_PUT},
781 {handleUserPwd, "CURLOPT_USERPWD", CURLOPT_USERPWD},
782 {handleProxyUserPwd, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD},
783 {handleRange, "CURLOPT_RANGE", CURLOPT_RANGE},
784 {handleErrorBuffer, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER},
785 {handleTimeout, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT},
786 {handlePostFields, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS},
787 {handlePostFieldSize, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE},
788 {handleReferer, "CURLOPT_REFERER", CURLOPT_REFERER},
789 {handleUserAgent, "CURLOPT_USERAGENT", CURLOPT_USERAGENT},
790 {handleFTPPort, "CURLOPT_FTPPORT", CURLOPT_FTPPORT},
791 {handleLowSpeedLimit, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT},
792 {handleLowSpeedTime, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME},
793 {handleResumeFrom, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM},
794 {handleCookie, "CURLOPT_COOKIE", CURLOPT_COOKIE},
795 {handleHTTPHeader, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER},
796 {handleHTTPPost, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST},
797 {handleSSLCert, "CURLOPT_SSLCERT", CURLOPT_SSLCERT},
798 {handleSSLCertType, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE},
799 {handleSSLCertPasswd, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD},
800 {handleSSLKey, "CURLOPT_SSLKEY", CURLOPT_SSLKEY},
801 {handleSSLKeyType, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE},
802 {handleSSLKeyPasswd, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD},
803 {handleSSLEngine, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE},
804 {handleSSLEngineDefault, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT},
805 {handleCRLF, "CURLOPT_CRLF", CURLOPT_CRLF},
806 {handleQuote, "CURLOPT_QUOTE", CURLOPT_QUOTE},
807 {handlePostQuote, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE},
808 {handleHeaderFunction, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION},
809 {handleCookieFile, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE},
810 {handleSSLVersion, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION},
811 {handleTimeCondition, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION},
812 {handleTimeValue, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE},
813 {handleCustomRequest, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST},
814 {handleInterface, "CURLOPT_INTERFACE", CURLOPT_INTERFACE},
815 {handleKRB4Level, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL},
816 {handleProgressFunction, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION},
817 {handleSSLVerifyPeer, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER},
818 {handleCAInfo, "CURLOPT_CAINFO", CURLOPT_CAINFO},
819 {handleCAPath, "CURLOPT_CAPATH", CURLOPT_CAPATH},
820 {handleFileTime, "CURLOPT_FILETIME", CURLOPT_FILETIME},
821 {handleMaxRedirs, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS},
822 {handleMaxConnects, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS},
823 {handleClosePolicy, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY},
824 {handleFreshConnect, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT},
825 {handleForbidReuse, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE},
826 {handleRandomFile, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE},
827 {handleEGDSocket, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET},
828 {handleConnectTimeout, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT},
829 {handleHTTPGet, "CURLOPT_HTTPGET", CURLOPT_HTTPGET},
830 {handleSSLVerifyHost, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST},
831 {handleCookieJar, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR},
832 {handleSSLCipherList, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST},
833 {handleHTTPVersion, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION},
834 {handleFTPUseEPSV, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV},
835 {handleDNSCacheTimeout, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT},
836 {handleDNSUseGlobalCache, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE},
837 {handleDebugFunction, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION},
838 #if HAVE_DECL_CURLOPT_PRIVATE
839 {handlePrivate, "CURLOPT_PRIVATE", CURLOPT_PRIVATE},
840 #else
841 {handlePrivate, "CURLOPT_PRIVATE", 0},
842 #endif
843 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
844 {handleHTTP200Aliases, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES},
845 #else
846 {handleHTTP200Aliases, "CURLOPT_HTTP200ALIASES", 0},
847 #endif
848 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
849 {handleUnrestrictedAuth, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH},
850 #else
851 {handleUnrestrictedAuth, "CURLOPT_UNRESTRICTED_AUTH", 0},
852 #endif
853 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
854 {handleFTPUseEPRT, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT},
855 #else
856 {handleFTPUseEPRT, "CURLOPT_FTP_USE_EPRT", 0},
857 #endif
858 #if HAVE_DECL_CURLOPT_HTTPAUTH
859 {handleHTTPAuth, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH},
860 #else
861 {handleHTTPAuth, "CURLOPT_HTTPAUTH", 0},
862 #endif
863 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
864 {handleFTPCreateMissingDirs, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS},
865 #else
866 {handleFTPCreateMissingDirs, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
867 #endif
868 #if HAVE_DECL_CURLOPT_PROXYAUTH
869 {handleProxyAuth, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH},
870 #else
871 {handleProxyAuth, "CURLOPT_PROXYAUTH", 0},
872 #endif
873 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
874 {handleFTPResponseTimeout, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT},
875 #else
876 {handleFTPResponseTimeout, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
877 #endif
878 #if HAVE_DECL_CURLOPT_IPRESOLVE
879 {handleIPResolve, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE},
880 #else
881 {handleIPResolve, "CURLOPT_IPRESOLVE", 0},
882 #endif
883 #if HAVE_DECL_CURLOPT_MAXFILESIZE
884 {handleMaxFileSize, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE},
885 #else
886 {handleMaxFileSize, "CURLOPT_MAXFILESIZE", 0},
887 #endif
888 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
889 {handleInFileSizeLarge, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE},
890 #else
891 {handleInFileSizeLarge, "CURLOPT_INFILESIZE_LARGE", 0},
892 #endif
893 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
894 {handleResumeFromLarge, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE},
895 #else
896 {handleResumeFromLarge, "CURLOPT_RESUME_FROM_LARGE", 0},
897 #endif
898 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
899 {handleMaxFileSizeLarge, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE},
900 #else
901 {handleMaxFileSizeLarge, "CURLOPT_MAXFILESIZE_LARGE", 0},
902 #endif
903 #if HAVE_DECL_CURLOPT_NETRC_FILE
904 {handleNETRCFile, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE},
905 #else
906 {handleNETRCFile, "CURLOPT_NETRC_FILE", 0},
907 #endif
908 #if HAVE_DECL_CURLOPT_FTP_SSL
909 {handleFTPSSL, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL},
910 #else
911 {handleFTPSSL, "CURLOPT_FTP_SSL", 0},
912 #endif
913 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
914 {handlePostFieldSizeLarge, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE},
915 #else
916 {handlePostFieldSizeLarge, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
917 #endif
918 #if HAVE_DECL_CURLOPT_TCP_NODELAY
919 {handleTCPNoDelay, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY},
920 #else
921 {handleTCPNoDelay, "CURLOPT_TCP_NODELAY", 0},
922 #endif
923 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
924 {handleFTPSSLAuth, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH},
925 #else
926 {handleFTPSSLAuth, "CURLOPT_FTPSSLAUTH", 0},
927 #endif
928 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
929 {handleIOCTLFunction, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION},
930 #else
931 {handleIOCTLFunction, "CURLOPT_IOCTLFUNCTION", 0},
932 #endif
933 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
934 {handleFTPAccount, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT},
935 #else
936 {handleFTPAccount, "CURLOPT_FTP_ACCOUNT", 0},
937 #endif
938 #if HAVE_DECL_CURLOPT_COOKIELIST
939 {handleCookieList, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST},
940 #else
941 {handleCookieList, "CURLOPT_COOKIELIST", 0},
942 #endif
943 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
944 {handleIgnoreContentLength, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH},
945 #else
946 {handleIgnoreContentLength, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
947 #endif
948 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
949 {handleFTPSkipPASVIP, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP},
950 #else
951 {handleFTPSkipPASVIP, "CURLOPT_FTP_SKIP_PASV_IP", 0},
952 #endif
953 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
954 {handleFTPFileMethod, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD},
955 #else
956 {handleFTPFileMethod, "CURLOPT_FTP_FILEMETHOD", 0},
957 #endif
958 #if HAVE_DECL_CURLOPT_LOCALPORT
959 {handleLocalPort, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT},
960 #else
961 {handleLocalPort, "CURLOPT_LOCALPORT", 0},
962 #endif
963 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
964 {handleLocalPortRange, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE},
965 #else
966 {handleLocalPortRange, "CURLOPT_LOCALPORTRANGE", 0},
967 #endif
968 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
969 {handleConnectOnly, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY},
970 #else
971 {handleConnectOnly, "CURLOPT_CONNECT_ONLY", 0},
972 #endif
973 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
974 {handleMaxSendSpeedLarge, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE},
975 #else
976 {handleMaxSendSpeedLarge, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
977 #endif
978 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
979 {handleMaxRecvSpeedLarge, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE},
980 #else
981 {handleMaxRecvSpeedLarge, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
982 #endif
983 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
984 {handleFTPAlternativeToUser, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER},
985 #else
986 {handleFTPAlternativeToUser, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
987 #endif
988 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
989 {handleSSLSessionIdCache, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE},
990 #else
991 {handleSSLSessionIdCache, "CURLOPT_SSL_SESSIONID_CACHE", 0},
992 #endif
993 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
994 {handleSSHAuthTypes, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES},
995 #else
996 {handleSSHAuthTypes, "CURLOPT_SSH_AUTH_TYPES", 0},
997 #endif
998 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
999 {handleSSHPublicKeyFile, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE},
1000 #else
1001 {handleSSHPublicKeyFile, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
1002 #endif
1003 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
1004 {handleSSHPrivateKeyFile, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE},
1005 #else
1006 {handleSSHPrivateKeyFile, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
1007 #endif
1008 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
1009 {handleFTPSSLCCC, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC},
1010 #else
1011 {handleFTPSSLCCC, "CURLOPT_FTP_SSL_CCC", 0},
1012 #endif
1013 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
1014 {handleTimeoutMS, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS},
1015 #else
1016 {handleTimeoutMS, "CURLOPT_TIMEOUT_MS", 0},
1017 #endif
1018 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
1019 {handleConnectTimeoutMS, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS},
1020 #else
1021 {handleConnectTimeoutMS, "CURLOPT_CONNECTTIMEOUT_MS", 0},
1022 #endif
1023 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
1024 {handleHTTPTransferDecoding, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING},
1025 #else
1026 {handleHTTPTransferDecoding, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
1027 #endif
1028 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1029 {handleHTTPContentDecoding, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING},
1030 #else
1031 {handleHTTPContentDecoding, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1032 #endif
1033 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1034 {handleNewFilePerms, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS},
1035 #else
1036 {handleNewFilePerms, "CURLOPT_NEW_FILE_PERMS", 0},
1037 #endif
1038 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1039 {handleNewDirectoryPerms, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS},
1040 #else
1041 {handleNewDirectoryPerms, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1042 #endif
1043 #if HAVE_DECL_CURLOPT_POST301
1044 {handlePost301, "CURLOPT_POST301", CURLOPT_POST301},
1045 #else
1046 {handlePost301, "CURLOPT_POST301", 0},
1047 #endif
1048 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1049 {handleSSHHostPublicKeyMD5, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5},
1050 #else
1051 {handleSSHHostPublicKeyMD5, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1052 #endif
1053 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1054 {handleCopyPostFields, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS},
1055 #else
1056 {handleCopyPostFields, "CURLOPT_COPYPOSTFIELDS", 0},
1057 #endif
1058 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1059 {handleProxyTransferMode, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE},
1060 #else
1061 {handleProxyTransferMode, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1062 #endif
1063 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1064 {handleSeekFunction, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION},
1065 #else
1066 {handleSeekFunction, "CURLOPT_SEEKFUNCTION", 0},
1067 #endif
1068 #if HAVE_DECL_CURLOPT_AUTOREFERER
1069 {handleAutoReferer, "CURLOPT_AUTOREFERER", CURLOPT_AUTOREFERER},
1070 #else
1071 {handleAutoReferer, "CURLOPT_AUTOREFERER", 0},
1072 #endif
1073 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
1074 {handleOpenSocketFunction, "CURLOPT_OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION},
1075 #else
1076 {handleOpenSocketFunction, "CURLOPT_OPENSOCKETFUNCTION", 0},
1077 #endif
1078 #if HAVE_DECL_CURLOPT_PROXYTYPE
1079 {handleProxyType, "CURLOPT_PROXYTYPE", CURLOPT_PROXYTYPE},
1080 #else
1081 {handleProxyType, "CURLOPT_PROXYTYPE", 0},
1082 #endif
1083 #if HAVE_DECL_CURLOPT_PROTOCOLS
1084 {handleProtocols, "CURLOPT_PROTOCOLS", CURLOPT_PROTOCOLS},
1085 #else
1086 {handleProtocols, "CURLOPT_PROTOCOLS", 0},
1087 #endif
1088 #if HAVE_DECL_CURLOPT_REDIR_PROTOCOLS
1089 {handleRedirProtocols, "CURLOPT_REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS},
1090 #else
1091 {handleRedirProtocols, "CURLOPT_REDIR_PROTOCOLS", 0},
1092 #endif
1093 #if HAVE_DECL_CURLOPT_RESOLVE
1094 {handleResolve, "CURLOPT_RESOLVE", CURLOPT_RESOLVE},
1095 #else
1096 {handleResolve, "CURLOPT_RESOLVE", 0},
1097 #endif
1098 #if HAVE_DECL_CURLOPT_DNS_SERVERS
1099 {handleDnsServers, "CURLOPT_DNS_SERVERS", CURLOPT_DNS_SERVERS},
1100 #else
1101 {handleDnsServers, "CURLOPT_DNS_SERVERS", 0},
1102 #endif
1105 static char *findOption(CURLOptionMapping optionMap[],
1106 CURLoption option)
1108 return optionMap[option].name;
1111 static void free_curl_slist(struct curl_slist *slist)
1113 if (NULL == slist)
1114 return;
1116 curl_slist_free_all(slist);
1119 static void raiseError(Connection *conn, CURLcode code)
1121 CAMLparam0();
1122 CAMLlocal1(exceptionData);
1123 value *exception;
1124 char *errorString = "Unknown Error";
1125 int i;
1127 for (i = 0; errorMap[i].name != NULL; i++)
1129 if (errorMap[i].error == code)
1131 errorString = errorMap[i].name;
1132 break;
1136 exceptionData = caml_alloc(3, 0);
1138 Store_field(exceptionData, 0, Val_int(code));
1139 Store_field(exceptionData, 1, Val_int(code));
1140 Store_field(exceptionData, 2, copy_string(errorString));
1142 if (conn != NULL && conn->errorBuffer != NULL)
1144 Store_field(Field(conn->ocamlValues, OcamlErrorBuffer), 0,
1145 copy_string(conn->errorBuffer));
1148 exception = caml_named_value("CurlException");
1150 if (exception == NULL)
1151 caml_failwith("CurlException not registered");
1153 raise_with_arg(*exception, exceptionData);
1155 CAMLreturn0;
1158 static void resetOcamlValues(Connection* connection)
1160 int i;
1162 for (i = 0; i < OcamlValuesSize; i++)
1163 Store_field(connection->ocamlValues, i, Val_unit);
1166 static Connection *newConnection(void)
1168 Connection *connection;
1170 connection = (Connection *)malloc(sizeof(Connection));
1172 enter_blocking_section();
1173 connection->connection = curl_easy_init();
1174 leave_blocking_section();
1176 connection->next = NULL;
1177 connection->prev = NULL;
1179 if (connectionList.tail == NULL)
1181 connectionList.tail = connection;
1182 connectionList.head = connection;
1184 else
1186 connection->prev = connectionList.head;
1187 connectionList.head->next = connection;
1188 connectionList.head = connection;
1191 connection->ocamlValues = alloc(OcamlValuesSize, 0);
1192 resetOcamlValues(connection);
1193 register_global_root(&connection->ocamlValues);
1195 connection->url = NULL;
1196 connection->proxy = NULL;
1197 connection->userPwd = NULL;
1198 connection->proxyUserPwd = NULL;
1199 connection->range = NULL;
1200 connection->errorBuffer = NULL;
1201 connection->postFields = NULL;
1202 connection->postFieldSize = -1;
1203 connection->referer = NULL;
1204 connection->userAgent = NULL;
1205 connection->ftpPort = NULL;
1206 connection->cookie = NULL;
1207 connection->httpHeader = NULL;
1208 connection->httpPostFirst = NULL;
1209 connection->httpPostLast = NULL;
1210 connection->httpPostStrings = NULL;
1211 connection->sslCert = NULL;
1212 connection->sslCertType = NULL;
1213 connection->sslCertPasswd = NULL;
1214 connection->sslKey = NULL;
1215 connection->sslKeyType = NULL;
1216 connection->sslKeyPasswd = NULL;
1217 connection->sslEngine = NULL;
1218 connection->quote = NULL;
1219 connection->postQuote = NULL;
1220 connection->cookieFile = NULL;
1221 connection->customRequest = NULL;
1222 connection->interface = NULL;
1223 connection->caInfo = NULL;
1224 connection->caPath = NULL;
1225 connection->randomFile = NULL;
1226 connection->egdSocket = NULL;
1227 connection->cookieJar = NULL;
1228 connection->sslCipherList = NULL;
1229 connection->private = NULL;
1230 connection->http200Aliases = NULL;
1231 connection->netrcFile = NULL;
1232 connection->ftpaccount = NULL;
1233 connection->cookielist = NULL;
1234 connection->ftpAlternativeToUser = NULL;
1235 connection->sshPublicKeyFile = NULL;
1236 connection->sshPrivateKeyFile = NULL;
1237 connection->copyPostFields = NULL;
1238 connection->resolve = NULL;
1239 connection->dns_servers = NULL;
1241 return connection;
1244 static Connection *duplicateConnection(Connection *original)
1246 Connection *connection;
1248 connection = (Connection *)malloc(sizeof(Connection));
1250 enter_blocking_section();
1251 connection->connection = curl_easy_duphandle(original->connection);
1252 leave_blocking_section();
1254 connection->next = NULL;
1255 connection->prev = NULL;
1257 if (connectionList.tail == NULL)
1259 connectionList.tail = connection;
1260 connectionList.head = connection;
1262 else
1264 connection->prev = connectionList.head;
1265 connectionList.head->next = connection;
1266 connectionList.head = connection;
1269 connection->ocamlValues = alloc(OcamlValuesSize, 0);
1270 resetOcamlValues(connection);
1271 register_global_root(&connection->ocamlValues);
1273 Store_field(connection->ocamlValues, OcamlWriteCallback,
1274 Field(original->ocamlValues, OcamlWriteCallback));
1275 Store_field(connection->ocamlValues, OcamlReadCallback,
1276 Field(original->ocamlValues, OcamlReadCallback));
1277 Store_field(connection->ocamlValues, OcamlErrorBuffer,
1278 Field(original->ocamlValues, OcamlErrorBuffer));
1279 Store_field(connection->ocamlValues, OcamlPostFields,
1280 Field(original->ocamlValues, OcamlPostFields));
1281 Store_field(connection->ocamlValues, OcamlHTTPHeader,
1282 Field(original->ocamlValues, OcamlHTTPHeader));
1283 Store_field(connection->ocamlValues, OcamlQuote,
1284 Field(original->ocamlValues, OcamlQuote));
1285 Store_field(connection->ocamlValues, OcamlPostQuote,
1286 Field(original->ocamlValues, OcamlPostQuote));
1287 Store_field(connection->ocamlValues, OcamlHeaderCallback,
1288 Field(original->ocamlValues, OcamlHeaderCallback));
1289 Store_field(connection->ocamlValues, OcamlProgressCallback,
1290 Field(original->ocamlValues, OcamlProgressCallback));
1291 Store_field(connection->ocamlValues, OcamlDebugCallback,
1292 Field(original->ocamlValues, OcamlDebugCallback));
1293 Store_field(connection->ocamlValues, OcamlHTTP200Aliases,
1294 Field(original->ocamlValues, OcamlHTTP200Aliases));
1295 Store_field(connection->ocamlValues, OcamlIOCTLCallback,
1296 Field(original->ocamlValues, OcamlIOCTLCallback));
1297 Store_field(connection->ocamlValues, OcamlSeekFunctionCallback,
1298 Field(original->ocamlValues, OcamlSeekFunctionCallback));
1300 connection->url = NULL;
1301 connection->proxy = NULL;
1302 connection->userPwd = NULL;
1303 connection->proxyUserPwd = NULL;
1304 connection->range = NULL;
1305 connection->errorBuffer = NULL;
1306 connection->postFields = NULL;
1307 connection->postFieldSize = -1;
1308 connection->referer = NULL;
1309 connection->userAgent = NULL;
1310 connection->ftpPort = NULL;
1311 connection->cookie = NULL;
1312 connection->httpHeader = NULL;
1313 connection->httpPostFirst = NULL;
1314 connection->httpPostLast = NULL;
1315 connection->httpPostStrings = NULL;
1316 connection->sslCert = NULL;
1317 connection->sslCertType = NULL;
1318 connection->sslCertPasswd = NULL;
1319 connection->sslKey = NULL;
1320 connection->sslKeyType = NULL;
1321 connection->sslKeyPasswd = NULL;
1322 connection->sslEngine = NULL;
1323 connection->quote = NULL;
1324 connection->postQuote = NULL;
1325 connection->cookieFile = NULL;
1326 connection->customRequest = NULL;
1327 connection->interface = NULL;
1328 connection->caInfo = NULL;
1329 connection->caPath = NULL;
1330 connection->randomFile = NULL;
1331 connection->egdSocket = NULL;
1332 connection->cookieJar = NULL;
1333 connection->sslCipherList = NULL;
1334 connection->private = NULL;
1335 connection->http200Aliases = NULL;
1336 connection->netrcFile = NULL;
1337 connection->ftpaccount = NULL;
1338 connection->cookielist = NULL;
1339 connection->sshPublicKeyFile = NULL;
1340 connection->sshPrivateKeyFile = NULL;
1341 connection->copyPostFields = NULL;
1342 connection->resolve = NULL;
1343 connection->dns_servers = NULL;
1345 if (Field(original->ocamlValues, OcamlURL) != Val_unit)
1346 handleURL(connection, Field(original->ocamlValues,
1347 OcamlURL));
1348 if (Field(original->ocamlValues, OcamlProxy) != Val_unit)
1349 handleProxy(connection, Field(original->ocamlValues,
1350 OcamlProxy));
1351 if (Field(original->ocamlValues, OcamlUserPWD) != Val_unit)
1352 handleUserPwd(connection, Field(original->ocamlValues,
1353 OcamlUserPWD));
1354 if (Field(original->ocamlValues, OcamlProxyUserPWD) != Val_unit)
1355 handleProxyUserPwd(connection, Field(original->ocamlValues,
1356 OcamlProxyUserPWD));
1357 if (Field(original->ocamlValues, OcamlRange) != Val_unit)
1358 handleRange(connection, Field(original->ocamlValues,
1359 OcamlRange));
1360 if (Field(original->ocamlValues, OcamlErrorBuffer) != Val_unit)
1361 handleErrorBuffer(connection, Field(original->ocamlValues,
1362 OcamlErrorBuffer));
1363 if (Field(original->ocamlValues, OcamlPostFields) != Val_unit)
1364 handlePostFields(connection, Field(original->ocamlValues,
1365 OcamlPostFields));
1366 if (Field(original->ocamlValues, OcamlReferer) != Val_unit)
1367 handleReferer(connection, Field(original->ocamlValues,
1368 OcamlReferer));
1369 if (Field(original->ocamlValues, OcamlUserAgent) != Val_unit)
1370 handleUserAgent(connection, Field(original->ocamlValues,
1371 OcamlUserAgent));
1372 if (Field(original->ocamlValues, OcamlFTPPort) != Val_unit)
1373 handleFTPPort(connection, Field(original->ocamlValues,
1374 OcamlFTPPort));
1375 if (Field(original->ocamlValues, OcamlCookie) != Val_unit)
1376 handleCookie(connection, Field(original->ocamlValues,
1377 OcamlCookie));
1378 if (Field(original->ocamlValues, OcamlHTTPHeader) != Val_unit)
1379 handleHTTPHeader(connection, Field(original->ocamlValues,
1380 OcamlHTTPHeader));
1381 if (Field(original->ocamlValues, OcamlHTTPPost) != Val_unit)
1382 handleHTTPPost(connection, Field(original->ocamlValues,
1383 OcamlHTTPPost));
1384 if (Field(original->ocamlValues, OcamlSSLCert) != Val_unit)
1385 handleSSLCert(connection, Field(original->ocamlValues,
1386 OcamlSSLCert));
1387 if (Field(original->ocamlValues, OcamlSSLCertType) != Val_unit)
1388 handleSSLCertType(connection, Field(original->ocamlValues,
1389 OcamlSSLCertType));
1390 if (Field(original->ocamlValues, OcamlSSLCertPasswd) != Val_unit)
1391 handleSSLCertPasswd(connection, Field(original->ocamlValues,
1392 OcamlSSLCertPasswd));
1393 if (Field(original->ocamlValues, OcamlSSLKey) != Val_unit)
1394 handleSSLKey(connection, Field(original->ocamlValues,
1395 OcamlSSLKey));
1396 if (Field(original->ocamlValues, OcamlSSLKeyType) != Val_unit)
1397 handleSSLKeyType(connection, Field(original->ocamlValues,
1398 OcamlSSLKeyType));
1399 if (Field(original->ocamlValues, OcamlSSLKeyPasswd) != Val_unit)
1400 handleSSLKeyPasswd(connection, Field(original->ocamlValues,
1401 OcamlSSLKeyPasswd));
1402 if (Field(original->ocamlValues, OcamlSSLEngine) != Val_unit)
1403 handleSSLEngine(connection, Field(original->ocamlValues,
1404 OcamlSSLEngine));
1405 if (Field(original->ocamlValues, OcamlQuote) != Val_unit)
1406 handleQuote(connection, Field(original->ocamlValues,
1407 OcamlQuote));
1408 if (Field(original->ocamlValues, OcamlPostQuote) != Val_unit)
1409 handlePostQuote(connection, Field(original->ocamlValues,
1410 OcamlPostQuote));
1411 if (Field(original->ocamlValues, OcamlCookieFile) != Val_unit)
1412 handleCookieFile(connection, Field(original->ocamlValues,
1413 OcamlCookieFile));
1414 if (Field(original->ocamlValues, OcamlCustomRequest) != Val_unit)
1415 handleCustomRequest(connection, Field(original->ocamlValues,
1416 OcamlCustomRequest));
1417 if (Field(original->ocamlValues, OcamlInterface) != Val_unit)
1418 handleInterface(connection, Field(original->ocamlValues,
1419 OcamlInterface));
1420 if (Field(original->ocamlValues, OcamlCAInfo) != Val_unit)
1421 handleCAInfo(connection, Field(original->ocamlValues,
1422 OcamlCAInfo));
1423 if (Field(original->ocamlValues, OcamlCAPath) != Val_unit)
1424 handleCAPath(connection, Field(original->ocamlValues,
1425 OcamlCAPath));
1426 if (Field(original->ocamlValues, OcamlRandomFile) != Val_unit)
1427 handleRandomFile(connection, Field(original->ocamlValues,
1428 OcamlRandomFile));
1429 if (Field(original->ocamlValues, OcamlEGDSocket) != Val_unit)
1430 handleEGDSocket(connection, Field(original->ocamlValues,
1431 OcamlEGDSocket));
1432 if (Field(original->ocamlValues, OcamlCookieJar) != Val_unit)
1433 handleCookieJar(connection, Field(original->ocamlValues,
1434 OcamlCookieJar));
1435 if (Field(original->ocamlValues, OcamlSSLCipherList) != Val_unit)
1436 handleSSLCipherList(connection, Field(original->ocamlValues,
1437 OcamlSSLCipherList));
1438 if (Field(original->ocamlValues, OcamlPrivate) != Val_unit)
1439 handlePrivate(connection, Field(original->ocamlValues,
1440 OcamlPrivate));
1441 if (Field(original->ocamlValues, OcamlHTTP200Aliases) != Val_unit)
1442 handleHTTP200Aliases(connection, Field(original->ocamlValues,
1443 OcamlHTTP200Aliases));
1444 if (Field(original->ocamlValues, OcamlNETRCFile) != Val_unit)
1445 handleNETRCFile(connection, Field(original->ocamlValues,
1446 OcamlNETRCFile));
1447 if (Field(original->ocamlValues, OcamlFTPAccount) != Val_unit)
1448 handleFTPAccount(connection, Field(original->ocamlValues,
1449 OcamlFTPAccount));
1450 if (Field(original->ocamlValues, OcamlCookieList) != Val_unit)
1451 handleCookieList(connection, Field(original->ocamlValues,
1452 OcamlCookieList));
1453 if (Field(original->ocamlValues, OcamlFTPAlternativeToUser) != Val_unit)
1454 handleFTPAlternativeToUser(connection,
1455 Field(original->ocamlValues,
1456 OcamlFTPAlternativeToUser));
1457 if (Field(original->ocamlValues, OcamlSSHPublicKeyFile) != Val_unit)
1458 handleSSHPublicKeyFile(connection,
1459 Field(original->ocamlValues,
1460 OcamlSSHPublicKeyFile));
1461 if (Field(original->ocamlValues, OcamlSSHPrivateKeyFile) != Val_unit)
1462 handleSSHPrivateKeyFile(connection,
1463 Field(original->ocamlValues,
1464 OcamlSSHPrivateKeyFile));
1465 if (Field(original->ocamlValues, OcamlCopyPostFields) != Val_unit)
1466 handleCopyPostFields(connection,
1467 Field(original->ocamlValues,
1468 OcamlCopyPostFields));
1470 return connection;
1473 static void free_if(void* p) { if (NULL != p) free(p); }
1475 static void removeConnection(Connection *connection)
1477 enter_blocking_section();
1478 curl_easy_cleanup(connection->connection);
1479 leave_blocking_section();
1481 if (connectionList.tail == connection)
1482 connectionList.tail = connectionList.tail->next;
1483 if (connectionList.head == connection)
1484 connectionList.head = connectionList.head->prev;
1486 if (connection->next != NULL)
1487 connection->next->prev = connection->prev;
1488 if (connection->prev != NULL)
1489 connection->prev->next = connection->next;
1491 remove_global_root(&connection->ocamlValues);
1493 free_if(connection->url);
1494 free_if(connection->proxy);
1495 free_if(connection->userPwd);
1496 free_if(connection->proxyUserPwd);
1497 free_if(connection->range);
1498 free_if(connection->errorBuffer);
1499 free_if(connection->postFields);
1500 free_if(connection->referer);
1501 free_if(connection->userAgent);
1502 free_if(connection->ftpPort);
1503 free_if(connection->cookie);
1504 free_curl_slist(connection->httpHeader);
1505 if (connection->httpPostFirst != NULL)
1506 curl_formfree(connection->httpPostFirst);
1507 free_curl_slist(connection->httpPostStrings);
1508 free_curl_slist(connection->resolve);
1509 free_if(connection->sslCert);
1510 free_if(connection->sslCertType);
1511 free_if(connection->sslCertPasswd);
1512 free_if(connection->sslKey);
1513 free_if(connection->sslKeyType);
1514 free_if(connection->sslKeyPasswd);
1515 free_if(connection->sslEngine);
1516 free_curl_slist(connection->quote);
1517 free_curl_slist(connection->postQuote);
1518 free_if(connection->cookieFile);
1519 free_if(connection->customRequest);
1520 free_if(connection->interface);
1521 free_if(connection->caInfo);
1522 free_if(connection->caPath);
1523 free_if(connection->randomFile);
1524 free_if(connection->egdSocket);
1525 free_if(connection->cookieJar);
1526 free_if(connection->sslCipherList);
1527 free_if(connection->private);
1528 free_curl_slist(connection->http200Aliases);
1529 free_if(connection->netrcFile);
1530 free_if(connection->ftpaccount);
1531 free_if(connection->cookielist);
1532 free_if(connection->ftpAlternativeToUser);
1533 free_if(connection->sshPublicKeyFile);
1534 free_if(connection->sshPrivateKeyFile);
1535 free_if(connection->copyPostFields);
1536 free_if(connection->dns_servers);
1538 free(connection);
1541 static void checkConnection(Connection *connection)
1543 return;
1545 Connection *listIter;
1547 listIter = connectionList.tail;
1549 while (listIter != NULL)
1551 if (listIter == connection)
1552 return;
1554 listIter = listIter->next;
1557 failwith("Invalid Connection");
1560 static Connection* findConnection(CURL* h)
1562 Connection *listIter;
1564 listIter = connectionList.tail;
1566 while (listIter != NULL)
1568 if (listIter->connection == h)
1569 return listIter;
1571 listIter = listIter->next;
1574 failwith("Unknown handle");
1577 #define WRAP_DATA_CALLBACK(f) \
1578 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1580 size_t result;\
1581 leave_blocking_section();\
1582 result = f##_nolock(ptr,size,nmemb,data);\
1583 enter_blocking_section();\
1584 return result;\
1587 static size_t writeFunction_nolock(char *ptr, size_t size, size_t nmemb, void *data)
1589 CAMLparam0();
1590 CAMLlocal2(result, str);
1591 Connection *conn = (Connection *)data;
1592 int i;
1594 checkConnection(conn);
1596 str = alloc_string(size*nmemb);
1598 for (i = 0; i < size*nmemb; i++)
1599 Byte(str, i) = ptr[i];
1601 result = callback(Field(conn->ocamlValues, OcamlWriteCallback), str);
1603 CAMLreturnT(size_t, Int_val(result));
1606 WRAP_DATA_CALLBACK(writeFunction)
1608 static size_t readFunction_nolock(void *ptr, size_t size, size_t nmemb, void *data)
1610 CAMLparam0();
1611 CAMLlocal1(result);
1612 Connection *conn = (Connection *)data;
1613 int length;
1615 checkConnection(conn);
1617 result = callback(Field(conn->ocamlValues, OcamlReadCallback),
1618 Val_int(size*nmemb));
1620 length = string_length(result);
1622 if (length >= size*nmemb)
1623 length = size*nmemb;
1625 memcpy(ptr, String_val(result), length);
1627 CAMLreturnT(size_t,length);
1630 WRAP_DATA_CALLBACK(readFunction)
1632 static size_t headerFunction_nolock(char *ptr, size_t size, size_t nmemb, void *data)
1634 CAMLparam0();
1635 CAMLlocal2(result,str);
1636 Connection *conn = (Connection *)data;
1637 int i;
1639 checkConnection(conn);
1641 str = alloc_string(size*nmemb);
1643 for (i = 0; i < size*nmemb; i++)
1644 Byte(str, i) = ptr[i];
1646 result = callback(Field(conn->ocamlValues, OcamlHeaderCallback), str);
1648 CAMLreturnT(size_t, Int_val(result));
1651 WRAP_DATA_CALLBACK(headerFunction)
1653 static int progressFunction_nolock(void *data,
1654 double dlTotal,
1655 double dlNow,
1656 double ulTotal,
1657 double ulNow)
1659 CAMLparam0();
1660 CAMLlocal1(result);
1661 CAMLlocalN(callbackData, 4);
1662 Connection *conn = (Connection *)data;
1664 checkConnection(conn);
1666 callbackData[0] = copy_double(dlTotal);
1667 callbackData[1] = copy_double(dlNow);
1668 callbackData[2] = copy_double(ulTotal);
1669 callbackData[3] = copy_double(ulNow);
1671 result = callbackN(Field(conn->ocamlValues, OcamlProgressCallback),
1672 4, callbackData);
1674 CAMLreturnT(int, Bool_val(result));
1677 static int progressFunction(void *data,
1678 double dlTotal,
1679 double dlNow,
1680 double ulTotal,
1681 double ulNow)
1683 int r;
1684 leave_blocking_section();
1685 r = progressFunction_nolock(data,dlTotal,dlNow,ulTotal,ulNow);
1686 enter_blocking_section();
1687 return r;
1690 static int debugFunction_nolock(CURL *debugConnection,
1691 curl_infotype infoType,
1692 char *buffer,
1693 size_t bufferLength,
1694 void *data)
1696 CAMLparam0();
1697 CAMLlocal3(camlDebugConnection, camlInfoType, camlMessage);
1698 int i;
1699 Connection *conn = (Connection *)data;
1701 checkConnection(conn);
1703 camlDebugConnection = (value)conn;
1704 camlInfoType = Val_long(infoType);
1705 camlMessage = alloc_string(bufferLength);
1707 for (i = 0; i < bufferLength; i++)
1708 Byte(camlMessage, i) = buffer[i];
1710 callback3(Field(conn->ocamlValues, OcamlDebugCallback),
1711 camlDebugConnection,
1712 camlInfoType,
1713 camlMessage);
1715 CAMLreturnT(int, 0);
1718 static int debugFunction(CURL *debugConnection,
1719 curl_infotype infoType,
1720 char *buffer,
1721 size_t bufferLength,
1722 void *data)
1724 int r;
1725 leave_blocking_section();
1726 r = debugFunction_nolock(debugConnection, infoType, buffer, bufferLength, data);
1727 enter_blocking_section();
1728 return r;
1731 static curlioerr ioctlFunction_nolock(CURL *ioctl,
1732 int cmd,
1733 void *data)
1735 CAMLparam0();
1736 CAMLlocal3(camlResult, camlConnection, camlCmd);
1737 Connection *conn = (Connection *)data;
1738 curlioerr result = CURLIOE_OK;
1740 checkConnection(conn);
1742 if (cmd == CURLIOCMD_NOP)
1743 camlCmd = Val_long(0);
1744 else if (cmd == CURLIOCMD_RESTARTREAD)
1745 camlCmd = Val_long(1);
1746 else
1747 failwith("Invalid IOCTL Cmd!");
1749 camlConnection = caml_alloc(1, Abstract_tag);
1750 Field(camlConnection, 0) = (value)conn;
1752 camlResult = callback2(Field(conn->ocamlValues, OcamlIOCTLCallback),
1753 camlConnection,
1754 camlCmd);
1756 switch (Long_val(camlResult))
1758 case 0: /* CURLIOE_OK */
1759 result = CURLIOE_OK;
1760 break;
1762 case 1: /* CURLIOE_UNKNOWNCMD */
1763 result = CURLIOE_UNKNOWNCMD;
1764 break;
1766 case 2: /* CURLIOE_FAILRESTART */
1767 result = CURLIOE_FAILRESTART;
1768 break;
1770 default: /* Incorrect return value, but let's handle it */
1771 result = CURLIOE_FAILRESTART;
1772 break;
1775 CAMLreturnT(curlioerr, result);
1778 static curlioerr ioctlFunction(CURL *ioctl,
1779 int cmd,
1780 void *data)
1782 curlioerr r;
1783 leave_blocking_section();
1784 r = ioctlFunction_nolock(ioctl, cmd, data);
1785 enter_blocking_section();
1786 return r;
1789 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1790 static int seekFunction_nolock(void *data,
1791 curl_off_t offset,
1792 int origin)
1794 CAMLparam0();
1795 CAMLlocal3(camlResult, camlOffset, camlOrigin);
1796 Connection *conn = (Connection *)data;
1797 int result = 0;
1799 camlOffset = copy_int64(offset);
1801 if (origin == SEEK_SET)
1802 camlOrigin = Val_long(0);
1803 else if (origin == SEEK_CUR)
1804 camlOrigin = Val_long(1);
1805 else if (origin == SEEK_END)
1806 camlOrigin = Val_long(2);
1807 else
1808 camlOrigin = Val_long(0);
1810 camlResult = callback2(Field(conn->ocamlValues,
1811 OcamlSeekFunctionCallback),
1812 camlOffset,
1813 camlOrigin);
1815 result = Int_val(camlResult);
1817 CAMLreturnT(int, result);
1820 static int seekFunction(void *data,
1821 curl_off_t offset,
1822 int origin)
1824 int r;
1825 leave_blocking_section();
1826 r = seekFunction_nolock(data,offset,origin);
1827 enter_blocking_section();
1828 return r;
1831 #endif
1833 #ifdef HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
1834 static int openSocketFunction_nolock(void *data,
1835 curlsocktype purpose,
1836 struct curl_sockaddr *addr)
1838 CAMLparam0();
1839 Connection *conn = (Connection *)data;
1840 int sock = -1;
1842 sock = socket(addr->family, addr->socktype, addr->protocol);
1844 if (-1 != sock)
1846 /* FIXME windows */
1847 callback(Field(conn->ocamlValues, OcamlOpenSocketFunctionCallback), Val_int(sock));
1850 CAMLreturnT(int, sock);
1853 static int openSocketFunction(void *data,
1854 curlsocktype purpose,
1855 struct curl_sockaddr *address)
1857 int r;
1858 leave_blocking_section();
1859 r = openSocketFunction_nolock(data,purpose,address);
1860 enter_blocking_section();
1861 return r;
1864 #endif
1867 ** curl_global_init helper function
1870 CAMLprim value helper_curl_global_init(value initOption)
1872 CAMLparam1(initOption);
1874 switch (Long_val(initOption))
1876 case 0: /* CURLINIT_GLOBALALL */
1877 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL)));
1878 break;
1880 case 1: /* CURLINIT_GLOBALSSL */
1881 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL)));
1882 break;
1884 case 2: /* CURLINIT_GLOBALWIN32 */
1885 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32)));
1886 break;
1888 case 3: /* CURLINIT_GLOBALNOTHING */
1889 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING)));
1890 break;
1892 default:
1893 failwith("Invalid Initialization Option");
1894 break;
1897 /* Keep compiler happy, we should never get here due to failwith() */
1898 CAMLreturn(Val_unit);
1902 ** curl_global_cleanup helper function
1905 CAMLprim value helper_curl_global_cleanup(void)
1907 CAMLparam0();
1909 curl_global_cleanup();
1911 CAMLreturn(Val_unit);
1915 ** curl_easy_init helper function
1918 CAMLprim value helper_curl_easy_init(void)
1920 CAMLparam0();
1921 CAMLlocal1(result);
1923 Connection *conn = newConnection();
1925 result = caml_alloc(1, Abstract_tag);
1926 Field(result, 0) = (value)conn;
1928 CAMLreturn(result);
1931 CAMLprim value helper_curl_easy_reset(value conn)
1933 CAMLparam1(conn);
1934 Connection *connection = Connection_val(conn);
1936 checkConnection(connection);
1937 curl_easy_reset(connection->connection);
1938 resetOcamlValues(connection);
1940 CAMLreturn(Val_unit);
1944 ** curl_easy_setopt helper utility functions
1947 static void handleWriteFunction(Connection *conn, value option)
1949 CAMLparam1(option);
1950 CURLcode result = CURLE_OK;
1952 if (Tag_val(option) == Closure_tag)
1953 Store_field(conn->ocamlValues, OcamlWriteCallback, option);
1954 else
1955 failwith("Not a proper closure");
1957 result = curl_easy_setopt(conn->connection,
1958 CURLOPT_WRITEFUNCTION,
1959 writeFunction);
1961 if (result != CURLE_OK)
1962 raiseError(conn, result);
1964 result = curl_easy_setopt(conn->connection,
1965 CURLOPT_WRITEDATA,
1966 conn);
1968 if (result != CURLE_OK)
1969 raiseError(conn, result);
1971 CAMLreturn0;
1974 static void handleReadFunction(Connection *conn, value option)
1976 CAMLparam1(option);
1977 CURLcode result = CURLE_OK;
1979 if (Tag_val(option) == Closure_tag)
1980 Store_field(conn->ocamlValues, OcamlReadCallback, option);
1981 else
1982 failwith("Not a proper closure");
1984 result = curl_easy_setopt(conn->connection,
1985 CURLOPT_READFUNCTION,
1986 readFunction);
1988 if (result != CURLE_OK)
1989 raiseError(conn, result);
1991 result = curl_easy_setopt(conn->connection,
1992 CURLOPT_READDATA,
1993 conn);
1995 if (result != CURLE_OK)
1996 raiseError(conn, result);
1998 CAMLreturn0;
2001 static void handleURL(Connection *conn, value option)
2003 CAMLparam1(option);
2004 CURLcode result = CURLE_OK;
2006 Store_field(conn->ocamlValues, OcamlURL, option);
2008 if (conn->url != NULL)
2009 free(conn->url);
2011 conn->url = strdup(String_val(option));
2013 result = curl_easy_setopt(conn->connection,
2014 CURLOPT_URL,
2015 conn->url);
2017 if (result != CURLE_OK)
2018 raiseError(conn, result);
2020 CAMLreturn0;
2023 static void handleInFileSize(Connection *conn, value option)
2025 CAMLparam1(option);
2026 CURLcode result = CURLE_OK;
2028 result = curl_easy_setopt(conn->connection,
2029 CURLOPT_INFILESIZE,
2030 Long_val(option));
2032 if (result != CURLE_OK)
2033 raiseError(conn, result);
2035 CAMLreturn0;
2038 static void handleProxy(Connection *conn, value option)
2040 CAMLparam1(option);
2041 CURLcode result = CURLE_OK;
2043 Store_field(conn->ocamlValues, OcamlProxy, option);
2045 if (conn->proxy != NULL)
2046 free(conn->proxy);
2048 conn->proxy = strdup(String_val(option));
2050 result = curl_easy_setopt(conn->connection,
2051 CURLOPT_PROXY,
2052 conn->proxy);
2054 if (result != CURLE_OK)
2055 raiseError(conn, result);
2057 CAMLreturn0;
2060 static void handleProxyPort(Connection *conn, value option)
2062 CAMLparam1(option);
2063 CURLcode result = CURLE_OK;
2065 result = curl_easy_setopt(conn->connection,
2066 CURLOPT_PROXYPORT,
2067 Long_val(option));
2069 if (result != CURLE_OK)
2070 raiseError(conn, result);
2072 CAMLreturn0;
2075 static void handleHTTPProxyTunnel(Connection *conn, value option)
2077 CAMLparam1(option);
2078 CURLcode result = CURLE_OK;
2080 result = curl_easy_setopt(conn->connection,
2081 CURLOPT_HTTPPROXYTUNNEL,
2082 Bool_val(option));
2084 if (result != CURLE_OK)
2085 raiseError(conn, result);
2087 CAMLreturn0;
2090 static void handleVerbose(Connection *conn, value option)
2092 CAMLparam1(option);
2093 CURLcode result = CURLE_OK;
2095 result = curl_easy_setopt(conn->connection,
2096 CURLOPT_VERBOSE,
2097 Bool_val(option));
2099 if (result != CURLE_OK)
2100 raiseError(conn, result);
2102 CAMLreturn0;
2105 static void handleHeader(Connection *conn, value option)
2107 CAMLparam1(option);
2108 CURLcode result = CURLE_OK;
2110 result = curl_easy_setopt(conn->connection,
2111 CURLOPT_HEADER,
2112 Bool_val(option));
2114 if (result != CURLE_OK)
2115 raiseError(conn, result);
2117 CAMLreturn0;
2120 static void handleNoProgress(Connection *conn, value option)
2122 CAMLparam1(option);
2123 CURLcode result = CURLE_OK;
2125 result = curl_easy_setopt(conn->connection,
2126 CURLOPT_NOPROGRESS,
2127 Bool_val(option));
2129 if (result != CURLE_OK)
2130 raiseError(conn, result);
2132 CAMLreturn0;
2135 static void handleNoSignal(Connection *conn, value option)
2137 #if HAVE_DECL_CURLOPT_NOSIGNAL
2138 CAMLparam1(option);
2139 CURLcode result = CURLE_OK;
2141 result = curl_easy_setopt(conn->connection,
2142 CURLOPT_NOSIGNAL,
2143 Bool_val(option));
2145 if (result != CURLE_OK)
2146 raiseError(conn, result);
2148 CAMLreturn0;
2149 #else
2150 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2151 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2152 #endif
2155 static void handleNoBody(Connection *conn, value option)
2157 CAMLparam1(option);
2158 CURLcode result = CURLE_OK;
2160 result = curl_easy_setopt(conn->connection,
2161 CURLOPT_NOBODY,
2162 Bool_val(option));
2164 if (result != CURLE_OK)
2165 raiseError(conn, result);
2167 CAMLreturn0;
2170 static void handleFailOnError(Connection *conn, value option)
2172 CAMLparam1(option);
2173 CURLcode result = CURLE_OK;
2175 result = curl_easy_setopt(conn->connection,
2176 CURLOPT_FAILONERROR,
2177 Bool_val(option));
2179 if (result != CURLE_OK)
2180 raiseError(conn, result);
2182 CAMLreturn0;
2185 static void handleUpload(Connection *conn, value option)
2187 CAMLparam1(option);
2188 CURLcode result = CURLE_OK;
2190 result = curl_easy_setopt(conn->connection,
2191 CURLOPT_UPLOAD,
2192 Bool_val(option));
2194 if (result != CURLE_OK)
2195 raiseError(conn, result);
2197 CAMLreturn0;
2200 static void handlePost(Connection *conn, value option)
2202 CAMLparam1(option);
2203 CURLcode result = CURLE_OK;
2205 result = curl_easy_setopt(conn->connection,
2206 CURLOPT_POST,
2207 Bool_val(option));
2209 if (result != CURLE_OK)
2210 raiseError(conn, result);
2212 CAMLreturn0;
2215 static void handleFTPListOnly(Connection *conn, value option)
2217 CAMLparam1(option);
2218 CURLcode result = CURLE_OK;
2220 result = curl_easy_setopt(conn->connection,
2221 CURLOPT_FTPLISTONLY,
2222 Bool_val(option));
2224 if (result != CURLE_OK)
2225 raiseError(conn, result);
2227 CAMLreturn0;
2230 static void handleFTPAppend(Connection *conn, value option)
2232 CAMLparam1(option);
2233 CURLcode result = CURLE_OK;
2235 result = curl_easy_setopt(conn->connection,
2236 CURLOPT_FTPAPPEND,
2237 Bool_val(option));
2239 if (result != CURLE_OK)
2240 raiseError(conn, result);
2242 CAMLreturn0;
2245 static void handleNETRC(Connection *conn, value option)
2247 CAMLparam1(option);
2248 CURLcode result = CURLE_OK;
2249 long netrc;
2251 switch (Long_val(option))
2253 case 0: /* CURL_NETRC_OPTIONAL */
2254 netrc = CURL_NETRC_OPTIONAL;
2255 break;
2257 case 1:/* CURL_NETRC_IGNORED */
2258 netrc = CURL_NETRC_IGNORED;
2259 break;
2261 case 2: /* CURL_NETRC_REQUIRED */
2262 netrc = CURL_NETRC_REQUIRED;
2263 break;
2265 default:
2266 failwith("Invalid NETRC Option");
2267 break;
2270 result = curl_easy_setopt(conn->connection,
2271 CURLOPT_NETRC,
2272 netrc);
2274 if (result != CURLE_OK)
2275 raiseError(conn, result);
2277 CAMLreturn0;
2280 static void handleEncoding(Connection *conn, value option)
2282 #if HAVE_DECL_CURLOPT_ENCODING
2283 CAMLparam1(option);
2284 CURLcode result = CURLE_OK;
2286 switch (Long_val(option))
2288 case 0: /* CURL_ENCODING_NONE */
2289 result = curl_easy_setopt(conn->connection,
2290 CURLOPT_ENCODING,
2291 "identity");
2292 break;
2294 case 1: /* CURL_ENCODING_DEFLATE */
2295 result = curl_easy_setopt(conn->connection,
2296 CURLOPT_ENCODING,
2297 "deflate");
2298 break;
2300 case 2: /* CURL_ENCODING_GZIP */
2301 result = curl_easy_setopt(conn->connection,
2302 CURLOPT_ENCODING,
2303 "gzip");
2304 break;
2306 case 3: /* CURL_ENCODING_ANY */
2307 result = curl_easy_setopt(conn->connection,
2308 CURLOPT_ENCODING,
2309 "");
2310 break;
2312 default:
2313 failwith("Invalid Encoding Option");
2314 break;
2317 if (result != CURLE_OK)
2318 raiseError(conn, result);
2320 CAMLreturn0;
2321 #else
2322 #warning "libcurl does not implement CURLOPT_ENCODING"
2323 failwith("libcurl does not implement CURLOPT_ENCODING");
2324 #endif
2327 static void handleFollowLocation(Connection *conn, value option)
2329 CAMLparam1(option);
2330 CURLcode result = CURLE_OK;
2332 result = curl_easy_setopt(conn->connection,
2333 CURLOPT_FOLLOWLOCATION,
2334 Bool_val(option));
2336 if (result != CURLE_OK)
2337 raiseError(conn, result);
2339 CAMLreturn0;
2342 static void handleTransferText(Connection *conn, value option)
2344 CAMLparam1(option);
2345 CURLcode result = CURLE_OK;
2347 result = curl_easy_setopt(conn->connection,
2348 CURLOPT_TRANSFERTEXT,
2349 Bool_val(option));
2351 if (result != CURLE_OK)
2352 raiseError(conn, result);
2354 CAMLreturn0;
2357 static void handlePut(Connection *conn, value option)
2359 CAMLparam1(option);
2360 CURLcode result = CURLE_OK;
2362 result = curl_easy_setopt(conn->connection,
2363 CURLOPT_PUT,
2364 Bool_val(option));
2366 if (result != CURLE_OK)
2367 raiseError(conn, result);
2369 CAMLreturn0;
2372 static void handleUserPwd(Connection *conn, value option)
2374 CAMLparam1(option);
2375 CURLcode result = CURLE_OK;
2377 Store_field(conn->ocamlValues, OcamlUserPWD, option);
2379 if (conn->userPwd != NULL)
2380 free(conn->userPwd);
2382 conn->userPwd = strdup(String_val(option));
2384 result = curl_easy_setopt(conn->connection,
2385 CURLOPT_USERPWD,
2386 conn->userPwd);
2388 if (result != CURLE_OK)
2389 raiseError(conn, result);
2391 CAMLreturn0;
2394 static void handleProxyUserPwd(Connection *conn, value option)
2396 CAMLparam1(option);
2397 CURLcode result = CURLE_OK;
2399 Store_field(conn->ocamlValues, OcamlProxyUserPWD, option);
2401 if (conn->proxyUserPwd != NULL)
2402 free(conn->proxyUserPwd);
2404 conn->proxyUserPwd = strdup(String_val(option));
2406 result = curl_easy_setopt(conn->connection,
2407 CURLOPT_PROXYUSERPWD,
2408 conn->proxyUserPwd);
2410 if (result != CURLE_OK)
2411 raiseError(conn, result);
2413 CAMLreturn0;
2416 static void handleRange(Connection *conn, value option)
2418 CAMLparam1(option);
2419 CURLcode result = CURLE_OK;
2421 Store_field(conn->ocamlValues, OcamlRange, option);
2423 if (conn->range != NULL)
2424 free(conn->range);
2426 conn->range = strdup(String_val(option));
2428 result = curl_easy_setopt(conn->connection,
2429 CURLOPT_RANGE,
2430 conn->range);
2432 if (result != CURLE_OK)
2433 raiseError(conn, result);
2435 CAMLreturn0;
2438 static void handleErrorBuffer(Connection *conn, value option)
2440 CAMLparam1(option);
2441 CURLcode result = CURLE_OK;
2443 Store_field(conn->ocamlValues, OcamlErrorBuffer, option);
2445 if (conn->errorBuffer != NULL)
2446 free(conn->errorBuffer);
2448 conn->errorBuffer = malloc(sizeof(char) * CURL_ERROR_SIZE);
2450 result = curl_easy_setopt(conn->connection,
2451 CURLOPT_ERRORBUFFER,
2452 conn->errorBuffer);
2454 if (result != CURLE_OK)
2455 raiseError(conn, result);
2457 CAMLreturn0;
2460 static void handleTimeout(Connection *conn, value option)
2462 CAMLparam1(option);
2463 CURLcode result = CURLE_OK;
2465 result = curl_easy_setopt(conn->connection,
2466 CURLOPT_TIMEOUT,
2467 Long_val(option));
2469 if (result != CURLE_OK)
2470 raiseError(conn, result);
2472 CAMLreturn0;
2475 static void handlePostFields(Connection *conn, value option)
2477 CAMLparam1(option);
2478 CURLcode result = CURLE_OK;
2480 Store_field(conn->ocamlValues, OcamlPostFields, option);
2482 if (conn->postFields != NULL)
2483 free(conn->postFields);
2485 conn->postFields = malloc(string_length(option)+1);
2486 memcpy(conn->postFields, String_val(option), string_length(option)+1);
2488 result = curl_easy_setopt(conn->connection,
2489 CURLOPT_POSTFIELDS,
2490 conn->postFields);
2492 if (result != CURLE_OK)
2493 raiseError(conn, result);
2495 CAMLreturn0;
2498 static void handlePostFieldSize(Connection *conn, value option)
2500 CAMLparam1(option);
2501 CURLcode result = CURLE_OK;
2503 result = curl_easy_setopt(conn->connection,
2504 CURLOPT_POSTFIELDSIZE,
2505 Long_val(option));
2507 if (result != CURLE_OK)
2508 raiseError(conn, result);
2510 CAMLreturn0;
2513 static void handleReferer(Connection *conn, value option)
2515 CAMLparam1(option);
2516 CURLcode result = CURLE_OK;
2518 Store_field(conn->ocamlValues, OcamlReferer, option);
2520 if (conn->referer != NULL)
2521 free(conn->referer);
2523 conn->referer = strdup(String_val(option));
2525 result = curl_easy_setopt(conn->connection,
2526 CURLOPT_REFERER,
2527 conn->referer);
2529 if (result != CURLE_OK)
2530 raiseError(conn, result);
2532 CAMLreturn0;
2535 static void handleUserAgent(Connection *conn, value option)
2537 CAMLparam1(option);
2538 CURLcode result = CURLE_OK;
2540 Store_field(conn->ocamlValues, OcamlUserAgent, option);
2542 if (conn->userAgent != NULL)
2543 free(conn->userAgent);
2545 conn->userAgent = strdup(String_val(option));
2547 result = curl_easy_setopt(conn->connection,
2548 CURLOPT_USERAGENT,
2549 conn->userAgent);
2551 if (result != CURLE_OK)
2552 raiseError(conn, result);
2554 CAMLreturn0;
2557 static void handleFTPPort(Connection *conn, value option)
2559 CAMLparam1(option);
2560 CURLcode result = CURLE_OK;
2562 Store_field(conn->ocamlValues, OcamlFTPPort, option);
2564 if (conn->ftpPort != NULL)
2565 free(conn->ftpPort);
2567 conn->ftpPort = strdup(String_val(option));
2569 result = curl_easy_setopt(conn->connection,
2570 CURLOPT_FTPPORT,
2571 conn->ftpPort);
2573 if (result != CURLE_OK)
2574 raiseError(conn, result);
2576 CAMLreturn0;
2579 static void handleLowSpeedLimit(Connection *conn, value option)
2581 CAMLparam1(option);
2582 CURLcode result = CURLE_OK;
2584 result = curl_easy_setopt(conn->connection,
2585 CURLOPT_LOW_SPEED_LIMIT,
2586 Long_val(option));
2588 if (result != CURLE_OK)
2589 raiseError(conn, result);
2591 CAMLreturn0;
2594 static void handleLowSpeedTime(Connection *conn, value option)
2596 CAMLparam1(option);
2597 CURLcode result = CURLE_OK;
2599 result = curl_easy_setopt(conn->connection,
2600 CURLOPT_LOW_SPEED_TIME,
2601 Long_val(option));
2603 if (result != CURLE_OK)
2604 raiseError(conn, result);
2606 CAMLreturn0;
2609 static void handleResumeFrom(Connection *conn, value option)
2611 CAMLparam1(option);
2612 CURLcode result = CURLE_OK;
2614 result = curl_easy_setopt(conn->connection,
2615 CURLOPT_RESUME_FROM,
2616 Long_val(option));
2618 if (result != CURLE_OK)
2619 raiseError(conn, result);
2621 CAMLreturn0;
2624 static void handleCookie(Connection *conn, value option)
2626 CAMLparam1(option);
2627 CURLcode result = CURLE_OK;
2629 Store_field(conn->ocamlValues, OcamlCookie, option);
2631 if (conn->cookie != NULL)
2632 free(conn->cookie);
2634 conn->cookie = strdup(String_val(option));
2636 result = curl_easy_setopt(conn->connection,
2637 CURLOPT_COOKIE,
2638 conn->cookie);
2640 if (result != CURLE_OK)
2641 raiseError(conn, result);
2643 CAMLreturn0;
2646 static void handleHTTPHeader(Connection *conn, value option)
2648 CAMLparam1(option);
2649 CAMLlocal1(listIter);
2650 CURLcode result = CURLE_OK;
2652 Store_field(conn->ocamlValues, OcamlHTTPHeader, option);
2654 free_curl_slist(conn->httpHeader);
2655 conn->httpHeader = NULL;
2657 listIter = option;
2659 while (!Is_long(listIter))
2661 conn->httpHeader = curl_slist_append(conn->httpHeader, String_val(Field(listIter, 0)));
2663 listIter = Field(listIter, 1);
2666 result = curl_easy_setopt(conn->connection,
2667 CURLOPT_HTTPHEADER,
2668 conn->httpHeader);
2670 if (result != CURLE_OK)
2671 raiseError(conn, result);
2673 CAMLreturn0;
2676 static void handleHTTPPost(Connection *conn, value option)
2678 CAMLparam1(option);
2679 CAMLlocal3(listIter, formItem, contentType);
2680 CURLcode result = CURLE_OK;
2681 char *str1, *str2, *str3, *str4;
2683 listIter = option;
2685 Store_field(conn->ocamlValues, OcamlHTTPPost, option);
2687 if (conn->httpPostFirst != NULL)
2688 curl_formfree(conn->httpPostFirst);
2690 conn->httpPostFirst = NULL;
2691 conn->httpPostLast = NULL;
2693 free_curl_slist(conn->httpPostStrings);
2694 conn->httpPostStrings = NULL;
2696 while (!Is_long(listIter))
2698 formItem = Field(listIter, 0);
2700 switch (Tag_val(formItem))
2702 case 0: /* CURLFORM_CONTENT */
2703 if (Wosize_val(formItem) < 3)
2705 failwith("Incorrect CURLFORM_CONTENT parameters");
2708 if (Is_long(Field(formItem, 2)) &&
2709 Long_val(Field(formItem, 2)) == 0)
2711 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2712 memcpy(str1,
2713 String_val(Field(formItem, 0)),
2714 string_length(Field(formItem, 0)));
2715 str1[string_length(Field(formItem, 0))] = 0;
2716 conn->httpPostStrings =
2717 curl_slist_append(conn->httpPostStrings, str1);
2719 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2720 memcpy(str2,
2721 String_val(Field(formItem, 1)),
2722 string_length(Field(formItem, 1)));
2723 str2[string_length(Field(formItem, 1))] = 0;
2724 conn->httpPostStrings =
2725 curl_slist_append(conn->httpPostStrings, str2);
2727 curl_formadd(&conn->httpPostFirst,
2728 &conn->httpPostLast,
2729 CURLFORM_PTRNAME,
2730 str1,
2731 CURLFORM_NAMELENGTH,
2732 string_length(Field(formItem, 0)),
2733 CURLFORM_PTRCONTENTS,
2734 str2,
2735 CURLFORM_CONTENTSLENGTH,
2736 string_length(Field(formItem, 1)),
2737 CURLFORM_END);
2739 else if (Is_block(Field(formItem, 2)))
2741 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2742 memcpy(str1,
2743 String_val(Field(formItem, 0)),
2744 string_length(Field(formItem, 0)));
2745 str1[string_length(Field(formItem, 0))] = 0;
2746 conn->httpPostStrings =
2747 curl_slist_append(conn->httpPostStrings, str1);
2749 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2750 memcpy(str2,
2751 String_val(Field(formItem, 1)),
2752 string_length(Field(formItem, 1)));
2753 str2[string_length(Field(formItem, 1))] = 0;
2754 conn->httpPostStrings =
2755 curl_slist_append(conn->httpPostStrings, str2);
2757 contentType = Field(formItem, 2);
2759 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2760 memcpy(str3,
2761 String_val(Field(contentType, 0)),
2762 string_length(Field(contentType, 0)));
2763 str3[string_length(Field(contentType, 0))] = 0;
2764 conn->httpPostStrings =
2765 curl_slist_append(conn->httpPostStrings, str3);
2767 curl_formadd(&conn->httpPostFirst,
2768 &conn->httpPostLast,
2769 CURLFORM_PTRNAME,
2770 str1,
2771 CURLFORM_NAMELENGTH,
2772 string_length(Field(formItem, 0)),
2773 CURLFORM_PTRCONTENTS,
2774 str2,
2775 CURLFORM_CONTENTSLENGTH,
2776 string_length(Field(formItem, 1)),
2777 CURLFORM_CONTENTTYPE,
2778 str3,
2779 CURLFORM_END);
2781 else
2783 failwith("Incorrect CURLFORM_CONTENT parameters");
2785 break;
2787 case 1: /* CURLFORM_FILECONTENT */
2788 if (Wosize_val(formItem) < 3)
2790 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2793 if (Is_long(Field(formItem, 2)) &&
2794 Long_val(Field(formItem, 2)) == 0)
2796 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2797 memcpy(str1,
2798 String_val(Field(formItem, 0)),
2799 string_length(Field(formItem, 0)));
2800 str1[string_length(Field(formItem, 0))] = 0;
2801 conn->httpPostStrings =
2802 curl_slist_append(conn->httpPostStrings, str1);
2804 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2805 memcpy(str2,
2806 String_val(Field(formItem, 1)),
2807 string_length(Field(formItem, 1)));
2808 str2[string_length(Field(formItem, 1))] = 0;
2809 conn->httpPostStrings =
2810 curl_slist_append(conn->httpPostStrings, str2);
2812 curl_formadd(&conn->httpPostFirst,
2813 &conn->httpPostLast,
2814 CURLFORM_PTRNAME,
2815 str1,
2816 CURLFORM_NAMELENGTH,
2817 string_length(Field(formItem, 0)),
2818 CURLFORM_FILECONTENT,
2819 str2,
2820 CURLFORM_END);
2822 else if (Is_block(Field(formItem, 2)))
2824 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2825 memcpy(str1,
2826 String_val(Field(formItem, 0)),
2827 string_length(Field(formItem, 0)));
2828 str1[string_length(Field(formItem, 0))] = 0;
2829 conn->httpPostStrings =
2830 curl_slist_append(conn->httpPostStrings, str1);
2832 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2833 memcpy(str2,
2834 String_val(Field(formItem, 1)),
2835 string_length(Field(formItem, 1)));
2836 str2[string_length(Field(formItem, 1))] = 0;
2837 conn->httpPostStrings =
2838 curl_slist_append(conn->httpPostStrings, str2);
2840 contentType = Field(formItem, 2);
2842 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2843 memcpy(str3,
2844 String_val(Field(contentType, 0)),
2845 string_length(Field(contentType, 0)));
2846 str3[string_length(Field(contentType, 0))] = 0;
2847 conn->httpPostStrings =
2848 curl_slist_append(conn->httpPostStrings, str3);
2850 curl_formadd(&conn->httpPostFirst,
2851 &conn->httpPostLast,
2852 CURLFORM_PTRNAME,
2853 str1,
2854 CURLFORM_NAMELENGTH,
2855 string_length(Field(formItem, 0)),
2856 CURLFORM_FILECONTENT,
2857 str2,
2858 CURLFORM_CONTENTTYPE,
2859 str3,
2860 CURLFORM_END);
2862 else
2864 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2866 break;
2868 case 2: /* CURLFORM_FILE */
2869 if (Wosize_val(formItem) < 3)
2871 failwith("Incorrect CURLFORM_FILE parameters");
2874 if (Is_long(Field(formItem, 2)) &&
2875 Long_val(Field(formItem, 2)) == 0)
2877 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2878 memcpy(str1,
2879 String_val(Field(formItem, 0)),
2880 string_length(Field(formItem, 0)));
2881 str1[string_length(Field(formItem, 0))] = 0;
2882 conn->httpPostStrings =
2883 curl_slist_append(conn->httpPostStrings, str1);
2885 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2886 memcpy(str2,
2887 String_val(Field(formItem, 1)),
2888 string_length(Field(formItem, 1)));
2889 str2[string_length(Field(formItem, 1))] = 0;
2890 conn->httpPostStrings =
2891 curl_slist_append(conn->httpPostStrings, str2);
2893 curl_formadd(&conn->httpPostFirst,
2894 &conn->httpPostLast,
2895 CURLFORM_PTRNAME,
2896 str1,
2897 CURLFORM_NAMELENGTH,
2898 string_length(Field(formItem, 0)),
2899 CURLFORM_FILE,
2900 str2,
2901 CURLFORM_END);
2903 else if (Is_block(Field(formItem, 2)))
2905 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2906 memcpy(str1,
2907 String_val(Field(formItem, 0)),
2908 string_length(Field(formItem, 0)));
2909 str1[string_length(Field(formItem, 0))] = 0;
2910 conn->httpPostStrings =
2911 curl_slist_append(conn->httpPostStrings, str1);
2913 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2914 memcpy(str2,
2915 String_val(Field(formItem, 1)),
2916 string_length(Field(formItem, 1)));
2917 str2[string_length(Field(formItem, 1))] = 0;
2918 conn->httpPostStrings =
2919 curl_slist_append(conn->httpPostStrings, str2);
2921 contentType = Field(formItem, 2);
2923 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2924 memcpy(str3,
2925 String_val(Field(contentType, 0)),
2926 string_length(Field(contentType, 0)));
2927 str3[string_length(Field(contentType, 0))] = 0;
2928 conn->httpPostStrings =
2929 curl_slist_append(conn->httpPostStrings, str3);
2931 curl_formadd(&conn->httpPostFirst,
2932 &conn->httpPostLast,
2933 CURLFORM_PTRNAME,
2934 str1,
2935 CURLFORM_NAMELENGTH,
2936 string_length(Field(formItem, 0)),
2937 CURLFORM_FILE,
2938 str2,
2939 CURLFORM_CONTENTTYPE,
2940 str3,
2941 CURLFORM_END);
2943 else
2945 failwith("Incorrect CURLFORM_FILE parameters");
2947 break;
2949 case 3: /* CURLFORM_BUFFER */
2950 if (Wosize_val(formItem) < 4)
2952 failwith("Incorrect CURLFORM_BUFFER parameters");
2955 if (Is_long(Field(formItem, 3)) &&
2956 Long_val(Field(formItem, 3)) == 0)
2958 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2959 memcpy(str1,
2960 String_val(Field(formItem, 0)),
2961 string_length(Field(formItem, 0)));
2962 str1[string_length(Field(formItem, 0))] = 0;
2963 conn->httpPostStrings =
2964 curl_slist_append(conn->httpPostStrings, str1);
2966 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2967 memcpy(str2,
2968 String_val(Field(formItem, 1)),
2969 string_length(Field(formItem, 1)));
2970 str2[string_length(Field(formItem, 1))] = 0;
2971 conn->httpPostStrings =
2972 curl_slist_append(conn->httpPostStrings, str2);
2974 str3 = (char *)malloc(string_length(Field(formItem, 2))+1);
2975 memcpy(str3,
2976 String_val(Field(formItem, 2)),
2977 string_length(Field(formItem, 2)));
2978 str3[string_length(Field(formItem, 2))] = 0;
2979 conn->httpPostStrings =
2980 curl_slist_append(conn->httpPostStrings, str3);
2982 curl_formadd(&conn->httpPostFirst,
2983 &conn->httpPostLast,
2984 CURLFORM_PTRNAME,
2985 str1,
2986 CURLFORM_NAMELENGTH,
2987 string_length(Field(formItem, 0)),
2988 CURLFORM_BUFFER,
2989 str2,
2990 CURLFORM_BUFFERPTR,
2991 str3,
2992 CURLFORM_BUFFERLENGTH,
2993 string_length(Field(formItem, 2)),
2994 CURLFORM_END);
2996 else if (Is_block(Field(formItem, 3)))
2998 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2999 memcpy(str1,
3000 String_val(Field(formItem, 0)),
3001 string_length(Field(formItem, 0)));
3002 str1[string_length(Field(formItem, 0))] = 0;
3003 conn->httpPostStrings =
3004 curl_slist_append(conn->httpPostStrings, str1);
3006 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
3007 memcpy(str2,
3008 String_val(Field(formItem, 1)),
3009 string_length(Field(formItem, 1)));
3010 str2[string_length(Field(formItem, 1))] = 0;
3011 conn->httpPostStrings =
3012 curl_slist_append(conn->httpPostStrings, str2);
3014 str3 = (char *)malloc(string_length(Field(formItem, 2))+1);
3015 memcpy(str3,
3016 String_val(Field(formItem, 2)),
3017 string_length(Field(formItem, 2)));
3018 str3[string_length(Field(formItem, 2))] = 0;
3019 conn->httpPostStrings =
3020 curl_slist_append(conn->httpPostStrings, str3);
3022 contentType = Field(formItem, 3);
3024 str4 = (char *)malloc(string_length(Field(contentType, 0))+1);
3025 memcpy(str4,
3026 String_val(Field(contentType, 0)),
3027 string_length(Field(contentType, 0)));
3028 str4[string_length(Field(contentType, 0))] = 0;
3029 conn->httpPostStrings =
3030 curl_slist_append(conn->httpPostStrings, str4);
3032 curl_formadd(&conn->httpPostFirst,
3033 &conn->httpPostLast,
3034 CURLFORM_PTRNAME,
3035 str1,
3036 CURLFORM_NAMELENGTH,
3037 string_length(Field(formItem, 0)),
3038 CURLFORM_BUFFER,
3039 str2,
3040 CURLFORM_BUFFERPTR,
3041 str3,
3042 CURLFORM_BUFFERLENGTH,
3043 string_length(Field(formItem, 2)),
3044 CURLFORM_CONTENTTYPE,
3045 str4,
3046 CURLFORM_END);
3048 else
3050 failwith("Incorrect CURLFORM_BUFFER parameters");
3052 break;
3055 listIter = Field(listIter, 1);
3058 result = curl_easy_setopt(conn->connection,
3059 CURLOPT_HTTPPOST,
3060 conn->httpPostFirst);
3062 if (result != CURLE_OK)
3063 raiseError(conn, result);
3065 CAMLreturn0;
3068 static void handleSSLCert(Connection *conn, value option)
3070 CAMLparam1(option);
3071 CURLcode result = CURLE_OK;
3073 Store_field(conn->ocamlValues, OcamlSSLCert, option);
3075 if (conn->sslCert != NULL)
3076 free(conn->sslCert);
3078 conn->sslCert = strdup(String_val(option));
3080 result = curl_easy_setopt(conn->connection,
3081 CURLOPT_SSLCERT,
3082 conn->sslCert);
3084 if (result != CURLE_OK)
3085 raiseError(conn, result);
3087 CAMLreturn0;
3090 static void handleSSLCertType(Connection *conn, value option)
3092 CAMLparam1(option);
3093 CURLcode result = CURLE_OK;
3095 Store_field(conn->ocamlValues, OcamlSSLCertType, option);
3097 if (conn->sslCertType != NULL)
3098 free(conn->sslCertType);
3100 conn->sslCertType = strdup(String_val(option));
3102 result = curl_easy_setopt(conn->connection,
3103 CURLOPT_SSLCERTTYPE,
3104 conn->sslCertType);
3106 if (result != CURLE_OK)
3107 raiseError(conn, result);
3109 CAMLreturn0;
3112 static void handleSSLCertPasswd(Connection *conn, value option)
3114 CAMLparam1(option);
3115 CURLcode result = CURLE_OK;
3117 Store_field(conn->ocamlValues, OcamlSSLCertPasswd, option);
3119 if (conn->sslCertPasswd != NULL)
3120 free(conn->sslCertPasswd);
3122 conn->sslCertPasswd = strdup(String_val(option));
3124 result = curl_easy_setopt(conn->connection,
3125 CURLOPT_SSLCERTPASSWD,
3126 conn->sslCertPasswd);
3128 if (result != CURLE_OK)
3129 raiseError(conn, result);
3131 CAMLreturn0;
3134 static void handleSSLKey(Connection *conn, value option)
3136 CAMLparam1(option);
3137 CURLcode result = CURLE_OK;
3139 Store_field(conn->ocamlValues, OcamlSSLKey, option);
3141 if (conn->sslKey != NULL)
3142 free(conn->sslKey);
3144 conn->sslKey = strdup(String_val(option));
3146 result = curl_easy_setopt(conn->connection,
3147 CURLOPT_SSLKEY,
3148 conn->sslKey);
3150 if (result != CURLE_OK)
3151 raiseError(conn, result);
3153 CAMLreturn0;
3156 static void handleSSLKeyType(Connection *conn, value option)
3158 CAMLparam1(option);
3159 CURLcode result = CURLE_OK;
3161 Store_field(conn->ocamlValues, OcamlSSLKeyType, option);
3163 if (conn->sslKeyType != NULL)
3164 free(conn->sslKeyType);
3166 conn->sslKeyType = strdup(String_val(option));
3168 result = curl_easy_setopt(conn->connection,
3169 CURLOPT_SSLKEYTYPE,
3170 conn->sslKeyType);
3172 if (result != CURLE_OK)
3173 raiseError(conn, result);
3175 CAMLreturn0;
3178 static void handleSSLKeyPasswd(Connection *conn, value option)
3180 CAMLparam1(option);
3181 CURLcode result = CURLE_OK;
3183 Store_field(conn->ocamlValues, OcamlSSLKeyPasswd, option);
3185 if (conn->sslKeyPasswd != NULL)
3186 free(conn->sslKeyPasswd);
3188 conn->sslKeyPasswd = strdup(String_val(option));
3190 result = curl_easy_setopt(conn->connection,
3191 CURLOPT_SSLKEYPASSWD,
3192 conn->sslKeyPasswd);
3194 if (result != CURLE_OK)
3195 raiseError(conn, result);
3197 CAMLreturn0;
3200 static void handleSSLEngine(Connection *conn, value option)
3202 CAMLparam1(option);
3203 CURLcode result = CURLE_OK;
3205 Store_field(conn->ocamlValues, OcamlSSLEngine, option);
3207 if (conn->sslEngine != NULL)
3208 free(conn->sslEngine);
3210 conn->sslEngine = strdup(String_val(option));
3212 result = curl_easy_setopt(conn->connection,
3213 CURLOPT_SSLENGINE,
3214 conn->sslEngine);
3216 if (result != CURLE_OK)
3217 raiseError(conn, result);
3219 CAMLreturn0;
3222 static void handleSSLEngineDefault(Connection *conn, value option)
3224 CAMLparam1(option);
3225 CURLcode result = CURLE_OK;
3227 result = curl_easy_setopt(conn->connection,
3228 CURLOPT_SSLENGINE_DEFAULT,
3229 Bool_val(option));
3231 if (result != CURLE_OK)
3232 raiseError(conn, result);
3234 CAMLreturn0;
3237 static void handleCRLF(Connection *conn, value option)
3239 CAMLparam1(option);
3240 CURLcode result = CURLE_OK;
3242 result = curl_easy_setopt(conn->connection,
3243 CURLOPT_CRLF,
3244 Bool_val(option));
3246 if (result != CURLE_OK)
3247 raiseError(conn, result);
3249 CAMLreturn0;
3252 static void handleQuote(Connection *conn, value option)
3254 CAMLparam1(option);
3255 CAMLlocal1(listIter);
3256 CURLcode result = CURLE_OK;
3258 Store_field(conn->ocamlValues, OcamlQuote, option);
3260 free_curl_slist(conn->quote);
3261 conn->quote = NULL;
3263 listIter = option;
3265 while (!Is_long(listIter))
3267 conn->quote = curl_slist_append(conn->quote, String_val(Field(listIter, 0)));
3269 listIter = Field(listIter, 1);
3272 result = curl_easy_setopt(conn->connection,
3273 CURLOPT_QUOTE,
3274 conn->quote);
3276 if (result != CURLE_OK)
3277 raiseError(conn, result);
3279 CAMLreturn0;
3282 static void handlePostQuote(Connection *conn, value option)
3284 CAMLparam1(option);
3285 CAMLlocal1(listIter);
3286 CURLcode result = CURLE_OK;
3288 Store_field(conn->ocamlValues, OcamlPostQuote, option);
3290 free_curl_slist(conn->postQuote);
3291 conn->postQuote = NULL;
3293 listIter = option;
3295 while (!Is_long(listIter))
3297 conn->postQuote = curl_slist_append(conn->postQuote, String_val(Field(listIter, 0)));
3299 listIter = Field(listIter, 1);
3302 result = curl_easy_setopt(conn->connection,
3303 CURLOPT_POSTQUOTE,
3304 conn->postQuote);
3306 if (result != CURLE_OK)
3307 raiseError(conn, result);
3309 CAMLreturn0;
3312 static void handleHeaderFunction(Connection *conn, value option)
3314 CAMLparam1(option);
3315 CURLcode result = CURLE_OK;
3317 if (Tag_val(option) == Closure_tag)
3318 Store_field(conn->ocamlValues, OcamlHeaderCallback, option);
3319 else
3320 failwith("Not a proper closure");
3322 result = curl_easy_setopt(conn->connection,
3323 CURLOPT_HEADERFUNCTION,
3324 headerFunction);
3326 if (result != CURLE_OK)
3327 raiseError(conn, result);
3329 result = curl_easy_setopt(conn->connection,
3330 CURLOPT_WRITEHEADER,
3331 conn);
3333 if (result != CURLE_OK)
3334 raiseError(conn, result);
3336 CAMLreturn0;
3339 static void handleCookieFile(Connection *conn, value option)
3341 CAMLparam1(option);
3342 CURLcode result = CURLE_OK;
3344 Store_field(conn->ocamlValues, OcamlCookieFile, option);
3346 if (conn->cookieFile != NULL)
3347 free(conn->cookieFile);
3349 conn->cookieFile = strdup(String_val(option));
3351 result = curl_easy_setopt(conn->connection,
3352 CURLOPT_COOKIEFILE,
3353 conn->cookieFile);
3355 if (result != CURLE_OK)
3356 raiseError(conn, result);
3358 CAMLreturn0;
3361 static void handleSSLVersion(Connection *conn, value option)
3363 CAMLparam1(option);
3364 CURLcode result = CURLE_OK;
3366 result = curl_easy_setopt(conn->connection,
3367 CURLOPT_SSLVERSION,
3368 Long_val(option));
3370 if (result != CURLE_OK)
3371 raiseError(conn, result);
3373 CAMLreturn0;
3376 static void handleTimeCondition(Connection *conn, value option)
3378 CAMLparam1(option);
3379 CURLcode result = CURLE_OK;
3381 switch (Long_val(option))
3383 case 0: /* TIMECOND_IFMODSINCE */
3384 result = curl_easy_setopt(conn->connection,
3385 CURLOPT_TIMECONDITION,
3386 CURL_TIMECOND_IFMODSINCE);
3387 break;
3389 case 1: /* TIMECOND_IFUNMODSINCE */
3390 result = curl_easy_setopt(conn->connection,
3391 CURLOPT_TIMECONDITION,
3392 CURL_TIMECOND_IFUNMODSINCE);
3393 break;
3395 default:
3396 failwith("Invalid TIMECOND Option");
3397 break;
3400 if (result != CURLE_OK)
3401 raiseError(conn, result);
3403 CAMLreturn0;
3406 static void handleTimeValue(Connection *conn, value option)
3408 CAMLparam1(option);
3409 CURLcode result = CURLE_OK;
3411 result = curl_easy_setopt(conn->connection,
3412 CURLOPT_TIMEVALUE,
3413 Int32_val(option));
3415 if (result != CURLE_OK)
3416 raiseError(conn, result);
3418 CAMLreturn0;
3421 static void handleCustomRequest(Connection *conn, value option)
3423 CAMLparam1(option);
3424 CURLcode result = CURLE_OK;
3426 Store_field(conn->ocamlValues, OcamlCustomRequest, option);
3428 if (conn->customRequest != NULL)
3429 free(conn->customRequest);
3431 conn->customRequest = strdup(String_val(option));
3433 result = curl_easy_setopt(conn->connection,
3434 CURLOPT_CUSTOMREQUEST,
3435 conn->customRequest);
3437 if (result != CURLE_OK)
3438 raiseError(conn, result);
3440 CAMLreturn0;
3443 static void handleInterface(Connection *conn, value option)
3445 CAMLparam1(option);
3446 CURLcode result = CURLE_OK;
3448 Store_field(conn->ocamlValues, OcamlInterface, option);
3450 if (conn->interface != NULL)
3451 free(conn->interface);
3453 conn->interface = strdup(String_val(option));
3455 result = curl_easy_setopt(conn->connection,
3456 CURLOPT_INTERFACE,
3457 conn->interface);
3459 if (result != CURLE_OK)
3460 raiseError(conn, result);
3462 CAMLreturn0;
3465 static void handleKRB4Level(Connection *conn, value option)
3467 CAMLparam1(option);
3468 CURLcode result = CURLE_OK;
3470 switch (Long_val(option))
3472 case 0: /* KRB4_NONE */
3473 result = curl_easy_setopt(conn->connection,
3474 CURLOPT_KRB4LEVEL,
3475 NULL);
3476 break;
3478 case 1: /* KRB4_CLEAR */
3479 result = curl_easy_setopt(conn->connection,
3480 CURLOPT_KRB4LEVEL,
3481 "clear");
3482 break;
3484 case 2: /* KRB4_SAFE */
3485 result = curl_easy_setopt(conn->connection,
3486 CURLOPT_KRB4LEVEL,
3487 "safe");
3488 break;
3490 case 3: /* KRB4_CONFIDENTIAL */
3491 result = curl_easy_setopt(conn->connection,
3492 CURLOPT_KRB4LEVEL,
3493 "confidential");
3494 break;
3496 case 4: /* KRB4_PRIVATE */
3497 result = curl_easy_setopt(conn->connection,
3498 CURLOPT_KRB4LEVEL,
3499 "private");
3500 break;
3502 default:
3503 failwith("Invalid KRB4 Option");
3504 break;
3507 if (result != CURLE_OK)
3508 raiseError(conn, result);
3510 CAMLreturn0;
3513 static void handleProgressFunction(Connection *conn, value option)
3515 CAMLparam1(option);
3516 CURLcode result = CURLE_OK;
3518 if (Tag_val(option) == Closure_tag)
3519 Store_field(conn->ocamlValues, OcamlProgressCallback, option);
3520 else
3521 failwith("Not a proper closure");
3523 result = curl_easy_setopt(conn->connection,
3524 CURLOPT_PROGRESSFUNCTION,
3525 progressFunction);
3526 if (result != CURLE_OK)
3527 raiseError(conn, result);
3529 result = curl_easy_setopt(conn->connection,
3530 CURLOPT_PROGRESSDATA,
3531 conn);
3533 if (result != CURLE_OK)
3534 raiseError(conn, result);
3536 CAMLreturn0;
3539 static void handleSSLVerifyPeer(Connection *conn, value option)
3541 CAMLparam1(option);
3542 CURLcode result = CURLE_OK;
3544 result = curl_easy_setopt(conn->connection,
3545 CURLOPT_SSL_VERIFYPEER,
3546 Bool_val(option));
3548 if (result != CURLE_OK)
3549 raiseError(conn, result);
3551 CAMLreturn0;
3554 static void handleCAInfo(Connection *conn, value option)
3556 CAMLparam1(option);
3557 CURLcode result = CURLE_OK;
3559 Store_field(conn->ocamlValues, OcamlCAInfo, option);
3561 if (conn->caInfo != NULL)
3562 free(conn->caInfo);
3564 conn->caInfo = strdup(String_val(option));
3566 result = curl_easy_setopt(conn->connection,
3567 CURLOPT_CAINFO,
3568 conn->caInfo);
3570 if (result != CURLE_OK)
3571 raiseError(conn, result);
3573 CAMLreturn0;
3576 static void handleCAPath(Connection *conn, value option)
3578 CAMLparam1(option);
3579 CURLcode result = CURLE_OK;
3581 Store_field(conn->ocamlValues, OcamlCAPath, option);
3583 if (conn->caPath != NULL)
3584 free(conn->caPath);
3586 conn->caPath = strdup(String_val(option));
3588 result = curl_easy_setopt(conn->connection,
3589 CURLOPT_CAPATH,
3590 conn->caPath);
3592 if (result != CURLE_OK)
3593 raiseError(conn, result);
3595 CAMLreturn0;
3598 static void handleFileTime(Connection *conn, value option)
3600 CAMLparam1(option);
3601 CURLcode result = CURLE_OK;
3603 result = curl_easy_setopt(conn->connection,
3604 CURLOPT_FILETIME,
3605 Bool_val(option));
3607 if (result != CURLE_OK)
3608 raiseError(conn, result);
3610 CAMLreturn0;
3613 static void handleMaxRedirs(Connection *conn, value option)
3615 CAMLparam1(option);
3616 CURLcode result = CURLE_OK;
3618 result = curl_easy_setopt(conn->connection,
3619 CURLOPT_MAXREDIRS,
3620 Long_val(option));
3622 if (result != CURLE_OK)
3623 raiseError(conn, result);
3625 CAMLreturn0;
3628 static void handleMaxConnects(Connection *conn, value option)
3630 CAMLparam1(option);
3631 CURLcode result = CURLE_OK;
3633 result = curl_easy_setopt(conn->connection,
3634 CURLOPT_MAXCONNECTS,
3635 Long_val(option));
3637 if (result != CURLE_OK)
3638 raiseError(conn, result);
3640 CAMLreturn0;
3643 static void handleClosePolicy(Connection *conn, value option)
3645 CAMLparam1(option);
3646 CURLcode result = CURLE_OK;
3648 switch (Long_val(option))
3650 case 0: /* CLOSEPOLICY_OLDEST */
3651 result = curl_easy_setopt(conn->connection,
3652 CURLOPT_CLOSEPOLICY,
3653 CURLCLOSEPOLICY_OLDEST);
3654 break;
3656 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3657 result = curl_easy_setopt(conn->connection,
3658 CURLOPT_CLOSEPOLICY,
3659 CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
3660 break;
3662 default:
3663 failwith("Invalid CLOSEPOLICY Option");
3664 break;
3667 if (result != CURLE_OK)
3668 raiseError(conn, result);
3670 CAMLreturn0;
3673 static void handleFreshConnect(Connection *conn, value option)
3675 CAMLparam1(option);
3676 CURLcode result = CURLE_OK;
3678 result = curl_easy_setopt(conn->connection,
3679 CURLOPT_FRESH_CONNECT,
3680 Bool_val(option));
3682 if (result != CURLE_OK)
3683 raiseError(conn, result);
3685 CAMLreturn0;
3688 static void handleForbidReuse(Connection *conn, value option)
3690 CAMLparam1(option);
3691 CURLcode result = CURLE_OK;
3693 result = curl_easy_setopt(conn->connection,
3694 CURLOPT_FORBID_REUSE,
3695 Bool_val(option));
3697 if (result != CURLE_OK)
3698 raiseError(conn, result);
3700 CAMLreturn0;
3703 static void handleRandomFile(Connection *conn, value option)
3705 CAMLparam1(option);
3706 CURLcode result = CURLE_OK;
3708 Store_field(conn->ocamlValues, OcamlRandomFile, option);
3710 if (conn->randomFile != NULL)
3711 free(conn->randomFile);
3713 conn->randomFile = strdup(String_val(option));
3715 result = curl_easy_setopt(conn->connection,
3716 CURLOPT_RANDOM_FILE,
3717 conn->randomFile);
3719 if (result != CURLE_OK)
3720 raiseError(conn, result);
3722 CAMLreturn0;
3725 static void handleEGDSocket(Connection *conn, value option)
3727 CAMLparam1(option);
3728 CURLcode result = CURLE_OK;
3730 Store_field(conn->ocamlValues, OcamlEGDSocket, option);
3732 if (conn->egdSocket != NULL)
3733 free(conn->egdSocket);
3735 conn->egdSocket = strdup(String_val(option));
3737 result = curl_easy_setopt(conn->connection,
3738 CURLOPT_EGDSOCKET,
3739 conn->egdSocket);
3741 if (result != CURLE_OK)
3742 raiseError(conn, result);
3744 CAMLreturn0;
3747 static void handleConnectTimeout(Connection *conn, value option)
3749 CAMLparam1(option);
3750 CURLcode result = CURLE_OK;
3752 result = curl_easy_setopt(conn->connection,
3753 CURLOPT_CONNECTTIMEOUT,
3754 Long_val(option));
3756 if (result != CURLE_OK)
3757 raiseError(conn, result);
3759 CAMLreturn0;
3762 static void handleHTTPGet(Connection *conn, value option)
3764 CAMLparam1(option);
3765 CURLcode result = CURLE_OK;
3767 result = curl_easy_setopt(conn->connection,
3768 CURLOPT_HTTPGET,
3769 Bool_val(option));
3771 if (result != CURLE_OK)
3772 raiseError(conn, result);
3774 CAMLreturn0;
3777 static void handleSSLVerifyHost(Connection *conn, value option)
3779 CAMLparam1(option);
3780 CURLcode result = CURLE_OK;
3782 switch (Long_val(option))
3784 case 0: /* SSLVERIFYHOST_NONE */
3785 case 1: /* SSLVERIFYHOST_EXISTENCE */
3786 case 2: /* SSLVERIFYHOST_HOSTNAME */
3787 result = curl_easy_setopt(conn->connection,
3788 CURLOPT_SSL_VERIFYHOST,
3789 Long_val(option));
3790 break;
3792 default:
3793 failwith("Invalid SSLVERIFYHOST Option");
3794 break;
3797 if (result != CURLE_OK)
3798 raiseError(conn, result);
3800 CAMLreturn0;
3803 static void handleCookieJar(Connection *conn, value option)
3805 CAMLparam1(option);
3806 CURLcode result = CURLE_OK;
3808 Store_field(conn->ocamlValues, OcamlCookieJar, option);
3810 if (conn->cookieJar != NULL)
3811 free(conn->cookieJar);
3813 conn->cookieJar = strdup(String_val(option));
3815 result = curl_easy_setopt(conn->connection,
3816 CURLOPT_COOKIEJAR,
3817 conn->cookieJar);
3819 if (result != CURLE_OK)
3820 raiseError(conn, result);
3822 CAMLreturn0;
3825 static void handleSSLCipherList(Connection *conn, value option)
3827 CAMLparam1(option);
3828 CURLcode result = CURLE_OK;
3830 Store_field(conn->ocamlValues, OcamlSSLCipherList, option);
3832 if (conn->sslCipherList != NULL)
3833 free(conn->sslCipherList);
3835 conn->sslCipherList = strdup(String_val(option));
3837 result = curl_easy_setopt(conn->connection,
3838 CURLOPT_SSL_CIPHER_LIST,
3839 conn->sslCipherList);
3841 if (result != CURLE_OK)
3842 raiseError(conn, result);
3844 CAMLreturn0;
3847 static void handleHTTPVersion(Connection *conn, value option)
3849 CAMLparam1(option);
3850 CURLcode result = CURLE_OK;
3852 switch (Long_val(option))
3854 case 0: /* HTTP_VERSION_NONE */
3855 result = curl_easy_setopt(conn->connection,
3856 CURLOPT_HTTP_VERSION,
3857 CURL_HTTP_VERSION_NONE);
3858 break;
3860 case 1: /* HTTP_VERSION_1_0 */
3861 result = curl_easy_setopt(conn->connection,
3862 CURLOPT_HTTP_VERSION,
3863 CURL_HTTP_VERSION_1_0);
3864 break;
3866 case 2: /* HTTP_VERSION_1_1 */
3867 result = curl_easy_setopt(conn->connection,
3868 CURLOPT_HTTP_VERSION,
3869 CURL_HTTP_VERSION_1_1);
3870 break;
3872 default:
3873 failwith("Invalid HTTP_VERSION Option");
3874 break;
3877 if (result != CURLE_OK)
3878 raiseError(conn, result);
3880 CAMLreturn0;
3883 static void handleFTPUseEPSV(Connection *conn, value option)
3885 CAMLparam1(option);
3886 CURLcode result = CURLE_OK;
3888 result = curl_easy_setopt(conn->connection,
3889 CURLOPT_FTP_USE_EPSV,
3890 Bool_val(option));
3892 if (result != CURLE_OK)
3893 raiseError(conn, result);
3895 CAMLreturn0;
3898 static void handleDNSCacheTimeout(Connection *conn, value option)
3900 CAMLparam1(option);
3901 CURLcode result = CURLE_OK;
3903 result = curl_easy_setopt(conn->connection,
3904 CURLOPT_DNS_CACHE_TIMEOUT,
3905 Long_val(option));
3907 if (result != CURLE_OK)
3908 raiseError(conn, result);
3910 CAMLreturn0;
3913 static void handleDNSUseGlobalCache(Connection *conn, value option)
3915 CAMLparam1(option);
3916 CURLcode result = CURLE_OK;
3918 result = curl_easy_setopt(conn->connection,
3919 CURLOPT_DNS_USE_GLOBAL_CACHE,
3920 Bool_val(option));
3922 if (result != CURLE_OK)
3923 raiseError(conn, result);
3925 CAMLreturn0;
3928 static void handleDebugFunction(Connection *conn, value option)
3930 CAMLparam1(option);
3931 CURLcode result = CURLE_OK;
3933 if (Tag_val(option) == Closure_tag)
3934 Store_field(conn->ocamlValues, OcamlDebugCallback, option);
3935 else
3936 failwith("Not a proper closure");
3938 result = curl_easy_setopt(conn->connection,
3939 CURLOPT_DEBUGFUNCTION,
3940 debugFunction);
3941 if (result != CURLE_OK)
3942 raiseError(conn, result);
3944 result = curl_easy_setopt(conn->connection,
3945 CURLOPT_DEBUGDATA,
3946 conn);
3948 if (result != CURLE_OK)
3949 raiseError(conn, result);
3951 CAMLreturn0;
3954 static void handlePrivate(Connection *conn, value option)
3956 #if HAVE_DECL_CURLOPT_PRIVATE
3957 CAMLparam1(option);
3958 CURLcode result = CURLE_OK;
3960 Store_field(conn->ocamlValues, OcamlPrivate, option);
3962 if (conn->private != NULL)
3963 free(conn->private);
3965 conn->private = strdup(String_val(option));
3967 result = curl_easy_setopt(conn->connection,
3968 CURLOPT_PRIVATE,
3969 conn->private);
3971 if (result != CURLE_OK)
3972 raiseError(conn, result);
3974 CAMLreturn0;
3975 #else
3976 #warning "libcurl does not implement CURLOPT_PRIVATE"
3977 failwith("libcurl does not implement CURLOPT_PRIVATE");
3978 #endif
3981 static void handleHTTP200Aliases(Connection *conn, value option)
3983 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3984 CAMLparam1(option);
3985 CAMLlocal1(listIter);
3986 CURLcode result = CURLE_OK;
3988 Store_field(conn->ocamlValues, OcamlHTTP200Aliases, option);
3990 free_curl_slist(conn->http200Aliases);
3991 conn->http200Aliases = NULL;
3993 listIter = option;
3995 while (!Is_long(listIter))
3997 conn->http200Aliases = curl_slist_append(conn->http200Aliases, String_val(Field(listIter, 0)));
3999 listIter = Field(listIter, 1);
4002 result = curl_easy_setopt(conn->connection,
4003 CURLOPT_HTTP200ALIASES,
4004 conn->http200Aliases);
4006 if (result != CURLE_OK)
4007 raiseError(conn, result);
4009 CAMLreturn0;
4010 #else
4011 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
4012 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
4013 #endif
4016 static void handleUnrestrictedAuth(Connection *conn, value option)
4018 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
4019 CAMLparam1(option);
4020 CURLcode result = CURLE_OK;
4022 result = curl_easy_setopt(conn->connection,
4023 CURLOPT_UNRESTRICTED_AUTH,
4024 Bool_val(option));
4026 if (result != CURLE_OK)
4027 raiseError(conn, result);
4029 CAMLreturn0;
4030 #else
4031 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4032 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4033 #endif
4036 static void handleFTPUseEPRT(Connection *conn, value option)
4038 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4039 CAMLparam1(option);
4040 CURLcode result = CURLE_OK;
4042 result = curl_easy_setopt(conn->connection,
4043 CURLOPT_FTP_USE_EPRT,
4044 Bool_val(option));
4046 if (result != CURLE_OK)
4047 raiseError(conn, result);
4049 CAMLreturn0;
4050 #else
4051 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4052 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4053 #endif
4056 static void handleHTTPAuth(Connection *conn, value option)
4058 #if HAVE_DECL_CURLOPT_HTTPAUTH
4059 CAMLparam1(option);
4060 CAMLlocal1(listIter);
4061 CURLcode result = CURLE_OK;
4062 long auth = CURLAUTH_NONE;
4064 listIter = option;
4066 while (!Is_long(listIter))
4068 switch (Long_val(Field(listIter, 0)))
4070 case 0: /* CURLAUTH_BASIC */
4071 auth |= CURLAUTH_BASIC;
4072 break;
4074 case 1: /* CURLAUTH_DIGEST */
4075 auth |= CURLAUTH_DIGEST;
4076 break;
4078 case 2: /* CURLAUTH_GSSNEGOTIATE */
4079 auth |= CURLAUTH_GSSNEGOTIATE;
4080 break;
4082 case 3: /* CURLAUTH_NTLM */
4083 auth |= CURLAUTH_NTLM;
4084 break;
4086 case 4: /* CURLAUTH_ANY */
4087 auth |= CURLAUTH_ANY;
4088 break;
4090 case 5: /* CURLAUTH_ANYSAFE */
4091 auth |= CURLAUTH_ANYSAFE;
4092 break;
4094 default:
4095 failwith("Invalid HTTPAUTH Value");
4096 break;
4099 listIter = Field(listIter, 1);
4102 result = curl_easy_setopt(conn->connection,
4103 CURLOPT_HTTPAUTH,
4104 auth);
4106 if (result != CURLE_OK)
4107 raiseError(conn, result);
4109 CAMLreturn0;
4110 #else
4111 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4112 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4113 #endif
4116 static void handleFTPCreateMissingDirs(Connection *conn, value option)
4118 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4119 CAMLparam1(option);
4120 CURLcode result = CURLE_OK;
4122 result = curl_easy_setopt(conn->connection,
4123 CURLOPT_FTP_CREATE_MISSING_DIRS,
4124 Bool_val(option));
4126 if (result != CURLE_OK)
4127 raiseError(conn, result);
4129 CAMLreturn0;
4130 #else
4131 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4132 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4133 #endif
4136 static void handleProxyAuth(Connection *conn, value option)
4138 #if HAVE_DECL_CURLOPT_PROXYAUTH
4139 CAMLparam1(option);
4140 CAMLlocal1(listIter);
4141 CURLcode result = CURLE_OK;
4142 long auth = CURLAUTH_NONE;
4144 listIter = option;
4146 while (!Is_long(listIter))
4148 switch (Long_val(Field(listIter, 0)))
4150 case 0: /* CURLAUTH_BASIC */
4151 auth |= CURLAUTH_BASIC;
4152 break;
4154 case 1: /* CURLAUTH_DIGEST */
4155 auth |= CURLAUTH_DIGEST;
4156 break;
4158 case 2: /* CURLAUTH_GSSNEGOTIATE */
4159 auth |= CURLAUTH_GSSNEGOTIATE;
4160 break;
4162 case 3: /* CURLAUTH_NTLM */
4163 auth |= CURLAUTH_NTLM;
4164 break;
4166 case 4: /* CURLAUTH_ANY */
4167 auth |= CURLAUTH_ANY;
4168 break;
4170 case 5: /* CURLAUTH_ANYSAFE */
4171 auth |= CURLAUTH_ANYSAFE;
4172 break;
4174 default:
4175 failwith("Invalid HTTPAUTH Value");
4176 break;
4179 listIter = Field(listIter, 1);
4182 result = curl_easy_setopt(conn->connection,
4183 CURLOPT_PROXYAUTH,
4184 auth);
4186 if (result != CURLE_OK)
4187 raiseError(conn, result);
4189 CAMLreturn0;
4190 #else
4191 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4192 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4193 #endif
4196 static void handleFTPResponseTimeout(Connection *conn, value option)
4198 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4199 CAMLparam1(option);
4200 CURLcode result = CURLE_OK;
4202 result = curl_easy_setopt(conn->connection,
4203 CURLOPT_FTP_RESPONSE_TIMEOUT,
4204 Long_val(option));
4206 if (result != CURLE_OK)
4207 raiseError(conn, result);
4209 CAMLreturn0;
4210 #else
4211 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4212 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4213 #endif
4216 static void handleIPResolve(Connection *conn, value option)
4218 #if HAVE_DECL_CURLOPT_IPRESOLVE
4219 CAMLparam1(option);
4220 CURLcode result = CURLE_OK;
4222 switch (Long_val(option))
4224 case 0: /* CURL_IPRESOLVE_WHATEVER */
4225 result = curl_easy_setopt(conn->connection,
4226 CURLOPT_IPRESOLVE,
4227 CURL_IPRESOLVE_WHATEVER);
4228 break;
4230 case 1: /* CURL_IPRESOLVE_V4 */
4231 result = curl_easy_setopt(conn->connection,
4232 CURLOPT_IPRESOLVE,
4233 CURL_IPRESOLVE_V4);
4234 break;
4236 case 2: /* CURL_IPRESOLVE_V6 */
4237 result = curl_easy_setopt(conn->connection,
4238 CURLOPT_IPRESOLVE,
4239 CURL_IPRESOLVE_V6);
4240 break;
4242 default:
4243 failwith("Invalid IPRESOLVE Value");
4244 break;
4247 if (result != CURLE_OK)
4248 raiseError(conn, result);
4250 CAMLreturn0;
4251 #else
4252 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4253 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4254 #endif
4257 static void handleMaxFileSize(Connection *conn, value option)
4259 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4260 CAMLparam1(option);
4261 CURLcode result = CURLE_OK;
4263 result = curl_easy_setopt(conn->connection,
4264 CURLOPT_MAXFILESIZE,
4265 Int32_val(option));
4267 if (result != CURLE_OK)
4268 raiseError(conn, result);
4270 CAMLreturn0;
4271 #else
4272 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4273 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4274 #endif
4277 static void handleInFileSizeLarge(Connection *conn, value option)
4279 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4280 CAMLparam1(option);
4281 CURLcode result = CURLE_OK;
4283 result = curl_easy_setopt(conn->connection,
4284 CURLOPT_INFILESIZE_LARGE,
4285 Int64_val(option));
4287 if (result != CURLE_OK)
4288 raiseError(conn, result);
4290 CAMLreturn0;
4291 #else
4292 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4293 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4294 #endif
4297 static void handleResumeFromLarge(Connection *conn, value option)
4299 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4300 CAMLparam1(option);
4301 CURLcode result = CURLE_OK;
4303 result = curl_easy_setopt(conn->connection,
4304 CURLOPT_RESUME_FROM_LARGE,
4305 Int64_val(option));
4307 if (result != CURLE_OK)
4308 raiseError(conn, result);
4310 CAMLreturn0;
4311 #else
4312 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4313 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4314 #endif
4317 static void handleMaxFileSizeLarge(Connection *conn, value option)
4319 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4320 CAMLparam1(option);
4321 CURLcode result = CURLE_OK;
4323 result = curl_easy_setopt(conn->connection,
4324 CURLOPT_MAXFILESIZE_LARGE,
4325 Int64_val(option));
4327 if (result != CURLE_OK)
4328 raiseError(conn, result);
4330 CAMLreturn0;
4331 #else
4332 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4333 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4334 #endif
4337 static void handleNETRCFile(Connection *conn, value option)
4339 #if HAVE_DECL_CURLOPT_NETRC_FILE
4340 CAMLparam1(option);
4341 CURLcode result = CURLE_OK;
4343 Store_field(conn->ocamlValues, OcamlNETRCFile, option);
4345 if (conn->netrcFile != NULL)
4346 free(conn->netrcFile);
4348 conn->netrcFile = strdup(String_val(option));
4350 result = curl_easy_setopt(conn->connection,
4351 CURLOPT_NETRC_FILE,
4352 conn->netrcFile);
4354 if (result != CURLE_OK)
4355 raiseError(conn, result);
4357 CAMLreturn0;
4358 #else
4359 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4360 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4361 #endif
4364 static void handleFTPSSL(Connection *conn, value option)
4366 #if HAVE_DECL_CURLOPT_FTP_SSL
4367 CAMLparam1(option);
4368 CURLcode result = CURLE_OK;
4370 switch (Long_val(option))
4372 case 0: /* CURLFTPSSL_NONE */
4373 result = curl_easy_setopt(conn->connection,
4374 CURLOPT_FTP_SSL,
4375 CURLFTPSSL_NONE);
4376 break;
4378 case 1: /* CURLFTPSSL_TRY */
4379 result = curl_easy_setopt(conn->connection,
4380 CURLOPT_FTP_SSL,
4381 CURLFTPSSL_TRY);
4382 break;
4384 case 2: /* CURLFTPSSL_CONTROL */
4385 result = curl_easy_setopt(conn->connection,
4386 CURLOPT_FTP_SSL,
4387 CURLFTPSSL_CONTROL);
4388 break;
4390 case 3: /* CURLFTPSSL_ALL */
4391 result = curl_easy_setopt(conn->connection,
4392 CURLOPT_FTP_SSL,
4393 CURLFTPSSL_ALL);
4394 break;
4396 default:
4397 failwith("Invalid FTP_SSL Value");
4398 break;
4401 if (result != CURLE_OK)
4402 raiseError(conn, result);
4404 CAMLreturn0;
4405 #else
4406 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4407 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4408 #endif
4411 static void handlePostFieldSizeLarge(Connection *conn, value option)
4413 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4414 CAMLparam1(option);
4415 CURLcode result = CURLE_OK;
4417 result = curl_easy_setopt(conn->connection,
4418 CURLOPT_POSTFIELDSIZE_LARGE,
4419 Int64_val(option));
4421 if (result != CURLE_OK)
4422 raiseError(conn, result);
4424 CAMLreturn0;
4425 #else
4426 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4427 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4428 #endif
4431 static void handleTCPNoDelay(Connection *conn, value option)
4433 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4434 CAMLparam1(option);
4435 CURLcode result = CURLE_OK;
4437 result = curl_easy_setopt(conn->connection,
4438 CURLOPT_TCP_NODELAY,
4439 Bool_val(option));
4441 if (result != CURLE_OK)
4442 raiseError(conn, result);
4444 CAMLreturn0;
4445 #else
4446 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4447 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4448 #endif
4451 static void handleFTPSSLAuth(Connection *conn, value option)
4453 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4454 CAMLparam1(option);
4455 CURLcode result = CURLE_OK;
4457 switch (Long_val(option))
4459 case 0: /* CURLFTPAUTH_DEFAULT */
4460 result = curl_easy_setopt(conn->connection,
4461 CURLOPT_FTPSSLAUTH,
4462 CURLFTPAUTH_DEFAULT);
4463 break;
4465 case 1: /* CURLFTPAUTH_SSL */
4466 result = curl_easy_setopt(conn->connection,
4467 CURLOPT_FTPSSLAUTH,
4468 CURLFTPAUTH_SSL);
4469 break;
4471 case 2: /* CURLFTPAUTH_TLS */
4472 result = curl_easy_setopt(conn->connection,
4473 CURLOPT_FTPSSLAUTH,
4474 CURLFTPAUTH_TLS);
4475 break;
4477 default:
4478 failwith("Invalid FTPSSLAUTH value");
4479 break;
4482 if (result != CURLE_OK)
4483 raiseError(conn, result);
4485 CAMLreturn0;
4486 #else
4487 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4488 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4489 #endif
4492 static void handleIOCTLFunction(Connection *conn, value option)
4494 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4495 CAMLparam1(option);
4496 CURLcode result = CURLE_OK;
4498 if (Tag_val(option) == Closure_tag)
4499 Store_field(conn->ocamlValues, OcamlIOCTLCallback, option);
4500 else
4501 failwith("Not a proper closure");
4503 result = curl_easy_setopt(conn->connection,
4504 CURLOPT_IOCTLFUNCTION,
4505 ioctlFunction);
4506 if (result != CURLE_OK)
4507 raiseError(conn, result);
4509 result = curl_easy_setopt(conn->connection,
4510 CURLOPT_DEBUGDATA,
4511 conn);
4513 if (result != CURLE_OK)
4514 raiseError(conn, result);
4516 CAMLreturn0;
4517 #else
4518 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4519 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4520 #endif
4523 static void handleFTPAccount(Connection *conn, value option)
4525 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4526 CAMLparam1(option);
4527 CURLcode result = CURLE_OK;
4529 Store_field(conn->ocamlValues, OcamlFTPAccount, option);
4531 if (conn->ftpaccount != NULL)
4532 free(conn->ftpaccount);
4534 conn->ftpaccount = strdup(String_val(option));
4536 result = curl_easy_setopt(conn->connection,
4537 CURLOPT_FTP_ACCOUNT,
4538 conn->ftpaccount);
4540 if (result != CURLE_OK)
4541 raiseError(conn, result);
4543 CAMLreturn0;
4544 #else
4545 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4546 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4547 #endif
4550 static void handleCookieList(Connection *conn, value option)
4552 #if HAVE_DECL_CURLOPT_COOKIELIST
4553 CAMLparam1(option);
4554 CURLcode result = CURLE_OK;
4556 Store_field(conn->ocamlValues, OcamlCookieList, option);
4558 if (conn->cookielist != NULL)
4559 free(conn->cookielist);
4561 conn->cookielist = strdup(String_val(option));
4563 result = curl_easy_setopt(conn->connection,
4564 CURLOPT_COOKIELIST,
4565 conn->cookielist);
4567 if (result != CURLE_OK)
4568 raiseError(conn, result);
4570 CAMLreturn0;
4571 #else
4572 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4573 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4574 #endif
4577 static void handleIgnoreContentLength(Connection *conn, value option)
4579 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4580 CAMLparam1(option);
4581 CURLcode result = CURLE_OK;
4583 result = curl_easy_setopt(conn->connection,
4584 CURLOPT_IGNORE_CONTENT_LENGTH,
4585 Bool_val(option));
4587 if (result != CURLE_OK)
4588 raiseError(conn, result);
4590 CAMLreturn0;
4591 #else
4592 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4593 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4594 #endif
4597 static void handleFTPSkipPASVIP(Connection *conn, value option)
4599 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4600 CAMLparam1(option);
4601 CURLcode result = CURLE_OK;
4603 result = curl_easy_setopt(conn->connection,
4604 CURLOPT_FTP_SKIP_PASV_IP,
4605 Bool_val(option));
4607 if (result != CURLE_OK)
4608 raiseError(conn, result);
4610 CAMLreturn0;
4611 #else
4612 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4613 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4614 #endif
4617 static void handleFTPFileMethod(Connection *conn, value option)
4619 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4620 CAMLparam1(option);
4621 CURLcode result = CURLE_OK;
4623 switch (Long_val(option))
4625 case 0: /* CURLFTPMETHOD_DEFAULT */
4626 result = curl_easy_setopt(conn->connection,
4627 CURLOPT_FTP_FILEMETHOD,
4628 CURLFTPMETHOD_DEFAULT);
4629 break;
4631 case 1: /* CURLFTMETHOD_MULTICWD */
4632 result = curl_easy_setopt(conn->connection,
4633 CURLOPT_FTP_FILEMETHOD,
4634 CURLFTPMETHOD_MULTICWD);
4635 break;
4637 case 2: /* CURLFTPMETHOD_NOCWD */
4638 result = curl_easy_setopt(conn->connection,
4639 CURLOPT_FTP_FILEMETHOD,
4640 CURLFTPMETHOD_NOCWD);
4641 break;
4643 case 3: /* CURLFTPMETHOD_SINGLECWD */
4644 result = curl_easy_setopt(conn->connection,
4645 CURLOPT_FTP_FILEMETHOD,
4646 CURLFTPMETHOD_SINGLECWD);
4648 default:
4649 failwith("Invalid FTP_FILEMETHOD value");
4650 break;
4653 if (result != CURLE_OK)
4654 raiseError(conn, result);
4656 CAMLreturn0;
4657 #else
4658 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4659 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4660 #endif
4663 static void handleLocalPort(Connection *conn, value option)
4665 #if HAVE_DECL_CURLOPT_LOCALPORT
4666 CAMLparam1(option);
4667 CURLcode result = CURLE_OK;
4669 result = curl_easy_setopt(conn->connection,
4670 CURLOPT_LOCALPORT,
4671 Long_val(option));
4673 if (result != CURLE_OK)
4674 raiseError(conn, result);
4676 CAMLreturn0;
4677 #else
4678 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4679 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4680 #endif
4683 static void handleLocalPortRange(Connection *conn, value option)
4685 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4686 CAMLparam1(option);
4687 CURLcode result = CURLE_OK;
4689 result = curl_easy_setopt(conn->connection,
4690 CURLOPT_LOCALPORTRANGE,
4691 Long_val(option));
4693 if (result != CURLE_OK)
4694 raiseError(conn, result);
4696 CAMLreturn0;
4697 #else
4698 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4699 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4700 #endif
4703 static void handleConnectOnly(Connection *conn, value option)
4705 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4706 CAMLparam1(option);
4707 CURLcode result = CURLE_OK;
4709 result = curl_easy_setopt(conn->connection,
4710 CURLOPT_CONNECT_ONLY,
4711 Bool_val(option));
4713 if (result != CURLE_OK)
4714 raiseError(conn, result);
4716 CAMLreturn0;
4717 #else
4718 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4719 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4720 #endif
4723 static void handleMaxSendSpeedLarge(Connection *conn, value option)
4725 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4726 CAMLparam1(option);
4727 CURLcode result = CURLE_OK;
4729 result = curl_easy_setopt(conn->connection,
4730 CURLOPT_MAX_SEND_SPEED_LARGE,
4731 Int64_val(option));
4733 if (result != CURLE_OK)
4734 raiseError(conn, result);
4736 CAMLreturn0;
4737 #else
4738 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4739 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4740 #endif
4743 static void handleMaxRecvSpeedLarge(Connection *conn, value option)
4745 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4746 CAMLparam1(option);
4747 CURLcode result = CURLE_OK;
4749 result = curl_easy_setopt(conn->connection,
4750 CURLOPT_MAX_RECV_SPEED_LARGE,
4751 Int64_val(option));
4753 if (result != CURLE_OK)
4754 raiseError(conn, result);
4756 CAMLreturn0;
4757 #else
4758 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4759 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4760 #endif
4763 static void handleFTPAlternativeToUser(Connection *conn, value option)
4765 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4766 CAMLparam1(option);
4767 CURLcode result = CURLE_OK;
4769 Store_field(conn->ocamlValues, OcamlFTPAlternativeToUser, option);
4771 if (conn->ftpAlternativeToUser != NULL)
4772 free(conn->ftpAlternativeToUser);
4774 conn->ftpAlternativeToUser = strdup(String_val(option));
4776 result = curl_easy_setopt(conn->connection,
4777 CURLOPT_FTP_ALTERNATIVE_TO_USER,
4778 conn->ftpAlternativeToUser);
4780 if (result != CURLE_OK)
4781 raiseError(conn, result);
4783 CAMLreturn0;
4784 #else
4785 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4786 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4787 #endif
4790 static void handleSSLSessionIdCache(Connection *conn, value option)
4792 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4793 CAMLparam1(option);
4794 CURLcode result = CURLE_OK;
4796 result = curl_easy_setopt(conn->connection,
4797 CURLOPT_SSL_SESSIONID_CACHE,
4798 Bool_val(option));
4800 if (result != CURLE_OK)
4801 raiseError(conn, result);
4803 CAMLreturn0;
4804 #else
4805 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4806 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4807 #endif
4810 static void handleSSHAuthTypes(Connection *conn, value option)
4812 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4813 CAMLparam1(option);
4814 CAMLlocal1(listIter);
4815 CURLcode result = CURLE_OK;
4816 long authTypes = CURLSSH_AUTH_NONE;
4818 listIter = option;
4820 while (!Is_long(listIter))
4822 switch (Long_val(Field(listIter, 0)))
4824 case 0: /* CURLSSH_AUTH_ANY */
4825 authTypes |= CURLSSH_AUTH_ANY;
4826 break;
4828 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4829 authTypes |= CURLSSH_AUTH_PUBLICKEY;
4830 break;
4832 case 2: /* CURLSSH_AUTH_PASSWORD */
4833 authTypes |= CURLSSH_AUTH_PASSWORD;
4834 break;
4836 case 3: /* CURLSSH_AUTH_HOST */
4837 authTypes |= CURLSSH_AUTH_HOST;
4838 break;
4840 case 4: /* CURLSSH_AUTH_KEYBOARD */
4841 authTypes |= CURLSSH_AUTH_KEYBOARD;
4842 break;
4844 default:
4845 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4846 break;
4849 listIter = Field(listIter, 1);
4852 result = curl_easy_setopt(conn->connection,
4853 CURLOPT_SSH_AUTH_TYPES,
4854 authTypes);
4856 if (result != CURLE_OK)
4857 raiseError(conn, result);
4859 CAMLreturn0;
4860 #else
4861 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4862 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4863 #endif
4866 static void handleSSHPublicKeyFile(Connection *conn, value option)
4868 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4869 CAMLparam1(option);
4870 CURLcode result = CURLE_OK;
4872 Store_field(conn->ocamlValues, OcamlSSHPublicKeyFile, option);
4874 if (conn->sshPublicKeyFile != NULL)
4875 free(conn->sshPublicKeyFile);
4877 conn->sshPublicKeyFile = strdup(String_val(option));
4879 result = curl_easy_setopt(conn->connection,
4880 CURLOPT_SSH_PUBLIC_KEYFILE,
4881 conn->sshPublicKeyFile);
4883 if (result != CURLE_OK)
4884 raiseError(conn, result);
4886 CAMLreturn0;
4887 #else
4888 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4889 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4890 #endif
4893 static void handleSSHPrivateKeyFile(Connection *conn, value option)
4895 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4896 CAMLparam1(option);
4897 CURLcode result = CURLE_OK;
4899 Store_field(conn->ocamlValues, OcamlSSHPrivateKeyFile, option);
4901 if (conn->sshPrivateKeyFile != NULL)
4902 free(conn->sshPrivateKeyFile);
4904 conn->sshPrivateKeyFile = strdup(String_val(option));
4906 result = curl_easy_setopt(conn->connection,
4907 CURLOPT_SSH_PRIVATE_KEYFILE,
4908 conn->sshPrivateKeyFile);
4910 if (result != CURLE_OK)
4911 raiseError(conn, result);
4913 CAMLreturn0;
4914 #else
4915 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4916 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4917 #endif
4920 static void handleFTPSSLCCC(Connection *conn, value option)
4922 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4923 CAMLparam1(option);
4924 CURLcode result = CURLE_OK;
4926 switch (Long_val(option))
4928 case 0: /* CURLFTPSSL_CCC_NONE */
4929 result = curl_easy_setopt(conn->connection,
4930 CURLOPT_FTP_SSL_CCC,
4931 CURLFTPSSL_CCC_NONE);
4932 break;
4934 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4935 result = curl_easy_setopt(conn->connection,
4936 CURLOPT_FTP_SSL_CCC,
4937 CURLFTPSSL_CCC_PASSIVE);
4938 break;
4940 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4941 result = curl_easy_setopt(conn->connection,
4942 CURLOPT_FTP_SSL_CCC,
4943 CURLFTPSSL_CCC_ACTIVE);
4944 break;
4946 default:
4947 failwith("Invalid FTPSSL_CCC value");
4948 break;
4951 if (result != CURLE_OK)
4952 raiseError(conn, result);
4954 CAMLreturn0;
4955 #else
4956 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4957 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4958 #endif
4961 static void handleTimeoutMS(Connection *conn, value option)
4963 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4964 CAMLparam1(option);
4965 CURLcode result = CURLE_OK;
4967 result = curl_easy_setopt(conn->connection,
4968 CURLOPT_TIMEOUT_MS,
4969 Long_val(option));
4971 if (result != CURLE_OK)
4972 raiseError(conn, result);
4974 CAMLreturn0;
4975 #else
4976 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4977 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4978 #endif
4981 static void handleConnectTimeoutMS(Connection *conn, value option)
4983 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4984 CAMLparam1(option);
4985 CURLcode result = CURLE_OK;
4987 result = curl_easy_setopt(conn->connection,
4988 CURLOPT_CONNECTTIMEOUT_MS,
4989 Long_val(option));
4991 if (result != CURLE_OK)
4992 raiseError(conn, result);
4994 CAMLreturn0;
4995 #else
4996 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4997 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
4998 #endif
5001 static void handleHTTPTransferDecoding(Connection *conn, value option)
5003 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
5004 CAMLparam1(option);
5005 CURLcode result = CURLE_OK;
5007 result = curl_easy_setopt(conn->connection,
5008 CURLOPT_HTTP_TRANSFER_DECODING,
5009 Bool_val(option));
5011 if (result != CURLE_OK)
5012 raiseError(conn, result);
5014 CAMLreturn0;
5015 #else
5016 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
5017 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
5018 #endif
5021 static void handleHTTPContentDecoding(Connection *conn, value option)
5023 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
5024 CAMLparam1(option);
5025 CURLcode result = CURLE_OK;
5027 result = curl_easy_setopt(conn->connection,
5028 CURLOPT_HTTP_CONTENT_DECODING,
5029 Bool_val(option));
5031 if (result != CURLE_OK)
5032 raiseError(conn, result);
5034 CAMLreturn0;
5035 #else
5036 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5037 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5038 #endif
5041 static void handleNewFilePerms(Connection *conn, value option)
5043 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5044 CAMLparam1(option);
5045 CURLcode result = CURLE_OK;
5047 result = curl_easy_setopt(conn->connection,
5048 CURLOPT_NEW_FILE_PERMS,
5049 Long_val(option));
5051 if (result != CURLE_OK)
5052 raiseError(conn, result);
5054 CAMLreturn0;
5055 #else
5056 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5057 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5058 #endif
5061 static void handleNewDirectoryPerms(Connection *conn, value option)
5063 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5064 CAMLparam1(option);
5065 CURLcode result = CURLE_OK;
5067 result = curl_easy_setopt(conn->connection,
5068 CURLOPT_NEW_DIRECTORY_PERMS,
5069 Long_val(option));
5071 if (result != CURLE_OK)
5072 raiseError(conn, result);
5074 CAMLreturn0;
5075 #else
5076 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5077 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5078 #endif
5081 static void handlePost301(Connection *conn, value option)
5083 #if HAVE_DECL_CURLOPT_POST301
5084 CAMLparam1(option);
5085 CURLcode result = CURLE_OK;
5087 result = curl_easy_setopt(conn->connection,
5088 CURLOPT_POST301,
5089 Bool_val(option));
5091 if (result != CURLE_OK)
5092 raiseError(conn, result);
5094 CAMLreturn0;
5095 #else
5096 #warning "libcurl does not implement CURLOPT_POST301"
5097 failwith("libcurl does not implement CURLOPT_POST301");
5098 #endif
5101 static void handleSSHHostPublicKeyMD5(Connection *conn, value option)
5103 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5104 CAMLparam1(option);
5105 CURLcode result = CURLE_OK;
5107 Store_field(conn->ocamlValues, OcamlSSHHostPublicKeyMD5, option);
5109 if (conn->sshHostPublicKeyMD5 != NULL)
5110 free(conn->sshHostPublicKeyMD5);
5112 conn->sshHostPublicKeyMD5 = strdup(String_val(option));
5114 result = curl_easy_setopt(conn->connection,
5115 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
5116 conn->sshHostPublicKeyMD5);
5118 if (result != CURLE_OK)
5119 raiseError(conn, result);
5121 CAMLreturn0;
5122 #else
5123 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5124 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5125 #endif
5128 static void handleCopyPostFields(Connection *conn, value option)
5130 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5131 CAMLparam1(option);
5132 CURLcode result = CURLE_OK;
5134 Store_field(conn->ocamlValues, OcamlCopyPostFields, option);
5136 if (conn->copyPostFields != NULL)
5137 free(conn->copyPostFields);
5139 conn->copyPostFields = strdup(String_val(option));
5141 result = curl_easy_setopt(conn->connection,
5142 CURLOPT_COPYPOSTFIELDS,
5143 conn->copyPostFields);
5145 if (result != CURLE_OK)
5146 raiseError(conn, result);
5148 CAMLreturn0;
5149 #else
5150 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5151 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5152 #endif
5155 static void handleProxyTransferMode(Connection *conn, value option)
5157 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5158 CAMLparam1(option);
5159 CURLcode result = CURLE_OK;
5161 result = curl_easy_setopt(conn->connection,
5162 CURLOPT_PROXY_TRANSFER_MODE,
5163 Bool_val(option));
5165 if (result != CURLE_OK)
5166 raiseError(conn, result);
5168 CAMLreturn0;
5169 #else
5170 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5171 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5172 #endif
5175 static void handleSeekFunction(Connection *conn, value option)
5177 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5178 CAMLparam1(option);
5179 CURLcode result = CURLE_OK;
5181 if (Tag_val(option) == Closure_tag)
5182 Store_field(conn->ocamlValues, OcamlSeekFunctionCallback, option);
5183 else
5184 failwith("Not a proper closure");
5186 result = curl_easy_setopt(conn->connection,
5187 CURLOPT_SEEKFUNCTION,
5188 seekFunction);
5190 if (result != CURLE_OK)
5191 raiseError(conn, result);
5193 result = curl_easy_setopt(conn->connection,
5194 CURLOPT_SEEKDATA,
5195 conn);
5197 if (result != CURLE_OK)
5198 raiseError(conn, result);
5200 CAMLreturn0;
5201 #else
5202 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5203 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5204 #endif
5207 static void handleAutoReferer(Connection *conn, value option)
5209 #if HAVE_DECL_CURLOPT_AUTOREFERER
5210 CAMLparam1(option);
5211 CURLcode result = curl_easy_setopt(conn->connection,
5212 CURLOPT_AUTOREFERER,
5213 Bool_val(option));
5215 if (result != CURLE_OK)
5216 raiseError(conn, result);
5218 CAMLreturn0;
5219 #else
5220 #warning "libcurl does not implement CURLOPT_AUTOREFERER"
5221 failwith("libcurl does not implement CURLOPT_AUTOREFERER");
5222 #endif
5225 static void handleOpenSocketFunction(Connection *conn, value option)
5227 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
5228 CAMLparam1(option);
5229 CURLcode result = CURLE_OK;
5231 Store_field(conn->ocamlValues, OcamlOpenSocketFunctionCallback, option);
5233 result = curl_easy_setopt(conn->connection,
5234 CURLOPT_OPENSOCKETDATA,
5235 conn);
5237 if (result != CURLE_OK)
5238 raiseError(conn, result);
5240 result = curl_easy_setopt(conn->connection,
5241 CURLOPT_OPENSOCKETFUNCTION,
5242 openSocketFunction);
5244 if (result != CURLE_OK)
5245 raiseError(conn, result);
5247 CAMLreturn0;
5248 #else
5249 #warning "libcurl does not implement CURLOPT_OPENSOCKETFUNCTION"
5250 failwith("libcurl does not implement CURLOPT_OPENSOCKETFUNCTION");
5251 #endif
5254 static void handleProxyType(Connection *conn, value option)
5256 #if HAVE_DECL_CURLOPT_PROXYTYPE
5257 CAMLparam1(option);
5258 CURLcode result = CURLE_OK;
5259 long proxy_type;
5261 switch (Long_val(option))
5263 case 0: proxy_type = CURLPROXY_HTTP; break;
5264 case 1: proxy_type = CURLPROXY_HTTP_1_0; break;
5265 case 2: proxy_type = CURLPROXY_SOCKS4; break;
5266 case 3: proxy_type = CURLPROXY_SOCKS5; break;
5267 case 4: proxy_type = CURLPROXY_SOCKS4A; break;
5268 case 5: proxy_type = CURLPROXY_SOCKS5_HOSTNAME; break;
5269 default:
5270 failwith("Invalid curl proxy type");
5273 result = curl_easy_setopt(conn->connection,
5274 CURLOPT_PROXYTYPE,
5275 proxy_type);
5277 if (result != CURLE_OK)
5278 raiseError(conn, result);
5280 CAMLreturn0;
5281 #else
5282 #warning "libcurl does not implement CURLOPT_PROXYTYPE"
5283 failwith("libcurl does not implement CURLOPT_PROXYTYPE");
5284 #endif
5287 #if HAVE_DECL_CURLOPT_PROTOCOLS && HAVE_DECL_CURLOPT_REDIR_PROTOCOLS
5289 long protoMap[] =
5291 CURLPROTO_ALL,
5292 CURLPROTO_HTTP, CURLPROTO_HTTPS, CURLPROTO_FTP, CURLPROTO_FTPS, CURLPROTO_SCP, CURLPROTO_SFTP,
5293 CURLPROTO_TELNET, CURLPROTO_LDAP, CURLPROTO_LDAPS, CURLPROTO_DICT, CURLPROTO_FILE, CURLPROTO_TFTP,
5294 /* factor out with autoconf? */
5295 #if defined(CURLPROTO_IMAP)
5296 CURLPROTO_IMAP,
5297 #else
5299 #endif
5300 #if defined(CURLPROTO_IMAPS)
5301 CURLPROTO_IMAPS,
5302 #else
5304 #endif
5305 #if defined(CURLPROTO_POP3)
5306 CURLPROTO_POP3,
5307 #else
5309 #endif
5310 #if defined(CURLPROTO_POP3S)
5311 CURLPROTO_POP3S,
5312 #else
5314 #endif
5315 #if defined(CURLPROTO_SMTP)
5316 CURLPROTO_SMTP,
5317 #else
5319 #endif
5320 #if defined(CURLPROTO_SMTPS)
5321 CURLPROTO_SMTPS,
5322 #else
5324 #endif
5325 #if defined(CURLPROTO_RTSP)
5326 CURLPROTO_RTSP,
5327 #else
5329 #endif
5330 #if defined(CURLPROTO_RTMP)
5331 CURLPROTO_RTMP,
5332 #else
5334 #endif
5335 #if defined(CURLPROTO_RTMPT)
5336 CURLPROTO_RTMPT,
5337 #else
5339 #endif
5340 #if defined(CURLPROTO_RTMPE)
5341 CURLPROTO_RTMPE,
5342 #else
5344 #endif
5345 #if defined(CURLPROTO_RTMPTE)
5346 CURLPROTO_RTMPTE,
5347 #else
5349 #endif
5350 #if defined(CURLPROTO_RTMPS)
5351 CURLPROTO_RTMPS,
5352 #else
5354 #endif
5355 #if defined(CURLPROTO_RTMPTS)
5356 CURLPROTO_RTMPTS,
5357 #else
5359 #endif
5360 #if defined(CURLPROTO_GOPHER)
5361 CURLPROTO_GOPHER,
5362 #else
5364 #endif
5367 static void handleProtocolsOption(CURLoption curlopt, Connection *conn, value option)
5369 CAMLparam1(option);
5370 CURLcode result = CURLE_OK;
5371 long protocols = 0;
5372 int index;
5374 while (Val_emptylist != option)
5376 index = Int_val(Field(option, 0));
5377 if ((index < 0) || (index >= sizeof(protoMap) / sizeof(protoMap[0])))
5378 failwith("Invalid curl protocol");
5380 protocols = protocols | protoMap[index];
5382 option = Field(option, 1);
5385 result = curl_easy_setopt(conn->connection,
5386 curlopt,
5387 protocols);
5389 if (result != CURLE_OK)
5390 raiseError(conn, result);
5392 CAMLreturn0;
5395 static void handleProtocols(Connection *conn, value option)
5397 handleProtocolsOption(CURLOPT_PROTOCOLS, conn, option);
5400 static void handleRedirProtocols(Connection *conn, value option)
5402 handleProtocolsOption(CURLOPT_REDIR_PROTOCOLS, conn, option);
5405 #else
5406 #warning "libcurl does not implement CURLOPT_PROTOCOLS or CURLOPT_REDIR_PROTOCOLS"
5407 static void handleProtocols(Connection *conn, value option)
5409 failwith("libcurl does not implement CURLOPT_PROTOCOLS");
5411 static void handleRedirProtocols(Connection *conn, value option)
5413 failwith("libcurl does not implement CURLOPT_REDIR_PROTOCOLS");
5415 #endif
5417 #ifdef HAVE_DECL_CURLOPT_RESOLVE
5418 static void handleResolve(Connection *conn, value option)
5420 CAMLparam1(option);
5421 CAMLlocal1(head);
5424 free_curl_slist(conn->resolve);
5425 conn->resolve = NULL;
5427 CURLcode result = CURLE_OK;
5429 head = option;
5431 while (head != Val_emptylist)
5433 conn->resolve = curl_slist_append(conn->resolve, String_val(Field(head,0)));
5434 head = Field(head, 1);
5437 result = curl_easy_setopt(conn->connection,
5438 CURLOPT_RESOLVE,
5439 conn->resolve);
5441 if (result != CURLE_OK)
5442 raiseError(conn, result);
5444 CAMLreturn0;
5447 #else
5448 #warning "libcurl does not implement CURLOPT_RESOLVE"
5449 static void handleResolve(Connection *conn, value option)
5451 failwith("libcurl does not implement CURLOPT_RESOLVE");
5453 #endif
5455 #ifdef HAVE_DECL_CURLOPT_DNS_SERVERS
5456 static void handleDnsServers(Connection *conn, value option)
5458 CAMLparam1(option);
5460 CURLcode result = CURLE_OK;
5461 free_if(conn->dns_servers);
5463 conn->dns_servers = strdup(String_val(option));
5465 result = curl_easy_setopt(conn->connection,
5466 CURLOPT_DNS_SERVERS,
5467 conn->dns_servers);
5469 if (result != CURLE_OK)
5470 raiseError(conn, result);
5472 CAMLreturn0;
5474 #else
5475 #warning "libcurl does not implement CURLOPT_DNS_SERVERS"
5476 static void handleDnsServers(Connection *conn, value option)
5478 failwith("libcurl does not implement CURLOPT_DNS_SERVERS");
5480 #endif
5483 ** curl_easy_setopt helper function
5486 CAMLprim value helper_curl_easy_setopt(value conn, value option)
5488 CAMLparam2(conn, option);
5489 CAMLlocal1(data);
5490 Connection *connection = Connection_val(conn);
5492 checkConnection(connection);
5494 if (Is_long(option))
5496 char error[128];
5498 sprintf(error, "Unimplemented Option: %s",
5499 findOption(unimplementedOptionMap,
5500 (CURLoption)(Long_val(option))));
5502 failwith(error);
5505 if (!Is_block(option))
5506 failwith("Not a block");
5508 if (Wosize_val(option) < 1)
5509 failwith("Insufficient data in block");
5511 data = Field(option, 0);
5513 if (Tag_val(option) < sizeof(implementedOptionMap)/sizeof(CURLOptionMapping))
5514 (*implementedOptionMap[Tag_val(option)].optionHandler)(connection,
5515 data);
5516 else
5517 failwith("Invalid CURLOPT Option");
5519 CAMLreturn(Val_unit);
5523 ** curl_easy_perform helper function
5526 CAMLprim value helper_curl_easy_perform(value conn)
5528 CAMLparam1(conn);
5529 CURLcode result = CURLE_OK;
5530 Connection *connection = Connection_val(conn);
5532 checkConnection(connection);
5534 enter_blocking_section();
5535 result = curl_easy_perform(connection->connection);
5536 leave_blocking_section();
5538 if (result != CURLE_OK)
5539 raiseError(connection, result);
5541 CAMLreturn(Val_unit);
5545 ** curl_easy_cleanup helper function
5548 CAMLprim value helper_curl_easy_cleanup(value conn)
5550 CAMLparam1(conn);
5551 Connection *connection = Connection_val(conn);
5553 checkConnection(connection);
5555 removeConnection(connection);
5557 CAMLreturn(Val_unit);
5561 ** curl_easy_duphandle helper function
5564 CAMLprim value helper_curl_easy_duphandle(value conn)
5566 CAMLparam1(conn);
5567 CAMLlocal1(result);
5568 Connection *connection = Connection_val(conn);
5570 checkConnection(connection);
5572 result = caml_alloc(1, Abstract_tag);
5573 Field(result, 0) = (value)duplicateConnection(connection);
5575 CAMLreturn(result);
5579 ** curl_easy_getinfo helper function
5582 enum GetInfoResultType {
5583 StringValue, LongValue, DoubleValue, StringListValue
5586 value convertStringList(struct curl_slist *slist)
5588 CAMLparam0();
5589 CAMLlocal3(result, current, next);
5590 struct curl_slist *p = slist;
5592 result = Val_int(0);
5593 current = Val_int(0);
5594 next = Val_int(0);
5596 while (p != NULL)
5598 next = alloc_tuple(2);
5599 Store_field(next, 0, copy_string(p->data));
5600 Store_field(next, 1, Val_int(0));
5602 if (result == Val_int(0))
5603 result = next;
5605 if (current != Val_int(0))
5606 Store_field(current, 1, next);
5608 current = next;
5610 p = p->next;
5613 curl_slist_free_all(slist);
5615 CAMLreturn(result);
5618 CAMLprim value helper_curl_easy_getinfo(value conn, value option)
5620 CAMLparam2(conn, option);
5621 CAMLlocal1(result);
5622 CURLcode curlResult;
5623 Connection *connection = Connection_val(conn);
5624 enum GetInfoResultType resultType;
5625 char *strValue = NULL;
5626 double doubleValue;
5627 long longValue;
5628 struct curl_slist *stringListValue = NULL;
5630 checkConnection(connection);
5632 switch(Long_val(option))
5634 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5635 case 0: /* CURLINFO_EFFECTIVE_URL */
5636 resultType = StringValue;
5638 curlResult = curl_easy_getinfo(connection->connection,
5639 CURLINFO_EFFECTIVE_URL,
5640 &strValue);
5641 break;
5642 #else
5643 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5644 #endif
5646 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5647 case 1: /* CURLINFO_HTTP_CODE */
5648 case 2: /* CURLINFO_RESPONSE_CODE */
5649 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5650 resultType = LongValue;
5652 curlResult = curl_easy_getinfo(connection->connection,
5653 CURLINFO_RESPONSE_CODE,
5654 &longValue);
5655 #else
5656 resultType = LongValue;
5658 curlResult = curl_easy_getinfo(connection->connection,
5659 CURLINFO_HTTP_CODE,
5660 &longValue);
5661 #endif
5662 break;
5663 #endif
5665 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5666 case 3: /* CURLINFO_TOTAL_TIME */
5667 resultType = DoubleValue;
5669 curlResult = curl_easy_getinfo(connection->connection,
5670 CURLINFO_TOTAL_TIME,
5671 &doubleValue);
5672 break;
5673 #endif
5675 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5676 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5677 resultType = DoubleValue;
5679 curlResult = curl_easy_getinfo(connection->connection,
5680 CURLINFO_NAMELOOKUP_TIME,
5681 &doubleValue);
5682 break;
5683 #endif
5685 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5686 case 5: /* CURLINFO_CONNECT_TIME */
5687 resultType = DoubleValue;
5689 curlResult = curl_easy_getinfo(connection->connection,
5690 CURLINFO_CONNECT_TIME,
5691 &doubleValue);
5692 break;
5693 #endif
5695 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5696 case 6: /* CURLINFO_PRETRANSFER_TIME */
5697 resultType = DoubleValue;
5699 curlResult = curl_easy_getinfo(connection->connection,
5700 CURLINFO_PRETRANSFER_TIME,
5701 &doubleValue);
5702 break;
5703 #endif
5705 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5706 case 7: /* CURLINFO_SIZE_UPLOAD */
5707 resultType = DoubleValue;
5709 curlResult = curl_easy_getinfo(connection->connection,
5710 CURLINFO_SIZE_UPLOAD,
5711 &doubleValue);
5712 break;
5713 #endif
5715 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5716 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5717 resultType = DoubleValue;
5719 curlResult = curl_easy_getinfo(connection->connection,
5720 CURLINFO_SIZE_DOWNLOAD,
5721 &doubleValue);
5722 break;
5723 #endif
5725 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5726 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5727 resultType = DoubleValue;
5729 curlResult = curl_easy_getinfo(connection->connection,
5730 CURLINFO_SPEED_DOWNLOAD,
5731 &doubleValue);
5732 break;
5733 #endif
5735 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5736 case 10: /* CURLINFO_SPEED_UPLOAD */
5737 resultType = DoubleValue;
5739 curlResult = curl_easy_getinfo(connection->connection,
5740 CURLINFO_SPEED_UPLOAD,
5741 &doubleValue);
5742 break;
5744 #endif
5746 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5747 case 11: /* CURLINFO_HEADER_SIZE */
5748 resultType = LongValue;
5750 curlResult = curl_easy_getinfo(connection->connection,
5751 CURLINFO_HEADER_SIZE,
5752 &longValue);
5753 break;
5754 #endif
5756 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5757 case 12: /* CURLINFO_REQUEST_SIZE */
5758 resultType = LongValue;
5760 curlResult = curl_easy_getinfo(connection->connection,
5761 CURLINFO_REQUEST_SIZE,
5762 &longValue);
5763 break;
5764 #endif
5766 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5767 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5768 resultType = LongValue;
5770 curlResult = curl_easy_getinfo(connection->connection,
5771 CURLINFO_SSL_VERIFYRESULT,
5772 &longValue);
5773 break;
5774 #endif
5776 #if HAVE_DECL_CURLINFO_FILETIME
5777 case 14: /* CURLINFO_FILETIME */
5778 resultType = DoubleValue;
5780 curlResult = curl_easy_getinfo(connection->connection,
5781 CURLINFO_FILETIME,
5782 &longValue);
5784 doubleValue = longValue;
5785 break;
5786 #endif
5788 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5789 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5790 resultType = DoubleValue;
5792 curlResult = curl_easy_getinfo(connection->connection,
5793 CURLINFO_CONTENT_LENGTH_DOWNLOAD,
5794 &doubleValue);
5795 break;
5796 #endif
5798 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5799 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5800 resultType = DoubleValue;
5802 curlResult = curl_easy_getinfo(connection->connection,
5803 CURLINFO_CONTENT_LENGTH_UPLOAD,
5804 &doubleValue);
5805 break;
5806 #endif
5808 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5809 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5810 resultType = DoubleValue;
5812 curlResult = curl_easy_getinfo(connection->connection,
5813 CURLINFO_STARTTRANSFER_TIME,
5814 &doubleValue);
5815 break;
5816 #endif
5818 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5819 case 18: /* CURLINFO_CONTENT_TYPE */
5820 resultType = StringValue;
5822 curlResult = curl_easy_getinfo(connection->connection,
5823 CURLINFO_CONTENT_TYPE,
5824 &strValue);
5825 break;
5826 #endif
5828 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5829 case 19: /* CURLINFO_REDIRECT_TIME */
5830 resultType = DoubleValue;
5832 curlResult = curl_easy_getinfo(connection->connection,
5833 CURLINFO_REDIRECT_TIME,
5834 &doubleValue);
5835 break;
5836 #endif
5838 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5839 case 20: /* CURLINFO_REDIRECT_COUNT */
5840 resultType = LongValue;
5842 curlResult = curl_easy_getinfo(connection->connection,
5843 CURLINFO_REDIRECT_COUNT,
5844 &longValue);
5845 break;
5846 #endif
5848 #if HAVE_DECL_CURLINFO_PRIVATE
5849 case 21: /* CURLINFO_PRIVATE */
5850 resultType = StringValue;
5852 curlResult = curl_easy_getinfo(connection->connection,
5853 CURLINFO_PRIVATE,
5854 &strValue);
5855 break;
5856 #endif
5858 #if HAVE_DECL_CURLINFO_HTTP_CONNECTCODE
5859 case 22: /* CURLINFO_HTTP_CONNECTCODE */
5860 resultType = LongValue;
5862 curlResult = curl_easy_getinfo(connection->connection,
5863 CURLINFO_HTTP_CONNECTCODE,
5864 &longValue);
5865 break;
5866 #endif
5868 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5869 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5870 resultType = LongValue;
5872 curlResult = curl_easy_getinfo(connection->connection,
5873 CURLINFO_HTTPAUTH_AVAIL,
5874 &longValue);
5875 break;
5876 #endif
5878 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5879 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5880 resultType = LongValue;
5882 curlResult = curl_easy_getinfo(connection->connection,
5883 CURLINFO_PROXYAUTH_AVAIL,
5884 &longValue);
5885 break;
5886 #endif
5888 #if HAVE_DECL_CURLINFO_OS_ERRNO
5889 case 25: /* CURLINFO_OS_ERRNO */
5890 resultType = LongValue;
5892 curlResult = curl_easy_getinfo(connection->connection,
5893 CURLINFO_OS_ERRNO,
5894 &longValue);
5895 break;
5896 #endif
5898 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5899 case 26: /* CURLINFO_NUM_CONNECTS */
5900 resultType = LongValue;
5902 curlResult = curl_easy_getinfo(connection->connection,
5903 CURLINFO_NUM_CONNECTS,
5904 &longValue);
5905 break;
5906 #endif
5908 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5909 case 27: /* CURLINFO_SSL_ENGINES */
5910 resultType = StringListValue;
5912 curlResult = curl_easy_getinfo(connection->connection,
5913 CURLINFO_SSL_ENGINES,
5914 &stringListValue);
5915 break;
5916 #endif
5918 #if HAVE_DECL_CURLINFO_COOKIELIST
5919 case 28: /* CURLINFO_COOKIELIST */
5920 resultType = StringListValue;
5922 curlResult = curl_easy_getinfo(connection->connection,
5923 CURLINFO_COOKIELIST,
5924 &stringListValue);
5925 break;
5926 #endif
5928 #if HAVE_DECL_CURLINFO_LASTSOCKET
5929 case 29: /* CURLINFO_LASTSOCKET */
5930 resultType = LongValue;
5932 curlResult = curl_easy_getinfo(connection->connection,
5933 CURLINFO_LASTSOCKET,
5934 &longValue);
5935 break;
5936 #endif
5938 #if HAVE_DECL_CURLINFO_FTP_ENTRY_PATH
5939 case 30: /* CURLINFO_FTP_ENTRY_PATH */
5940 resultType = StringValue;
5942 curlResult = curl_easy_getinfo(connection->connection,
5943 CURLINFO_FTP_ENTRY_PATH,
5944 &strValue);
5945 break;
5946 #endif
5948 #if HAVE_DECL_CURLINFO_REDIRECT_URL
5949 case 31: /* CURLINFO_REDIRECT_URL */
5950 resultType = StringValue;
5952 curlResult = curl_easy_getinfo(connection->connection,
5953 CURLINFO_REDIRECT_URL,
5954 &strValue);
5955 break;
5956 #else
5957 #warning "libcurl does not provide CURLINFO_REDIRECT_URL"
5958 #endif
5960 #if HAVE_DECL_CURLINFO_PRIMARY_IP
5961 case 32: /* CURLINFO_PRIMARY_IP */
5962 resultType = StringValue;
5964 curlResult = curl_easy_getinfo(connection->connection,
5965 CURLINFO_PRIMARY_IP,
5966 &strValue);
5967 break;
5968 #else
5969 #warning "libcurl does not provide CURLINFO_PRIMARY_IP"
5970 #endif
5972 default:
5973 failwith("Invalid CURLINFO Option");
5974 break;
5977 if (curlResult != CURLE_OK)
5978 raiseError(connection, curlResult);
5980 switch (resultType)
5982 case StringValue:
5983 result = alloc(1, StringValue);
5984 Store_field(result, 0, copy_string(strValue?strValue:""));
5985 break;
5987 case LongValue:
5988 result = alloc(1, LongValue);
5989 Store_field(result, 0, Val_long(longValue));
5990 break;
5992 case DoubleValue:
5993 result = alloc(1, DoubleValue);
5994 Store_field(result, 0, copy_double(doubleValue));
5995 break;
5997 case StringListValue:
5998 result = alloc(1, StringListValue);
5999 Store_field(result, 0, convertStringList(stringListValue));
6000 break;
6003 CAMLreturn(result);
6007 ** curl_escape helper function
6010 CAMLprim value helper_curl_escape(value str)
6012 CAMLparam1(str);
6013 CAMLlocal1(result);
6014 char *curlResult;
6016 curlResult = curl_escape(String_val(str), string_length(str));
6017 result = copy_string(curlResult);
6018 free(curlResult);
6020 CAMLreturn(result);
6024 ** curl_unescape helper function
6027 CAMLprim value helper_curl_unescape(value str)
6029 CAMLparam1(str);
6030 CAMLlocal1(result);
6031 char *curlResult;
6033 curlResult = curl_unescape(String_val(str), string_length(str));
6034 result = copy_string(curlResult);
6035 free(curlResult);
6037 CAMLreturn(result);
6041 ** curl_getdate helper function
6044 CAMLprim value helper_curl_getdate(value str, value now)
6046 CAMLparam2(str, now);
6047 CAMLlocal1(result);
6048 time_t curlResult;
6049 time_t curlNow;
6051 curlNow = (time_t)Double_val(now);
6052 curlResult = curl_getdate(String_val(str), &curlNow);
6053 result = copy_double((double)curlResult);
6055 CAMLreturn(result);
6059 ** curl_version helper function
6062 CAMLprim value helper_curl_version(void)
6064 CAMLparam0();
6065 CAMLlocal1(result);
6066 char *str;
6068 str = curl_version();
6069 result = copy_string(str);
6071 CAMLreturn(result);
6074 CAMLprim value caml_curl_version_info(value unit)
6076 CAMLparam1(unit);
6077 CAMLlocal3(v, vlist, vnum);
6078 const char* const* p = NULL;
6080 curl_version_info_data* data = curl_version_info(CURLVERSION_NOW);
6081 if (NULL == data) caml_failwith("curl_version_info");
6083 vlist = Val_emptylist;
6084 for (p = data->protocols; NULL != *p; p++)
6086 vlist = Val_cons(vlist, caml_copy_string(*p));
6089 vnum = caml_alloc_tuple(3);
6090 Store_field(vnum,0,Val_int(0xFF & (data->version_num >> 16)));
6091 Store_field(vnum,1,Val_int(0xFF & (data->version_num >> 8)));
6092 Store_field(vnum,2,Val_int(0xFF & (data->version_num)));
6094 v = caml_alloc_tuple(7);
6095 Store_field(v,0,caml_copy_string(data->version));
6096 Store_field(v,1,vnum);
6097 Store_field(v,2,caml_copy_string(data->host));
6098 Store_field(v,3,Val_int(data->features));
6099 Store_field(v,4,data->ssl_version ? Val_some(caml_copy_string(data->ssl_version)) : Val_none);
6100 Store_field(v,5,data->libz_version ? Val_some(caml_copy_string(data->libz_version)) : Val_none);
6101 Store_field(v,6,vlist);
6103 CAMLreturn(v);
6107 * Curl multi stack support
6109 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
6110 * Other exported functions are prefixed with caml_curlm_, some of them
6111 * can/should be decomposed into smaller parts.
6114 struct ml_multi_handle
6116 CURLM* handle;
6117 value values; /* callbacks */
6120 enum
6122 curlmopt_socket_function,
6124 /* last, not used */
6125 multi_values_total,
6128 typedef struct ml_multi_handle ml_multi_handle;
6130 #define Multi_val(v) (*(ml_multi_handle**)Data_custom_val(v))
6131 #define CURLM_val(v) (Multi_val(v)->handle)
6133 static struct custom_operations curl_multi_ops = {
6134 "ygrek.curl_multi",
6135 custom_finalize_default,
6136 custom_compare_default,
6137 custom_hash_default,
6138 custom_serialize_default,
6139 custom_deserialize_default
6142 CAMLprim value caml_curl_multi_init(value unit)
6144 CAMLparam1(unit);
6145 CAMLlocal1(v);
6146 ml_multi_handle* multi = (ml_multi_handle*)caml_stat_alloc(sizeof(ml_multi_handle));
6147 CURLM* h = curl_multi_init();
6149 if (!h)
6151 caml_stat_free(multi);
6152 failwith("caml_curl_multi_init");
6155 multi->handle = h;
6156 multi->values = caml_alloc(multi_values_total, 0);
6157 caml_register_generational_global_root(&multi->values);
6159 v = caml_alloc_custom(&curl_multi_ops, sizeof(ml_multi_handle*), 0, 1);
6160 Multi_val(v) = multi;
6162 CAMLreturn(v);
6165 CAMLprim value caml_curl_multi_cleanup(value handle)
6167 CAMLparam1(handle);
6168 ml_multi_handle* h = Multi_val(handle);
6170 if (NULL == h)
6171 CAMLreturn(Val_unit);
6173 caml_remove_generational_global_root(&h->values);
6175 if (CURLM_OK != curl_multi_cleanup(h->handle))
6176 failwith("caml_curl_multi_cleanup");
6178 Multi_val(handle) = (ml_multi_handle*)NULL;
6180 CAMLreturn(Val_unit);
6183 static CURL* curlm_remove_finished(CURLM* multi_handle, CURLcode* result)
6185 int msgs_in_queue = 0;
6187 while (1)
6189 CURLMsg* msg = curl_multi_info_read(multi_handle, &msgs_in_queue);
6190 if (NULL == msg) return NULL;
6191 if (CURLMSG_DONE == msg->msg)
6193 CURL* easy_handle = msg->easy_handle;
6194 if (result) *result = msg->data.result;
6195 if (CURLM_OK != curl_multi_remove_handle(multi_handle, easy_handle))
6197 //failwith("curlm_remove_finished");
6199 return easy_handle;
6204 CAMLprim value caml_curlm_remove_finished(value v_multi)
6206 CAMLparam1(v_multi);
6207 CAMLlocal2(v_easy, v_tuple);
6208 CURL* handle;
6209 CURLM* multi_handle;
6210 CURLcode result;
6212 multi_handle = CURLM_val(v_multi);
6214 caml_enter_blocking_section();
6215 handle = curlm_remove_finished(multi_handle,&result);
6216 caml_leave_blocking_section();
6218 if (NULL == handle)
6220 CAMLreturn(Val_none);
6222 else
6224 /* not good: same handle, but different block */
6225 v_easy = caml_alloc(1, Abstract_tag);
6226 Field(v_easy, 0) = (value)findConnection(handle);
6227 v_tuple = caml_alloc(2, 0);
6228 Store_field(v_tuple,0,v_easy);
6229 Store_field(v_tuple,1,Val_int(result)); /* CURLcode */
6230 CAMLreturn(Val_some(v_tuple));
6234 static int curlm_wait_data(CURLM* multi_handle)
6236 struct timeval timeout;
6237 CURLMcode ret;
6239 fd_set fdread;
6240 fd_set fdwrite;
6241 fd_set fdexcep;
6242 int maxfd;
6244 FD_ZERO(&fdread);
6245 FD_ZERO(&fdwrite);
6246 FD_ZERO(&fdexcep);
6248 /* set a suitable timeout */
6249 timeout.tv_sec = 1;
6250 timeout.tv_usec = 0;
6252 /* get file descriptors from the transfers */
6253 ret = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
6255 if (ret == CURLM_OK && maxfd >= 0)
6257 int rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
6258 if (-1 != rc) return 0;
6259 //printf("select error\n");
6261 else
6263 //printf("curl_multi_fdset error\n");
6265 return 1;
6268 CAMLprim value caml_curlm_wait_data(value v_multi)
6270 CAMLparam1(v_multi);
6271 int ret;
6272 CURLM* h;
6274 h = CURLM_val(v_multi);
6276 caml_enter_blocking_section();
6277 ret = curlm_wait_data(h);
6278 caml_leave_blocking_section();
6280 CAMLreturn(Val_bool(0 == ret));
6283 CAMLprim value caml_curl_multi_add_handle(value v_multi, value v_easy)
6285 CAMLparam2(v_multi,v_easy);
6287 if (CURLM_OK != curl_multi_add_handle(CURLM_val(v_multi), Connection_val(v_easy)->connection))
6288 failwith("caml_curl_multi_add_handle");
6290 CAMLreturn(Val_unit);
6293 CAMLprim value caml_curl_multi_perform_all(value v_multi)
6295 CAMLparam1(v_multi);
6296 CURLM* h;
6297 int still_running = 0;
6299 h = CURLM_val(v_multi);
6301 caml_enter_blocking_section();
6302 while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(h, &still_running));
6303 caml_leave_blocking_section();
6305 CAMLreturn(Val_int(still_running));
6308 CAMLprim value helper_curl_easy_strerror(value v_code)
6310 CAMLparam1(v_code);
6311 CAMLreturn(caml_copy_string(curl_easy_strerror(Int_val(v_code))));