4 *** Copyright (c) 2003-2008, Lars Nilsson, <lars@quantumchamaeleon.com>
5 *** Copyright (c) 2009, ygrek, <ygrek@autistici.org>
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>
24 #pragma message("No config file given.")
27 void leave_blocking_section(void);
28 void enter_blocking_section(void);
30 #define Val_none Val_int(0)
37 some
= caml_alloc(1, 0);
38 Store_field( some
, 0, v
);
42 static value
Val_pair(value v1
, value v2
)
46 pair
= caml_alloc_small(2,0);
52 static value
Val_cons(value list
, value v
) { return Val_pair(v
,list
); }
54 typedef struct Connection Connection
;
55 typedef struct ConnectionList ConnectionList
;
57 #define Connection_val(v) ((Connection *)Field(v, 0))
70 OcamlProgressCallback
,
74 OcamlSeekFunctionCallback
,
75 OcamlOpenSocketFunctionCallback
,
107 OcamlFTPAlternativeToUser
,
108 OcamlSSHPublicKeyFile
,
109 OcamlSSHPrivateKeyFile
,
110 OcamlSSHHostPublicKeyMD5
,
113 /* Not used, last for size */
137 struct curl_slist
*httpHeader
;
138 struct curl_httppost
*httpPostFirst
;
139 struct curl_httppost
*httpPostLast
;
140 struct curl_slist
*httpPostStrings
;
141 struct curl_slist
*resolve
;
149 struct curl_slist
*quote
;
150 struct curl_slist
*postQuote
;
153 char *interface_
; /* `interface` gives problems on windows */
161 struct curl_slist
*http200Aliases
;
165 char *ftpAlternativeToUser
;
166 char *sshPublicKeyFile
;
167 char *sshPrivateKeyFile
;
168 char *sshHostPublicKeyMD5
;
169 char *copyPostFields
;
173 struct ConnectionList
179 static ConnectionList connectionList
= {NULL
, NULL
};
181 typedef struct CURLErrorMapping CURLErrorMapping
;
183 struct CURLErrorMapping
189 CURLErrorMapping errorMap
[] =
191 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
192 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL
},
194 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
196 #if HAVE_DECL_CURLE_FAILED_INIT
197 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT
},
199 {"CURLE_FAILED_INIT", -1},
201 #if HAVE_DECL_CURLE_URL_MALFORMAT
202 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT
},
204 {"CURLE_URL_MALFORMAT", -1},
206 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
207 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER
},
209 {"CURLE_URL_MALFORMAT_USER", -1},
211 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
212 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY
},
214 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
216 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
217 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST
},
219 {"CURLE_COULDNT_RESOLVE_HOST", -1},
221 #if HAVE_DECL_CURLE_COULDNT_CONNECT
222 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT
},
224 {"CURLE_COULDNT_CONNECT", -1},
226 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
227 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY
},
229 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
231 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
232 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED
},
234 {"CURLE_FTP_ACCESS_DENIED", -1},
236 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
237 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT
},
239 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
241 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
242 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY
},
244 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
246 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
247 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY
},
249 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
251 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
252 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY
},
254 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
256 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
257 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT
},
259 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
261 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
262 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST
},
264 {"CURLE_FTP_CANT_GET_HOST", -1},
266 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
267 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT
},
269 {"CURLE_FTP_CANT_RECONNECT", -1},
271 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
272 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY
},
274 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
276 #if HAVE_DECL_CURLE_PARTIAL_FILE
277 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE
},
279 {"CURLE_PARTIAL_FILE", -1},
281 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
282 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE
},
284 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
286 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
287 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR
},
289 {"CURLE_FTP_WRITE_ERROR", -1},
291 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
292 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR
},
294 {"CURLE_FTP_QUOTE_ERROR", -1},
296 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
297 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND
},
299 {"CURLE_HTTP_NOT_FOUND", -1},
301 #if HAVE_DECL_CURLE_WRITE_ERROR
302 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR
},
304 {"CURLE_WRITE_ERROR", -1},
306 #if HAVE_DECL_CURLE_MALFORMAT_USER
307 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER
},
309 {"CURLE_MALFORMAT_USER", -1},
311 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
312 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE
},
314 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
316 #if HAVE_DECL_CURLE_READ_ERROR
317 {"CURLE_READ_ERROR", CURLE_READ_ERROR
},
319 {"CURLE_READ_ERROR", -1},
321 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
322 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY
},
324 {"CURLE_OUT_OF_MEMORY", -1},
326 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
327 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED
},
329 {"CURLE_OPERATION_TIMEOUTED", -1},
331 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
332 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII
},
334 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
336 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
337 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED
},
339 {"CURLE_FTP_PORT_FAILED", -1},
341 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
342 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST
},
344 {"CURLE_FTP_COULDNT_USE_REST", -1},
346 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
347 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE
},
349 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
351 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
352 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR
},
354 {"CURLE_HTTP_RANGE_ERROR", -1},
356 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
357 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR
},
359 {"CURLE_HTTP_POST_ERROR", -1},
361 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
362 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR
},
364 {"CURLE_SSL_CONNECT_ERROR", -1},
366 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
367 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME
},
369 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
371 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
372 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE
},
374 {"CURLE_FILE_COULDNT_READ_FILE", -1},
376 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
377 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND
},
379 {"CURLE_LDAP_CANNOT_BIND", -1},
381 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
382 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED
},
384 {"CURLE_LDAP_SEARCH_FAILED", -1},
386 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
387 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND
},
389 {"CURLE_LIBRARY_NOT_FOUND", -1},
391 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
392 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND
},
394 {"CURLE_FUNCTION_NOT_FOUND", -1},
396 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
397 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK
},
399 {"CURLE_ABORTED_BY_CALLBACK", -1},
401 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
402 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT
},
404 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
406 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
407 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER
},
409 {"CURLE_BAD_CALLING_ORDER", -1},
411 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
412 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED
},
414 {"CURLE_HTTP_PORT_FAILED", -1},
416 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
417 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED
},
419 {"CURLE_BAD_PASSWORD_ENTERED", -1},
421 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
422 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS
},
424 {"CURLE_TOO_MANY_REDIRECTS", -1},
426 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
427 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION
},
429 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
431 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
432 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX
},
434 {"CURLE_TELNET_OPTION_SYNTAX", -1},
436 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
437 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE
},
439 {"CURLE_SSL_PEER_CERTIFICATE", -1},
441 #if HAVE_DECL_CURLE_GOT_NOTHING
442 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING
},
444 {"CURLE_GOT_NOTHING", -1},
446 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
447 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND
},
449 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
451 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
452 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED
},
454 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
456 #if HAVE_DECL_CURLE_SEND_ERROR
457 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR
},
459 {"CURLE_SEND_ERROR", -1},
461 #if HAVE_DECL_CURLE_RECV_ERROR
462 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR
},
464 {"CURLE_RECV_ERROR", -1},
466 #if HAVE_DECL_CURLE_SHARE_IN_USE
467 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE
},
469 {"CURLE_SHARE_IN_USE", -1},
471 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
472 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM
},
474 {"CURLE_SSL_CERTPROBLEN", -1},
476 #if HAVE_DECL_CURLE_SSL_CIPHER
477 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER
},
479 {"CURLE_SSL_CIPHER", -1},
481 #if HAVE_DECL_CURLE_SSL_CACERT
482 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT
},
484 {"CURLE_SSL_CACERT", -1},
486 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
487 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING
},
489 {"CURLE_BAD_CONTENT_ENCODING", -1},
491 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
492 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL
},
494 {"CURLE_LDAP_INVALID_URL", -1},
496 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
497 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED
},
499 {"CURLE_FILESIZE_EXCEEDED", -1},
501 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
502 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED
},
504 {"CURLE_FTP_SSL_FAILED", -1},
506 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
507 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND
},
509 {"CURLE_SEND_FAIL_REWIND", -1},
511 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
512 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED
},
514 {"CURLE_SSL_ENGINE_INITFAILED", -1},
516 #if HAVE_DECL_CURLE_LOGIN_DENIED
517 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED
},
519 {"CURLE_LOGIN_DENIED", -1},
521 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
522 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND
},
524 {"CURLE_TFTP_NOTFOUND", -1},
526 #if HAVE_DECL_CURLE_TFTP_PERM
527 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM
},
529 {"CURLE_TFTP_PERM", -1},
531 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
532 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL
},
534 {"CURLE_REMOTE_DISK_FULL", -1},
536 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
537 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL
},
539 {"CURLE_TFTP_ILLEGAL", -1},
541 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
542 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID
},
544 {"CURLE_TFTP_UNKNOWNID", -1},
546 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
547 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS
},
549 {"CURLE_REMOTE_FILE_EXISTS", -1},
551 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
552 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER
},
554 {"CURLE_TFTP_NOSUCHUSER", -1},
556 #if HAVE_DECL_CURLE_CONV_FAILED
557 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED
},
559 {"CURLE_CONV_FAILED", -1},
561 #if HAVE_DECL_CURLE_CONV_REQUIRED
562 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED
},
564 {"CURLE_CONV_REQUIRED", -1},
566 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
567 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE
},
569 {"CURLE_SSL_CACERT_BADFILE", -1},
571 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
572 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND
},
574 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
576 #if HAVE_DECL_CURLE_SSH
577 {"CURLE_SSH", CURLE_SSH
},
581 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
582 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED
},
584 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
586 #if HAVE_DECL_CURLE_AGAIN
587 {"CURLE_AGAIN", CURLE_AGAIN
},
591 {"CURLE_OK", CURLE_OK
},
595 typedef struct CURLOptionMapping CURLOptionMapping
;
597 struct CURLOptionMapping
599 void (*optionHandler
)(Connection
*, value
);
604 CURLOptionMapping unimplementedOptionMap
[] =
606 {NULL
, "CURLOPT_STDERR", CURLOPT_STDERR
},
610 static void handleWriteFunction(Connection
*, value
);
611 static void handleReadFunction(Connection
*, value
);
612 static void handleInFileSize(Connection
*, value
);
613 static void handleURL(Connection
*, value
);
614 static void handleProxy(Connection
*, value
);
615 static void handleProxyPort(Connection
*, value
);
616 static void handleHTTPProxyTunnel(Connection
*, value
);
617 static void handleVerbose(Connection
*, value
);
618 static void handleHeader(Connection
*, value
);
619 static void handleNoProgress(Connection
*, value
);
620 static void handleNoSignal(Connection
*, value
);
621 static void handleNoBody(Connection
*, value
);
622 static void handleFailOnError(Connection
*, value
);
623 static void handleUpload(Connection
*, value
);
624 static void handlePost(Connection
*, value
);
625 static void handleFTPListOnly(Connection
*, value
);
626 static void handleFTPAppend(Connection
*, value
);
627 static void handleNETRC(Connection
*, value
);
628 static void handleEncoding(Connection
*, value
);
629 static void handleFollowLocation(Connection
*, value
);
630 static void handleTransferText(Connection
*, value
);
631 static void handlePut(Connection
*, value
);
632 static void handleUserPwd(Connection
*, value
);
633 static void handleProxyUserPwd(Connection
*, value
);
634 static void handleRange(Connection
*, value
);
635 static void handleErrorBuffer(Connection
*, value
);
636 static void handleTimeout(Connection
*, value
);
637 static void handlePostFields(Connection
*, value
);
638 static void handlePostFieldSize(Connection
*, value
);
639 static void handleReferer(Connection
*, value
);
640 static void handleUserAgent(Connection
*, value
);
641 static void handleFTPPort(Connection
*, value
);
642 static void handleLowSpeedLimit(Connection
*, value
);
643 static void handleLowSpeedTime(Connection
*, value
);
644 static void handleResumeFrom(Connection
*, value
);
645 static void handleCookie(Connection
*, value
);
646 static void handleHTTPHeader(Connection
*, value
);
647 static void handleHTTPPost(Connection
*, value
);
648 static void handleSSLCert(Connection
*, value
);
649 static void handleSSLCertType(Connection
*, value
);
650 static void handleSSLCertPasswd(Connection
*, value
);
651 static void handleSSLKey(Connection
*, value
);
652 static void handleSSLKeyType(Connection
*, value
);
653 static void handleSSLKeyPasswd(Connection
*, value
);
654 static void handleSSLEngine(Connection
*, value
);
655 static void handleSSLEngineDefault(Connection
*, value
);
656 static void handleCRLF(Connection
*, value
);
657 static void handleQuote(Connection
*, value
);
658 static void handlePostQuote(Connection
*, value
);
659 static void handleHeaderFunction(Connection
*, value
);
660 static void handleCookieFile(Connection
*, value
);
661 static void handleSSLVersion(Connection
*, value
);
662 static void handleTimeCondition(Connection
*, value
);
663 static void handleTimeValue(Connection
*, value
);
664 static void handleCustomRequest(Connection
*, value
);
665 static void handleInterface(Connection
*, value
);
666 static void handleKRB4Level(Connection
*, value
);
667 static void handleProgressFunction(Connection
*, value
);
668 static void handleSSLVerifyPeer(Connection
*, value
);
669 static void handleCAInfo(Connection
*, value
);
670 static void handleCAPath(Connection
*, value
);
671 static void handleFileTime(Connection
*, value
);
672 static void handleMaxRedirs(Connection
*, value
);
673 static void handleMaxConnects(Connection
*, value
);
674 static void handleClosePolicy(Connection
*, value
);
675 static void handleFreshConnect(Connection
*, value
);
676 static void handleForbidReuse(Connection
*, value
);
677 static void handleRandomFile(Connection
*, value
);
678 static void handleEGDSocket(Connection
*, value
);
679 static void handleConnectTimeout(Connection
*, value
);
680 static void handleHTTPGet(Connection
*, value
);
681 static void handleSSLVerifyHost(Connection
*, value
);
682 static void handleCookieJar(Connection
*, value
);
683 static void handleSSLCipherList(Connection
*, value
);
684 static void handleHTTPVersion(Connection
*, value
);
685 static void handleFTPUseEPSV(Connection
*, value
);
686 static void handleDNSCacheTimeout(Connection
*, value
);
687 static void handleDNSUseGlobalCache(Connection
*, value
);
688 static void handleDebugFunction(Connection
*, value
);
689 static void handlePrivate(Connection
*, value
);
690 static void handleHTTP200Aliases(Connection
*, value
);
691 static void handleUnrestrictedAuth(Connection
*, value
);
692 static void handleFTPUseEPRT(Connection
*, value
);
693 static void handleHTTPAuth(Connection
*, value
);
694 static void handleFTPCreateMissingDirs(Connection
*, value
);
695 static void handleProxyAuth(Connection
*, value
);
696 static void handleFTPResponseTimeout(Connection
*, value
);
697 static void handleIPResolve(Connection
*, value
);
698 static void handleMaxFileSize(Connection
*, value
);
699 static void handleInFileSizeLarge(Connection
*, value
);
700 static void handleResumeFromLarge(Connection
*, value
);
701 static void handleMaxFileSizeLarge(Connection
*, value
);
702 static void handleNETRCFile(Connection
*, value
);
703 static void handleFTPSSL(Connection
*, value
);
704 static void handlePostFieldSizeLarge(Connection
*, value
);
705 static void handleTCPNoDelay(Connection
*, value
);
706 static void handleFTPSSLAuth(Connection
*, value
);
707 static void handleIOCTLFunction(Connection
*, value
);
708 static void handleFTPAccount(Connection
*, value
);
709 static void handleCookieList(Connection
*, value
);
710 static void handleIgnoreContentLength(Connection
*, value
);
711 static void handleFTPSkipPASVIP(Connection
*, value
);
712 static void handleFTPFileMethod(Connection
*, value
);
713 static void handleLocalPort(Connection
*, value
);
714 static void handleLocalPortRange(Connection
*, value
);
715 static void handleConnectOnly(Connection
*, value
);
716 static void handleMaxSendSpeedLarge(Connection
*, value
);
717 static void handleMaxRecvSpeedLarge(Connection
*, value
);
718 static void handleFTPAlternativeToUser(Connection
*, value
);
719 static void handleSSLSessionIdCache(Connection
*, value
);
720 static void handleSSHAuthTypes(Connection
*, value
);
721 static void handleSSHPublicKeyFile(Connection
*, value
);
722 static void handleSSHPrivateKeyFile(Connection
*, value
);
723 static void handleFTPSSLCCC(Connection
*, value
);
724 static void handleTimeoutMS(Connection
*, value
);
725 static void handleConnectTimeoutMS(Connection
*, value
);
726 static void handleHTTPTransferDecoding(Connection
*, value
);
727 static void handleHTTPContentDecoding(Connection
*, value
);
728 static void handleNewFilePerms(Connection
*, value
);
729 static void handleNewDirectoryPerms(Connection
*, value
);
730 static void handlePost301(Connection
*, value
);
731 static void handleSSHHostPublicKeyMD5(Connection
*, value
);
732 static void handleCopyPostFields(Connection
*, value
);
733 static void handleProxyTransferMode(Connection
*, value
);
734 static void handleSeekFunction(Connection
*, value
);
735 static void handleAutoReferer(Connection
*, value
);
736 static void handleOpenSocketFunction(Connection
*, value
);
737 static void handleProxyType(Connection
*, value
);
738 static void handleProtocols(Connection
*, value
);
739 static void handleRedirProtocols(Connection
*, value
);
740 static void handleResolve(Connection
*, value
);
741 static void handleDnsServers(Connection
*, value
);
743 CURLOptionMapping implementedOptionMap
[] =
745 {handleWriteFunction
, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION
},
746 {handleReadFunction
, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION
},
747 {handleInFileSize
, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE
},
748 {handleURL
, "CURLOPT_URL", CURLOPT_URL
},
749 {handleProxy
, "CURLOPT_PROXY", CURLOPT_PROXY
},
750 {handleProxyPort
, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT
},
751 {handleHTTPProxyTunnel
, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL
},
752 {handleVerbose
, "CURLOPT_VERBOSE", CURLOPT_VERBOSE
},
753 {handleHeader
, "CURLOPT_HEADER", CURLOPT_HEADER
},
754 {handleNoProgress
, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS
},
755 #if HAVE_DECL_CURLOPT_NOSIGNAL
756 {handleNoSignal
, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL
},
758 {handleNoSignal
, "CURLOPT_NOSIGNAL", 0},
760 {handleNoBody
, "CURLOPT_NOBODY", CURLOPT_NOBODY
},
761 {handleFailOnError
, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR
},
762 {handleUpload
, "CURLOPT_UPLOAD", CURLOPT_UPLOAD
},
763 {handlePost
, "CURLOPT_POST", CURLOPT_POST
},
764 {handleFTPListOnly
, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY
},
765 {handleFTPAppend
, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND
},
766 {handleNETRC
, "CURLOPT_NETRC", CURLOPT_NETRC
},
767 #if HAVE_DECL_CURLOPT_ENCODING
768 {handleEncoding
, "CURLOPT_ENCODING", CURLOPT_ENCODING
},
770 {handleEncoding
, "CURLOPT_ENCODING", 0},
772 {handleFollowLocation
, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION
},
773 {handleTransferText
, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT
},
774 {handlePut
, "CURLOPT_PUT", CURLOPT_PUT
},
775 {handleUserPwd
, "CURLOPT_USERPWD", CURLOPT_USERPWD
},
776 {handleProxyUserPwd
, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD
},
777 {handleRange
, "CURLOPT_RANGE", CURLOPT_RANGE
},
778 {handleErrorBuffer
, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER
},
779 {handleTimeout
, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT
},
780 {handlePostFields
, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS
},
781 {handlePostFieldSize
, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE
},
782 {handleReferer
, "CURLOPT_REFERER", CURLOPT_REFERER
},
783 {handleUserAgent
, "CURLOPT_USERAGENT", CURLOPT_USERAGENT
},
784 {handleFTPPort
, "CURLOPT_FTPPORT", CURLOPT_FTPPORT
},
785 {handleLowSpeedLimit
, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT
},
786 {handleLowSpeedTime
, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME
},
787 {handleResumeFrom
, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM
},
788 {handleCookie
, "CURLOPT_COOKIE", CURLOPT_COOKIE
},
789 {handleHTTPHeader
, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER
},
790 {handleHTTPPost
, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST
},
791 {handleSSLCert
, "CURLOPT_SSLCERT", CURLOPT_SSLCERT
},
792 {handleSSLCertType
, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE
},
793 {handleSSLCertPasswd
, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD
},
794 {handleSSLKey
, "CURLOPT_SSLKEY", CURLOPT_SSLKEY
},
795 {handleSSLKeyType
, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE
},
796 {handleSSLKeyPasswd
, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD
},
797 {handleSSLEngine
, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE
},
798 {handleSSLEngineDefault
, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT
},
799 {handleCRLF
, "CURLOPT_CRLF", CURLOPT_CRLF
},
800 {handleQuote
, "CURLOPT_QUOTE", CURLOPT_QUOTE
},
801 {handlePostQuote
, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE
},
802 {handleHeaderFunction
, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION
},
803 {handleCookieFile
, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE
},
804 {handleSSLVersion
, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION
},
805 {handleTimeCondition
, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION
},
806 {handleTimeValue
, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE
},
807 {handleCustomRequest
, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST
},
808 {handleInterface
, "CURLOPT_INTERFACE", CURLOPT_INTERFACE
},
809 {handleKRB4Level
, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL
},
810 {handleProgressFunction
, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION
},
811 {handleSSLVerifyPeer
, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER
},
812 {handleCAInfo
, "CURLOPT_CAINFO", CURLOPT_CAINFO
},
813 {handleCAPath
, "CURLOPT_CAPATH", CURLOPT_CAPATH
},
814 {handleFileTime
, "CURLOPT_FILETIME", CURLOPT_FILETIME
},
815 {handleMaxRedirs
, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS
},
816 {handleMaxConnects
, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS
},
817 {handleClosePolicy
, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY
},
818 {handleFreshConnect
, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT
},
819 {handleForbidReuse
, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE
},
820 {handleRandomFile
, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE
},
821 {handleEGDSocket
, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET
},
822 {handleConnectTimeout
, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT
},
823 {handleHTTPGet
, "CURLOPT_HTTPGET", CURLOPT_HTTPGET
},
824 {handleSSLVerifyHost
, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST
},
825 {handleCookieJar
, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR
},
826 {handleSSLCipherList
, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST
},
827 {handleHTTPVersion
, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION
},
828 {handleFTPUseEPSV
, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV
},
829 {handleDNSCacheTimeout
, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT
},
830 {handleDNSUseGlobalCache
, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE
},
831 {handleDebugFunction
, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION
},
832 #if HAVE_DECL_CURLOPT_PRIVATE
833 {handlePrivate
, "CURLOPT_PRIVATE", CURLOPT_PRIVATE
},
835 {handlePrivate
, "CURLOPT_PRIVATE", 0},
837 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
838 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES
},
840 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", 0},
842 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
843 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH
},
845 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", 0},
847 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
848 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT
},
850 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", 0},
852 #if HAVE_DECL_CURLOPT_HTTPAUTH
853 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH
},
855 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", 0},
857 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
858 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS
},
860 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
862 #if HAVE_DECL_CURLOPT_PROXYAUTH
863 {handleProxyAuth
, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH
},
865 {handleProxyAuth
, "CURLOPT_PROXYAUTH", 0},
867 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
868 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT
},
870 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
872 #if HAVE_DECL_CURLOPT_IPRESOLVE
873 {handleIPResolve
, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE
},
875 {handleIPResolve
, "CURLOPT_IPRESOLVE", 0},
877 #if HAVE_DECL_CURLOPT_MAXFILESIZE
878 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE
},
880 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", 0},
882 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
883 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE
},
885 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", 0},
887 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
888 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE
},
890 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", 0},
892 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
893 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE
},
895 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", 0},
897 #if HAVE_DECL_CURLOPT_NETRC_FILE
898 {handleNETRCFile
, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE
},
900 {handleNETRCFile
, "CURLOPT_NETRC_FILE", 0},
902 #if HAVE_DECL_CURLOPT_FTP_SSL
903 {handleFTPSSL
, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL
},
905 {handleFTPSSL
, "CURLOPT_FTP_SSL", 0},
907 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
908 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE
},
910 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
912 #if HAVE_DECL_CURLOPT_TCP_NODELAY
913 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY
},
915 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", 0},
917 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
918 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH
},
920 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", 0},
922 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
923 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION
},
925 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", 0},
927 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
928 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT
},
930 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", 0},
932 #if HAVE_DECL_CURLOPT_COOKIELIST
933 {handleCookieList
, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST
},
935 {handleCookieList
, "CURLOPT_COOKIELIST", 0},
937 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
938 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH
},
940 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
942 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
943 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP
},
945 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", 0},
947 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
948 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD
},
950 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", 0},
952 #if HAVE_DECL_CURLOPT_LOCALPORT
953 {handleLocalPort
, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT
},
955 {handleLocalPort
, "CURLOPT_LOCALPORT", 0},
957 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
958 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE
},
960 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", 0},
962 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
963 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY
},
965 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", 0},
967 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
968 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE
},
970 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
972 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
973 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE
},
975 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
977 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
978 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER
},
980 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
982 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
983 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE
},
985 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", 0},
987 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
988 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES
},
990 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", 0},
992 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
993 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE
},
995 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
997 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
998 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE
},
1000 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
1002 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
1003 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC
},
1005 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", 0},
1007 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
1008 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS
},
1010 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", 0},
1012 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
1013 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS
},
1015 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", 0},
1017 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
1018 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING
},
1020 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
1022 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1023 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING
},
1025 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1027 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1028 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS
},
1030 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", 0},
1032 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1033 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS
},
1035 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1037 #if HAVE_DECL_CURLOPT_POST301
1038 {handlePost301
, "CURLOPT_POST301", CURLOPT_POST301
},
1040 {handlePost301
, "CURLOPT_POST301", 0},
1042 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1043 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
},
1045 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1047 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1048 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS
},
1050 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", 0},
1052 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1053 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE
},
1055 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1057 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1058 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION
},
1060 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", 0},
1062 #if HAVE_DECL_CURLOPT_AUTOREFERER
1063 {handleAutoReferer
, "CURLOPT_AUTOREFERER", CURLOPT_AUTOREFERER
},
1065 {handleAutoReferer
, "CURLOPT_AUTOREFERER", 0},
1067 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
1068 {handleOpenSocketFunction
, "CURLOPT_OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION
},
1070 {handleOpenSocketFunction
, "CURLOPT_OPENSOCKETFUNCTION", 0},
1072 #if HAVE_DECL_CURLOPT_PROXYTYPE
1073 {handleProxyType
, "CURLOPT_PROXYTYPE", CURLOPT_PROXYTYPE
},
1075 {handleProxyType
, "CURLOPT_PROXYTYPE", 0},
1077 #if HAVE_DECL_CURLOPT_PROTOCOLS
1078 {handleProtocols
, "CURLOPT_PROTOCOLS", CURLOPT_PROTOCOLS
},
1080 {handleProtocols
, "CURLOPT_PROTOCOLS", 0},
1082 #if HAVE_DECL_CURLOPT_REDIR_PROTOCOLS
1083 {handleRedirProtocols
, "CURLOPT_REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS
},
1085 {handleRedirProtocols
, "CURLOPT_REDIR_PROTOCOLS", 0},
1087 #if HAVE_DECL_CURLOPT_RESOLVE
1088 {handleResolve
, "CURLOPT_RESOLVE", CURLOPT_RESOLVE
},
1090 {handleResolve
, "CURLOPT_RESOLVE", 0},
1092 #if HAVE_DECL_CURLOPT_DNS_SERVERS
1093 {handleDnsServers
, "CURLOPT_DNS_SERVERS", CURLOPT_DNS_SERVERS
},
1095 {handleDnsServers
, "CURLOPT_DNS_SERVERS", 0},
1099 static char *findOption(CURLOptionMapping optionMap
[],
1102 return optionMap
[option
].name
;
1105 static void free_curl_slist(struct curl_slist
*slist
)
1110 curl_slist_free_all(slist
);
1113 static void raiseError(Connection
*conn
, CURLcode code
)
1116 CAMLlocal1(exceptionData
);
1118 char *errorString
= "Unknown Error";
1121 for (i
= 0; errorMap
[i
].name
!= NULL
; i
++)
1123 if (errorMap
[i
].error
== code
)
1125 errorString
= errorMap
[i
].name
;
1130 exceptionData
= caml_alloc(3, 0);
1132 Store_field(exceptionData
, 0, Val_int(code
));
1133 Store_field(exceptionData
, 1, Val_int(code
));
1134 Store_field(exceptionData
, 2, copy_string(errorString
));
1136 if (conn
!= NULL
&& conn
->errorBuffer
!= NULL
)
1138 Store_field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0,
1139 copy_string(conn
->errorBuffer
));
1142 exception
= caml_named_value("CurlException");
1144 if (exception
== NULL
)
1145 caml_failwith("CurlException not registered");
1147 raise_with_arg(*exception
, exceptionData
);
1152 static void resetOcamlValues(Connection
* connection
)
1156 for (i
= 0; i
< OcamlValuesSize
; i
++)
1157 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1160 static Connection
*newConnection(void)
1162 Connection
*connection
;
1164 connection
= (Connection
*)malloc(sizeof(Connection
));
1166 enter_blocking_section();
1167 connection
->connection
= curl_easy_init();
1168 leave_blocking_section();
1170 connection
->next
= NULL
;
1171 connection
->prev
= NULL
;
1173 if (connectionList
.tail
== NULL
)
1175 connectionList
.tail
= connection
;
1176 connectionList
.head
= connection
;
1180 connection
->prev
= connectionList
.head
;
1181 connectionList
.head
->next
= connection
;
1182 connectionList
.head
= connection
;
1185 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1186 resetOcamlValues(connection
);
1187 register_global_root(&connection
->ocamlValues
);
1189 connection
->url
= NULL
;
1190 connection
->proxy
= NULL
;
1191 connection
->userPwd
= NULL
;
1192 connection
->proxyUserPwd
= NULL
;
1193 connection
->range
= NULL
;
1194 connection
->errorBuffer
= NULL
;
1195 connection
->postFields
= NULL
;
1196 connection
->postFieldSize
= -1;
1197 connection
->referer
= NULL
;
1198 connection
->userAgent
= NULL
;
1199 connection
->ftpPort
= NULL
;
1200 connection
->cookie
= NULL
;
1201 connection
->httpHeader
= NULL
;
1202 connection
->httpPostFirst
= NULL
;
1203 connection
->httpPostLast
= NULL
;
1204 connection
->httpPostStrings
= NULL
;
1205 connection
->sslCert
= NULL
;
1206 connection
->sslCertType
= NULL
;
1207 connection
->sslCertPasswd
= NULL
;
1208 connection
->sslKey
= NULL
;
1209 connection
->sslKeyType
= NULL
;
1210 connection
->sslKeyPasswd
= NULL
;
1211 connection
->sslEngine
= NULL
;
1212 connection
->quote
= NULL
;
1213 connection
->postQuote
= NULL
;
1214 connection
->cookieFile
= NULL
;
1215 connection
->customRequest
= NULL
;
1216 connection
->interface_
= NULL
;
1217 connection
->caInfo
= NULL
;
1218 connection
->caPath
= NULL
;
1219 connection
->randomFile
= NULL
;
1220 connection
->egdSocket
= NULL
;
1221 connection
->cookieJar
= NULL
;
1222 connection
->sslCipherList
= NULL
;
1223 connection
->private = NULL
;
1224 connection
->http200Aliases
= NULL
;
1225 connection
->netrcFile
= NULL
;
1226 connection
->ftpaccount
= NULL
;
1227 connection
->cookielist
= NULL
;
1228 connection
->ftpAlternativeToUser
= NULL
;
1229 connection
->sshPublicKeyFile
= NULL
;
1230 connection
->sshPrivateKeyFile
= NULL
;
1231 connection
->copyPostFields
= NULL
;
1232 connection
->resolve
= NULL
;
1233 connection
->dns_servers
= NULL
;
1238 static Connection
*duplicateConnection(Connection
*original
)
1240 Connection
*connection
;
1242 connection
= (Connection
*)malloc(sizeof(Connection
));
1244 enter_blocking_section();
1245 connection
->connection
= curl_easy_duphandle(original
->connection
);
1246 leave_blocking_section();
1248 connection
->next
= NULL
;
1249 connection
->prev
= NULL
;
1251 if (connectionList
.tail
== NULL
)
1253 connectionList
.tail
= connection
;
1254 connectionList
.head
= connection
;
1258 connection
->prev
= connectionList
.head
;
1259 connectionList
.head
->next
= connection
;
1260 connectionList
.head
= connection
;
1263 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1264 resetOcamlValues(connection
);
1265 register_global_root(&connection
->ocamlValues
);
1267 Store_field(connection
->ocamlValues
, OcamlWriteCallback
,
1268 Field(original
->ocamlValues
, OcamlWriteCallback
));
1269 Store_field(connection
->ocamlValues
, OcamlReadCallback
,
1270 Field(original
->ocamlValues
, OcamlReadCallback
));
1271 Store_field(connection
->ocamlValues
, OcamlErrorBuffer
,
1272 Field(original
->ocamlValues
, OcamlErrorBuffer
));
1273 Store_field(connection
->ocamlValues
, OcamlPostFields
,
1274 Field(original
->ocamlValues
, OcamlPostFields
));
1275 Store_field(connection
->ocamlValues
, OcamlHTTPHeader
,
1276 Field(original
->ocamlValues
, OcamlHTTPHeader
));
1277 Store_field(connection
->ocamlValues
, OcamlQuote
,
1278 Field(original
->ocamlValues
, OcamlQuote
));
1279 Store_field(connection
->ocamlValues
, OcamlPostQuote
,
1280 Field(original
->ocamlValues
, OcamlPostQuote
));
1281 Store_field(connection
->ocamlValues
, OcamlHeaderCallback
,
1282 Field(original
->ocamlValues
, OcamlHeaderCallback
));
1283 Store_field(connection
->ocamlValues
, OcamlProgressCallback
,
1284 Field(original
->ocamlValues
, OcamlProgressCallback
));
1285 Store_field(connection
->ocamlValues
, OcamlDebugCallback
,
1286 Field(original
->ocamlValues
, OcamlDebugCallback
));
1287 Store_field(connection
->ocamlValues
, OcamlHTTP200Aliases
,
1288 Field(original
->ocamlValues
, OcamlHTTP200Aliases
));
1289 Store_field(connection
->ocamlValues
, OcamlIOCTLCallback
,
1290 Field(original
->ocamlValues
, OcamlIOCTLCallback
));
1291 Store_field(connection
->ocamlValues
, OcamlSeekFunctionCallback
,
1292 Field(original
->ocamlValues
, OcamlSeekFunctionCallback
));
1294 connection
->url
= NULL
;
1295 connection
->proxy
= NULL
;
1296 connection
->userPwd
= NULL
;
1297 connection
->proxyUserPwd
= NULL
;
1298 connection
->range
= NULL
;
1299 connection
->errorBuffer
= NULL
;
1300 connection
->postFields
= NULL
;
1301 connection
->postFieldSize
= -1;
1302 connection
->referer
= NULL
;
1303 connection
->userAgent
= NULL
;
1304 connection
->ftpPort
= NULL
;
1305 connection
->cookie
= NULL
;
1306 connection
->httpHeader
= NULL
;
1307 connection
->httpPostFirst
= NULL
;
1308 connection
->httpPostLast
= NULL
;
1309 connection
->httpPostStrings
= NULL
;
1310 connection
->sslCert
= NULL
;
1311 connection
->sslCertType
= NULL
;
1312 connection
->sslCertPasswd
= NULL
;
1313 connection
->sslKey
= NULL
;
1314 connection
->sslKeyType
= NULL
;
1315 connection
->sslKeyPasswd
= NULL
;
1316 connection
->sslEngine
= NULL
;
1317 connection
->quote
= NULL
;
1318 connection
->postQuote
= NULL
;
1319 connection
->cookieFile
= NULL
;
1320 connection
->customRequest
= NULL
;
1321 connection
->interface_
= NULL
;
1322 connection
->caInfo
= NULL
;
1323 connection
->caPath
= NULL
;
1324 connection
->randomFile
= NULL
;
1325 connection
->egdSocket
= NULL
;
1326 connection
->cookieJar
= NULL
;
1327 connection
->sslCipherList
= NULL
;
1328 connection
->private = NULL
;
1329 connection
->http200Aliases
= NULL
;
1330 connection
->netrcFile
= NULL
;
1331 connection
->ftpaccount
= NULL
;
1332 connection
->cookielist
= NULL
;
1333 connection
->sshPublicKeyFile
= NULL
;
1334 connection
->sshPrivateKeyFile
= NULL
;
1335 connection
->copyPostFields
= NULL
;
1336 connection
->resolve
= NULL
;
1337 connection
->dns_servers
= NULL
;
1339 if (Field(original
->ocamlValues
, OcamlURL
) != Val_unit
)
1340 handleURL(connection
, Field(original
->ocamlValues
,
1342 if (Field(original
->ocamlValues
, OcamlProxy
) != Val_unit
)
1343 handleProxy(connection
, Field(original
->ocamlValues
,
1345 if (Field(original
->ocamlValues
, OcamlUserPWD
) != Val_unit
)
1346 handleUserPwd(connection
, Field(original
->ocamlValues
,
1348 if (Field(original
->ocamlValues
, OcamlProxyUserPWD
) != Val_unit
)
1349 handleProxyUserPwd(connection
, Field(original
->ocamlValues
,
1350 OcamlProxyUserPWD
));
1351 if (Field(original
->ocamlValues
, OcamlRange
) != Val_unit
)
1352 handleRange(connection
, Field(original
->ocamlValues
,
1354 if (Field(original
->ocamlValues
, OcamlErrorBuffer
) != Val_unit
)
1355 handleErrorBuffer(connection
, Field(original
->ocamlValues
,
1357 if (Field(original
->ocamlValues
, OcamlPostFields
) != Val_unit
)
1358 handlePostFields(connection
, Field(original
->ocamlValues
,
1360 if (Field(original
->ocamlValues
, OcamlReferer
) != Val_unit
)
1361 handleReferer(connection
, Field(original
->ocamlValues
,
1363 if (Field(original
->ocamlValues
, OcamlUserAgent
) != Val_unit
)
1364 handleUserAgent(connection
, Field(original
->ocamlValues
,
1366 if (Field(original
->ocamlValues
, OcamlFTPPort
) != Val_unit
)
1367 handleFTPPort(connection
, Field(original
->ocamlValues
,
1369 if (Field(original
->ocamlValues
, OcamlCookie
) != Val_unit
)
1370 handleCookie(connection
, Field(original
->ocamlValues
,
1372 if (Field(original
->ocamlValues
, OcamlHTTPHeader
) != Val_unit
)
1373 handleHTTPHeader(connection
, Field(original
->ocamlValues
,
1375 if (Field(original
->ocamlValues
, OcamlHTTPPost
) != Val_unit
)
1376 handleHTTPPost(connection
, Field(original
->ocamlValues
,
1378 if (Field(original
->ocamlValues
, OcamlSSLCert
) != Val_unit
)
1379 handleSSLCert(connection
, Field(original
->ocamlValues
,
1381 if (Field(original
->ocamlValues
, OcamlSSLCertType
) != Val_unit
)
1382 handleSSLCertType(connection
, Field(original
->ocamlValues
,
1384 if (Field(original
->ocamlValues
, OcamlSSLCertPasswd
) != Val_unit
)
1385 handleSSLCertPasswd(connection
, Field(original
->ocamlValues
,
1386 OcamlSSLCertPasswd
));
1387 if (Field(original
->ocamlValues
, OcamlSSLKey
) != Val_unit
)
1388 handleSSLKey(connection
, Field(original
->ocamlValues
,
1390 if (Field(original
->ocamlValues
, OcamlSSLKeyType
) != Val_unit
)
1391 handleSSLKeyType(connection
, Field(original
->ocamlValues
,
1393 if (Field(original
->ocamlValues
, OcamlSSLKeyPasswd
) != Val_unit
)
1394 handleSSLKeyPasswd(connection
, Field(original
->ocamlValues
,
1395 OcamlSSLKeyPasswd
));
1396 if (Field(original
->ocamlValues
, OcamlSSLEngine
) != Val_unit
)
1397 handleSSLEngine(connection
, Field(original
->ocamlValues
,
1399 if (Field(original
->ocamlValues
, OcamlQuote
) != Val_unit
)
1400 handleQuote(connection
, Field(original
->ocamlValues
,
1402 if (Field(original
->ocamlValues
, OcamlPostQuote
) != Val_unit
)
1403 handlePostQuote(connection
, Field(original
->ocamlValues
,
1405 if (Field(original
->ocamlValues
, OcamlCookieFile
) != Val_unit
)
1406 handleCookieFile(connection
, Field(original
->ocamlValues
,
1408 if (Field(original
->ocamlValues
, OcamlCustomRequest
) != Val_unit
)
1409 handleCustomRequest(connection
, Field(original
->ocamlValues
,
1410 OcamlCustomRequest
));
1411 if (Field(original
->ocamlValues
, OcamlInterface
) != Val_unit
)
1412 handleInterface(connection
, Field(original
->ocamlValues
,
1414 if (Field(original
->ocamlValues
, OcamlCAInfo
) != Val_unit
)
1415 handleCAInfo(connection
, Field(original
->ocamlValues
,
1417 if (Field(original
->ocamlValues
, OcamlCAPath
) != Val_unit
)
1418 handleCAPath(connection
, Field(original
->ocamlValues
,
1420 if (Field(original
->ocamlValues
, OcamlRandomFile
) != Val_unit
)
1421 handleRandomFile(connection
, Field(original
->ocamlValues
,
1423 if (Field(original
->ocamlValues
, OcamlEGDSocket
) != Val_unit
)
1424 handleEGDSocket(connection
, Field(original
->ocamlValues
,
1426 if (Field(original
->ocamlValues
, OcamlCookieJar
) != Val_unit
)
1427 handleCookieJar(connection
, Field(original
->ocamlValues
,
1429 if (Field(original
->ocamlValues
, OcamlSSLCipherList
) != Val_unit
)
1430 handleSSLCipherList(connection
, Field(original
->ocamlValues
,
1431 OcamlSSLCipherList
));
1432 if (Field(original
->ocamlValues
, OcamlPrivate
) != Val_unit
)
1433 handlePrivate(connection
, Field(original
->ocamlValues
,
1435 if (Field(original
->ocamlValues
, OcamlHTTP200Aliases
) != Val_unit
)
1436 handleHTTP200Aliases(connection
, Field(original
->ocamlValues
,
1437 OcamlHTTP200Aliases
));
1438 if (Field(original
->ocamlValues
, OcamlNETRCFile
) != Val_unit
)
1439 handleNETRCFile(connection
, Field(original
->ocamlValues
,
1441 if (Field(original
->ocamlValues
, OcamlFTPAccount
) != Val_unit
)
1442 handleFTPAccount(connection
, Field(original
->ocamlValues
,
1444 if (Field(original
->ocamlValues
, OcamlCookieList
) != Val_unit
)
1445 handleCookieList(connection
, Field(original
->ocamlValues
,
1447 if (Field(original
->ocamlValues
, OcamlFTPAlternativeToUser
) != Val_unit
)
1448 handleFTPAlternativeToUser(connection
,
1449 Field(original
->ocamlValues
,
1450 OcamlFTPAlternativeToUser
));
1451 if (Field(original
->ocamlValues
, OcamlSSHPublicKeyFile
) != Val_unit
)
1452 handleSSHPublicKeyFile(connection
,
1453 Field(original
->ocamlValues
,
1454 OcamlSSHPublicKeyFile
));
1455 if (Field(original
->ocamlValues
, OcamlSSHPrivateKeyFile
) != Val_unit
)
1456 handleSSHPrivateKeyFile(connection
,
1457 Field(original
->ocamlValues
,
1458 OcamlSSHPrivateKeyFile
));
1459 if (Field(original
->ocamlValues
, OcamlCopyPostFields
) != Val_unit
)
1460 handleCopyPostFields(connection
,
1461 Field(original
->ocamlValues
,
1462 OcamlCopyPostFields
));
1467 static void free_if(void* p
) { if (NULL
!= p
) free(p
); }
1469 static void removeConnection(Connection
*connection
)
1471 enter_blocking_section();
1472 curl_easy_cleanup(connection
->connection
);
1473 leave_blocking_section();
1475 if (connectionList
.tail
== connection
)
1476 connectionList
.tail
= connectionList
.tail
->next
;
1477 if (connectionList
.head
== connection
)
1478 connectionList
.head
= connectionList
.head
->prev
;
1480 if (connection
->next
!= NULL
)
1481 connection
->next
->prev
= connection
->prev
;
1482 if (connection
->prev
!= NULL
)
1483 connection
->prev
->next
= connection
->next
;
1485 remove_global_root(&connection
->ocamlValues
);
1487 free_if(connection
->url
);
1488 free_if(connection
->proxy
);
1489 free_if(connection
->userPwd
);
1490 free_if(connection
->proxyUserPwd
);
1491 free_if(connection
->range
);
1492 free_if(connection
->errorBuffer
);
1493 free_if(connection
->postFields
);
1494 free_if(connection
->referer
);
1495 free_if(connection
->userAgent
);
1496 free_if(connection
->ftpPort
);
1497 free_if(connection
->cookie
);
1498 free_curl_slist(connection
->httpHeader
);
1499 if (connection
->httpPostFirst
!= NULL
)
1500 curl_formfree(connection
->httpPostFirst
);
1501 free_curl_slist(connection
->httpPostStrings
);
1502 free_curl_slist(connection
->resolve
);
1503 free_if(connection
->sslCert
);
1504 free_if(connection
->sslCertType
);
1505 free_if(connection
->sslCertPasswd
);
1506 free_if(connection
->sslKey
);
1507 free_if(connection
->sslKeyType
);
1508 free_if(connection
->sslKeyPasswd
);
1509 free_if(connection
->sslEngine
);
1510 free_curl_slist(connection
->quote
);
1511 free_curl_slist(connection
->postQuote
);
1512 free_if(connection
->cookieFile
);
1513 free_if(connection
->customRequest
);
1514 free_if(connection
->interface_
);
1515 free_if(connection
->caInfo
);
1516 free_if(connection
->caPath
);
1517 free_if(connection
->randomFile
);
1518 free_if(connection
->egdSocket
);
1519 free_if(connection
->cookieJar
);
1520 free_if(connection
->sslCipherList
);
1521 free_if(connection
->private);
1522 free_curl_slist(connection
->http200Aliases
);
1523 free_if(connection
->netrcFile
);
1524 free_if(connection
->ftpaccount
);
1525 free_if(connection
->cookielist
);
1526 free_if(connection
->ftpAlternativeToUser
);
1527 free_if(connection
->sshPublicKeyFile
);
1528 free_if(connection
->sshPrivateKeyFile
);
1529 free_if(connection
->copyPostFields
);
1530 free_if(connection
->dns_servers
);
1536 static void checkConnection(Connection
* connection
)
1541 static void checkConnection(Connection
*connection
)
1543 Connection
*listIter
;
1545 listIter
= connectionList
.tail
;
1547 while (listIter
!= NULL
)
1549 if (listIter
== connection
)
1552 listIter
= listIter
->next
;
1555 failwith("Invalid Connection");
1559 static Connection
* findConnection(CURL
* h
)
1561 Connection
*listIter
;
1563 listIter
= connectionList
.tail
;
1565 while (listIter
!= NULL
)
1567 if (listIter
->connection
== h
)
1570 listIter
= listIter
->next
;
1573 failwith("Unknown handle");
1576 #define WRAP_DATA_CALLBACK(f) \
1577 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1580 leave_blocking_section();\
1581 result = f##_nolock(ptr,size,nmemb,data);\
1582 enter_blocking_section();\
1586 static size_t writeFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1589 CAMLlocal2(result
, str
);
1590 Connection
*conn
= (Connection
*)data
;
1593 checkConnection(conn
);
1595 str
= alloc_string(size
*nmemb
);
1597 for (i
= 0; i
< size
*nmemb
; i
++)
1598 Byte(str
, i
) = ptr
[i
];
1600 result
= callback(Field(conn
->ocamlValues
, OcamlWriteCallback
), str
);
1602 CAMLreturnT(size_t, Int_val(result
));
1605 WRAP_DATA_CALLBACK(writeFunction
)
1607 static size_t readFunction_nolock(void *ptr
, size_t size
, size_t nmemb
, void *data
)
1611 Connection
*conn
= (Connection
*)data
;
1614 checkConnection(conn
);
1616 result
= callback(Field(conn
->ocamlValues
, OcamlReadCallback
),
1617 Val_int(size
*nmemb
));
1619 length
= string_length(result
);
1621 if (length
>= size
*nmemb
)
1622 length
= size
*nmemb
;
1624 memcpy(ptr
, String_val(result
), length
);
1626 CAMLreturnT(size_t,length
);
1629 WRAP_DATA_CALLBACK(readFunction
)
1631 static size_t headerFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1634 CAMLlocal2(result
,str
);
1635 Connection
*conn
= (Connection
*)data
;
1638 checkConnection(conn
);
1640 str
= alloc_string(size
*nmemb
);
1642 for (i
= 0; i
< size
*nmemb
; i
++)
1643 Byte(str
, i
) = ptr
[i
];
1645 result
= callback(Field(conn
->ocamlValues
, OcamlHeaderCallback
), str
);
1647 CAMLreturnT(size_t, Int_val(result
));
1650 WRAP_DATA_CALLBACK(headerFunction
)
1652 static int progressFunction_nolock(void *data
,
1660 CAMLlocalN(callbackData
, 4);
1661 Connection
*conn
= (Connection
*)data
;
1663 checkConnection(conn
);
1665 callbackData
[0] = copy_double(dlTotal
);
1666 callbackData
[1] = copy_double(dlNow
);
1667 callbackData
[2] = copy_double(ulTotal
);
1668 callbackData
[3] = copy_double(ulNow
);
1670 result
= callbackN(Field(conn
->ocamlValues
, OcamlProgressCallback
),
1673 CAMLreturnT(int, Bool_val(result
));
1676 static int progressFunction(void *data
,
1683 leave_blocking_section();
1684 r
= progressFunction_nolock(data
,dlTotal
,dlNow
,ulTotal
,ulNow
);
1685 enter_blocking_section();
1689 static int debugFunction_nolock(CURL
*debugConnection
,
1690 curl_infotype infoType
,
1692 size_t bufferLength
,
1696 CAMLlocal3(camlDebugConnection
, camlInfoType
, camlMessage
);
1698 Connection
*conn
= (Connection
*)data
;
1699 (void)debugConnection
; /* not used */
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
,
1715 CAMLreturnT(int, 0);
1718 static int debugFunction(CURL
*debugConnection
,
1719 curl_infotype infoType
,
1721 size_t bufferLength
,
1725 leave_blocking_section();
1726 r
= debugFunction_nolock(debugConnection
, infoType
, buffer
, bufferLength
, data
);
1727 enter_blocking_section();
1731 static curlioerr
ioctlFunction_nolock(CURL
*ioctl
,
1736 CAMLlocal3(camlResult
, camlConnection
, camlCmd
);
1737 Connection
*conn
= (Connection
*)data
;
1738 curlioerr result
= CURLIOE_OK
;
1739 (void)ioctl
; /* not used */
1741 checkConnection(conn
);
1743 if (cmd
== CURLIOCMD_NOP
)
1744 camlCmd
= Val_long(0);
1745 else if (cmd
== CURLIOCMD_RESTARTREAD
)
1746 camlCmd
= Val_long(1);
1748 failwith("Invalid IOCTL Cmd!");
1750 camlConnection
= caml_alloc(1, Abstract_tag
);
1751 Field(camlConnection
, 0) = (value
)conn
;
1753 camlResult
= callback2(Field(conn
->ocamlValues
, OcamlIOCTLCallback
),
1757 switch (Long_val(camlResult
))
1759 case 0: /* CURLIOE_OK */
1760 result
= CURLIOE_OK
;
1763 case 1: /* CURLIOE_UNKNOWNCMD */
1764 result
= CURLIOE_UNKNOWNCMD
;
1767 case 2: /* CURLIOE_FAILRESTART */
1768 result
= CURLIOE_FAILRESTART
;
1771 default: /* Incorrect return value, but let's handle it */
1772 result
= CURLIOE_FAILRESTART
;
1776 CAMLreturnT(curlioerr
, result
);
1779 static curlioerr
ioctlFunction(CURL
*ioctl
,
1784 leave_blocking_section();
1785 r
= ioctlFunction_nolock(ioctl
, cmd
, data
);
1786 enter_blocking_section();
1790 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1791 static int seekFunction_nolock(void *data
,
1796 CAMLlocal3(camlResult
, camlOffset
, camlOrigin
);
1797 Connection
*conn
= (Connection
*)data
;
1800 camlOffset
= copy_int64(offset
);
1802 if (origin
== SEEK_SET
)
1803 camlOrigin
= Val_long(0);
1804 else if (origin
== SEEK_CUR
)
1805 camlOrigin
= Val_long(1);
1806 else if (origin
== SEEK_END
)
1807 camlOrigin
= Val_long(2);
1809 camlOrigin
= Val_long(0);
1811 camlResult
= callback2(Field(conn
->ocamlValues
,
1812 OcamlSeekFunctionCallback
),
1816 result
= Int_val(camlResult
);
1818 CAMLreturnT(int, result
);
1821 static int seekFunction(void *data
,
1826 leave_blocking_section();
1827 r
= seekFunction_nolock(data
,offset
,origin
);
1828 enter_blocking_section();
1834 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
1835 static int openSocketFunction_nolock(void *data
,
1836 curlsocktype purpose
,
1837 struct curl_sockaddr
*addr
)
1840 Connection
*conn
= (Connection
*)data
;
1842 (void)purpose
; /* not used */
1844 sock
= socket(addr
->family
, addr
->socktype
, addr
->protocol
);
1849 callback(Field(conn
->ocamlValues
, OcamlOpenSocketFunctionCallback
), Val_int(sock
));
1852 CAMLreturnT(int, sock
);
1855 static int openSocketFunction(void *data
,
1856 curlsocktype purpose
,
1857 struct curl_sockaddr
*address
)
1860 leave_blocking_section();
1861 r
= openSocketFunction_nolock(data
,purpose
,address
);
1862 enter_blocking_section();
1869 ** curl_global_init helper function
1872 CAMLprim value
helper_curl_global_init(value initOption
)
1874 CAMLparam1(initOption
);
1876 switch (Long_val(initOption
))
1878 case 0: /* CURLINIT_GLOBALALL */
1879 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL
)));
1882 case 1: /* CURLINIT_GLOBALSSL */
1883 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL
)));
1886 case 2: /* CURLINIT_GLOBALWIN32 */
1887 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32
)));
1890 case 3: /* CURLINIT_GLOBALNOTHING */
1891 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING
)));
1895 failwith("Invalid Initialization Option");
1899 /* Keep compiler happy, we should never get here due to failwith() */
1900 CAMLreturn(Val_unit
);
1904 ** curl_global_cleanup helper function
1907 CAMLprim value
helper_curl_global_cleanup(void)
1911 curl_global_cleanup();
1913 CAMLreturn(Val_unit
);
1917 ** curl_easy_init helper function
1920 CAMLprim value
helper_curl_easy_init(void)
1925 Connection
*conn
= newConnection();
1927 result
= caml_alloc(1, Abstract_tag
);
1928 Field(result
, 0) = (value
)conn
;
1933 CAMLprim value
helper_curl_easy_reset(value conn
)
1936 Connection
*connection
= Connection_val(conn
);
1938 checkConnection(connection
);
1939 curl_easy_reset(connection
->connection
);
1940 resetOcamlValues(connection
);
1942 CAMLreturn(Val_unit
);
1946 ** curl_easy_setopt helper utility functions
1949 static void handleWriteFunction(Connection
*conn
, value option
)
1952 CURLcode result
= CURLE_OK
;
1954 if (Tag_val(option
) == Closure_tag
)
1955 Store_field(conn
->ocamlValues
, OcamlWriteCallback
, option
);
1957 failwith("Not a proper closure");
1959 result
= curl_easy_setopt(conn
->connection
,
1960 CURLOPT_WRITEFUNCTION
,
1963 if (result
!= CURLE_OK
)
1964 raiseError(conn
, result
);
1966 result
= curl_easy_setopt(conn
->connection
,
1970 if (result
!= CURLE_OK
)
1971 raiseError(conn
, result
);
1976 static void handleReadFunction(Connection
*conn
, value option
)
1979 CURLcode result
= CURLE_OK
;
1981 if (Tag_val(option
) == Closure_tag
)
1982 Store_field(conn
->ocamlValues
, OcamlReadCallback
, option
);
1984 failwith("Not a proper closure");
1986 result
= curl_easy_setopt(conn
->connection
,
1987 CURLOPT_READFUNCTION
,
1990 if (result
!= CURLE_OK
)
1991 raiseError(conn
, result
);
1993 result
= curl_easy_setopt(conn
->connection
,
1997 if (result
!= CURLE_OK
)
1998 raiseError(conn
, result
);
2003 static void handleURL(Connection
*conn
, value option
)
2006 CURLcode result
= CURLE_OK
;
2008 Store_field(conn
->ocamlValues
, OcamlURL
, option
);
2010 if (conn
->url
!= NULL
)
2013 conn
->url
= strdup(String_val(option
));
2015 result
= curl_easy_setopt(conn
->connection
,
2019 if (result
!= CURLE_OK
)
2020 raiseError(conn
, result
);
2025 static void handleInFileSize(Connection
*conn
, value option
)
2028 CURLcode result
= CURLE_OK
;
2030 result
= curl_easy_setopt(conn
->connection
,
2034 if (result
!= CURLE_OK
)
2035 raiseError(conn
, result
);
2040 static void handleProxy(Connection
*conn
, value option
)
2043 CURLcode result
= CURLE_OK
;
2045 Store_field(conn
->ocamlValues
, OcamlProxy
, option
);
2047 if (conn
->proxy
!= NULL
)
2050 conn
->proxy
= strdup(String_val(option
));
2052 result
= curl_easy_setopt(conn
->connection
,
2056 if (result
!= CURLE_OK
)
2057 raiseError(conn
, result
);
2062 static void handleProxyPort(Connection
*conn
, value option
)
2065 CURLcode result
= CURLE_OK
;
2067 result
= curl_easy_setopt(conn
->connection
,
2071 if (result
!= CURLE_OK
)
2072 raiseError(conn
, result
);
2077 static void handleHTTPProxyTunnel(Connection
*conn
, value option
)
2080 CURLcode result
= CURLE_OK
;
2082 result
= curl_easy_setopt(conn
->connection
,
2083 CURLOPT_HTTPPROXYTUNNEL
,
2086 if (result
!= CURLE_OK
)
2087 raiseError(conn
, result
);
2092 static void handleVerbose(Connection
*conn
, value option
)
2095 CURLcode result
= CURLE_OK
;
2097 result
= curl_easy_setopt(conn
->connection
,
2101 if (result
!= CURLE_OK
)
2102 raiseError(conn
, result
);
2107 static void handleHeader(Connection
*conn
, value option
)
2110 CURLcode result
= CURLE_OK
;
2112 result
= curl_easy_setopt(conn
->connection
,
2116 if (result
!= CURLE_OK
)
2117 raiseError(conn
, result
);
2122 static void handleNoProgress(Connection
*conn
, value option
)
2125 CURLcode result
= CURLE_OK
;
2127 result
= curl_easy_setopt(conn
->connection
,
2131 if (result
!= CURLE_OK
)
2132 raiseError(conn
, result
);
2137 static void handleNoSignal(Connection
*conn
, value option
)
2139 #if HAVE_DECL_CURLOPT_NOSIGNAL
2141 CURLcode result
= CURLE_OK
;
2143 result
= curl_easy_setopt(conn
->connection
,
2147 if (result
!= CURLE_OK
)
2148 raiseError(conn
, result
);
2152 #pragma message("libcurl does not implement CURLOPT_NOSIGNAL")
2153 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2157 static void handleNoBody(Connection
*conn
, value option
)
2160 CURLcode result
= CURLE_OK
;
2162 result
= curl_easy_setopt(conn
->connection
,
2166 if (result
!= CURLE_OK
)
2167 raiseError(conn
, result
);
2172 static void handleFailOnError(Connection
*conn
, value option
)
2175 CURLcode result
= CURLE_OK
;
2177 result
= curl_easy_setopt(conn
->connection
,
2178 CURLOPT_FAILONERROR
,
2181 if (result
!= CURLE_OK
)
2182 raiseError(conn
, result
);
2187 static void handleUpload(Connection
*conn
, value option
)
2190 CURLcode result
= CURLE_OK
;
2192 result
= curl_easy_setopt(conn
->connection
,
2196 if (result
!= CURLE_OK
)
2197 raiseError(conn
, result
);
2202 static void handlePost(Connection
*conn
, value option
)
2205 CURLcode result
= CURLE_OK
;
2207 result
= curl_easy_setopt(conn
->connection
,
2211 if (result
!= CURLE_OK
)
2212 raiseError(conn
, result
);
2217 static void handleFTPListOnly(Connection
*conn
, value option
)
2220 CURLcode result
= CURLE_OK
;
2222 result
= curl_easy_setopt(conn
->connection
,
2223 CURLOPT_FTPLISTONLY
,
2226 if (result
!= CURLE_OK
)
2227 raiseError(conn
, result
);
2232 static void handleFTPAppend(Connection
*conn
, value option
)
2235 CURLcode result
= CURLE_OK
;
2237 result
= curl_easy_setopt(conn
->connection
,
2241 if (result
!= CURLE_OK
)
2242 raiseError(conn
, result
);
2247 static void handleNETRC(Connection
*conn
, value option
)
2250 CURLcode result
= CURLE_OK
;
2253 switch (Long_val(option
))
2255 case 0: /* CURL_NETRC_OPTIONAL */
2256 netrc
= CURL_NETRC_OPTIONAL
;
2259 case 1:/* CURL_NETRC_IGNORED */
2260 netrc
= CURL_NETRC_IGNORED
;
2263 case 2: /* CURL_NETRC_REQUIRED */
2264 netrc
= CURL_NETRC_REQUIRED
;
2268 failwith("Invalid NETRC Option");
2272 result
= curl_easy_setopt(conn
->connection
,
2276 if (result
!= CURLE_OK
)
2277 raiseError(conn
, result
);
2282 static void handleEncoding(Connection
*conn
, value option
)
2284 #if HAVE_DECL_CURLOPT_ENCODING
2286 CURLcode result
= CURLE_OK
;
2288 switch (Long_val(option
))
2290 case 0: /* CURL_ENCODING_NONE */
2291 result
= curl_easy_setopt(conn
->connection
,
2296 case 1: /* CURL_ENCODING_DEFLATE */
2297 result
= curl_easy_setopt(conn
->connection
,
2302 case 2: /* CURL_ENCODING_GZIP */
2303 result
= curl_easy_setopt(conn
->connection
,
2308 case 3: /* CURL_ENCODING_ANY */
2309 result
= curl_easy_setopt(conn
->connection
,
2315 failwith("Invalid Encoding Option");
2319 if (result
!= CURLE_OK
)
2320 raiseError(conn
, result
);
2324 #pragma message("libcurl does not implement CURLOPT_ENCODING")
2325 failwith("libcurl does not implement CURLOPT_ENCODING");
2329 static void handleFollowLocation(Connection
*conn
, value option
)
2332 CURLcode result
= CURLE_OK
;
2334 result
= curl_easy_setopt(conn
->connection
,
2335 CURLOPT_FOLLOWLOCATION
,
2338 if (result
!= CURLE_OK
)
2339 raiseError(conn
, result
);
2344 static void handleTransferText(Connection
*conn
, value option
)
2347 CURLcode result
= CURLE_OK
;
2349 result
= curl_easy_setopt(conn
->connection
,
2350 CURLOPT_TRANSFERTEXT
,
2353 if (result
!= CURLE_OK
)
2354 raiseError(conn
, result
);
2359 static void handlePut(Connection
*conn
, value option
)
2362 CURLcode result
= CURLE_OK
;
2364 result
= curl_easy_setopt(conn
->connection
,
2368 if (result
!= CURLE_OK
)
2369 raiseError(conn
, result
);
2374 static void handleUserPwd(Connection
*conn
, value option
)
2377 CURLcode result
= CURLE_OK
;
2379 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2381 if (conn
->userPwd
!= NULL
)
2382 free(conn
->userPwd
);
2384 conn
->userPwd
= strdup(String_val(option
));
2386 result
= curl_easy_setopt(conn
->connection
,
2390 if (result
!= CURLE_OK
)
2391 raiseError(conn
, result
);
2396 static void handleProxyUserPwd(Connection
*conn
, value option
)
2399 CURLcode result
= CURLE_OK
;
2401 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2403 if (conn
->proxyUserPwd
!= NULL
)
2404 free(conn
->proxyUserPwd
);
2406 conn
->proxyUserPwd
= strdup(String_val(option
));
2408 result
= curl_easy_setopt(conn
->connection
,
2409 CURLOPT_PROXYUSERPWD
,
2410 conn
->proxyUserPwd
);
2412 if (result
!= CURLE_OK
)
2413 raiseError(conn
, result
);
2418 static void handleRange(Connection
*conn
, value option
)
2421 CURLcode result
= CURLE_OK
;
2423 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2425 if (conn
->range
!= NULL
)
2428 conn
->range
= strdup(String_val(option
));
2430 result
= curl_easy_setopt(conn
->connection
,
2434 if (result
!= CURLE_OK
)
2435 raiseError(conn
, result
);
2440 static void handleErrorBuffer(Connection
*conn
, value option
)
2443 CURLcode result
= CURLE_OK
;
2445 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2447 if (conn
->errorBuffer
!= NULL
)
2448 free(conn
->errorBuffer
);
2450 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2452 result
= curl_easy_setopt(conn
->connection
,
2453 CURLOPT_ERRORBUFFER
,
2456 if (result
!= CURLE_OK
)
2457 raiseError(conn
, result
);
2462 static void handleTimeout(Connection
*conn
, value option
)
2465 CURLcode result
= CURLE_OK
;
2467 result
= curl_easy_setopt(conn
->connection
,
2471 if (result
!= CURLE_OK
)
2472 raiseError(conn
, result
);
2477 static void handlePostFields(Connection
*conn
, value option
)
2480 CURLcode result
= CURLE_OK
;
2482 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2484 if (conn
->postFields
!= NULL
)
2485 free(conn
->postFields
);
2487 conn
->postFields
= malloc(string_length(option
)+1);
2488 memcpy(conn
->postFields
, String_val(option
), string_length(option
)+1);
2490 result
= curl_easy_setopt(conn
->connection
,
2494 if (result
!= CURLE_OK
)
2495 raiseError(conn
, result
);
2500 static void handlePostFieldSize(Connection
*conn
, value option
)
2503 CURLcode result
= CURLE_OK
;
2505 result
= curl_easy_setopt(conn
->connection
,
2506 CURLOPT_POSTFIELDSIZE
,
2509 if (result
!= CURLE_OK
)
2510 raiseError(conn
, result
);
2515 static void handleReferer(Connection
*conn
, value option
)
2518 CURLcode result
= CURLE_OK
;
2520 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2522 if (conn
->referer
!= NULL
)
2523 free(conn
->referer
);
2525 conn
->referer
= strdup(String_val(option
));
2527 result
= curl_easy_setopt(conn
->connection
,
2531 if (result
!= CURLE_OK
)
2532 raiseError(conn
, result
);
2537 static void handleUserAgent(Connection
*conn
, value option
)
2540 CURLcode result
= CURLE_OK
;
2542 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2544 if (conn
->userAgent
!= NULL
)
2545 free(conn
->userAgent
);
2547 conn
->userAgent
= strdup(String_val(option
));
2549 result
= curl_easy_setopt(conn
->connection
,
2553 if (result
!= CURLE_OK
)
2554 raiseError(conn
, result
);
2559 static void handleFTPPort(Connection
*conn
, value option
)
2562 CURLcode result
= CURLE_OK
;
2564 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2566 if (conn
->ftpPort
!= NULL
)
2567 free(conn
->ftpPort
);
2569 conn
->ftpPort
= strdup(String_val(option
));
2571 result
= curl_easy_setopt(conn
->connection
,
2575 if (result
!= CURLE_OK
)
2576 raiseError(conn
, result
);
2581 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2584 CURLcode result
= CURLE_OK
;
2586 result
= curl_easy_setopt(conn
->connection
,
2587 CURLOPT_LOW_SPEED_LIMIT
,
2590 if (result
!= CURLE_OK
)
2591 raiseError(conn
, result
);
2596 static void handleLowSpeedTime(Connection
*conn
, value option
)
2599 CURLcode result
= CURLE_OK
;
2601 result
= curl_easy_setopt(conn
->connection
,
2602 CURLOPT_LOW_SPEED_TIME
,
2605 if (result
!= CURLE_OK
)
2606 raiseError(conn
, result
);
2611 static void handleResumeFrom(Connection
*conn
, value option
)
2614 CURLcode result
= CURLE_OK
;
2616 result
= curl_easy_setopt(conn
->connection
,
2617 CURLOPT_RESUME_FROM
,
2620 if (result
!= CURLE_OK
)
2621 raiseError(conn
, result
);
2626 static void handleCookie(Connection
*conn
, value option
)
2629 CURLcode result
= CURLE_OK
;
2631 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2633 if (conn
->cookie
!= NULL
)
2636 conn
->cookie
= strdup(String_val(option
));
2638 result
= curl_easy_setopt(conn
->connection
,
2642 if (result
!= CURLE_OK
)
2643 raiseError(conn
, result
);
2648 static void handleHTTPHeader(Connection
*conn
, value option
)
2651 CAMLlocal1(listIter
);
2652 CURLcode result
= CURLE_OK
;
2654 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2656 free_curl_slist(conn
->httpHeader
);
2657 conn
->httpHeader
= NULL
;
2661 while (!Is_long(listIter
))
2663 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, String_val(Field(listIter
, 0)));
2665 listIter
= Field(listIter
, 1);
2668 result
= curl_easy_setopt(conn
->connection
,
2672 if (result
!= CURLE_OK
)
2673 raiseError(conn
, result
);
2678 static void handleHTTPPost(Connection
*conn
, value option
)
2681 CAMLlocal3(listIter
, formItem
, contentType
);
2682 CURLcode result
= CURLE_OK
;
2683 char *str1
, *str2
, *str3
, *str4
;
2687 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2689 if (conn
->httpPostFirst
!= NULL
)
2690 curl_formfree(conn
->httpPostFirst
);
2692 conn
->httpPostFirst
= NULL
;
2693 conn
->httpPostLast
= NULL
;
2695 free_curl_slist(conn
->httpPostStrings
);
2696 conn
->httpPostStrings
= NULL
;
2698 while (!Is_long(listIter
))
2700 formItem
= Field(listIter
, 0);
2702 switch (Tag_val(formItem
))
2704 case 0: /* CURLFORM_CONTENT */
2705 if (Wosize_val(formItem
) < 3)
2707 failwith("Incorrect CURLFORM_CONTENT parameters");
2710 if (Is_long(Field(formItem
, 2)) &&
2711 Long_val(Field(formItem
, 2)) == 0)
2713 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2715 String_val(Field(formItem
, 0)),
2716 string_length(Field(formItem
, 0)));
2717 str1
[string_length(Field(formItem
, 0))] = 0;
2718 conn
->httpPostStrings
=
2719 curl_slist_append(conn
->httpPostStrings
, str1
);
2721 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2723 String_val(Field(formItem
, 1)),
2724 string_length(Field(formItem
, 1)));
2725 str2
[string_length(Field(formItem
, 1))] = 0;
2726 conn
->httpPostStrings
=
2727 curl_slist_append(conn
->httpPostStrings
, str2
);
2729 curl_formadd(&conn
->httpPostFirst
,
2730 &conn
->httpPostLast
,
2733 CURLFORM_NAMELENGTH
,
2734 string_length(Field(formItem
, 0)),
2735 CURLFORM_PTRCONTENTS
,
2737 CURLFORM_CONTENTSLENGTH
,
2738 string_length(Field(formItem
, 1)),
2741 else if (Is_block(Field(formItem
, 2)))
2743 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2745 String_val(Field(formItem
, 0)),
2746 string_length(Field(formItem
, 0)));
2747 str1
[string_length(Field(formItem
, 0))] = 0;
2748 conn
->httpPostStrings
=
2749 curl_slist_append(conn
->httpPostStrings
, str1
);
2751 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2753 String_val(Field(formItem
, 1)),
2754 string_length(Field(formItem
, 1)));
2755 str2
[string_length(Field(formItem
, 1))] = 0;
2756 conn
->httpPostStrings
=
2757 curl_slist_append(conn
->httpPostStrings
, str2
);
2759 contentType
= Field(formItem
, 2);
2761 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2763 String_val(Field(contentType
, 0)),
2764 string_length(Field(contentType
, 0)));
2765 str3
[string_length(Field(contentType
, 0))] = 0;
2766 conn
->httpPostStrings
=
2767 curl_slist_append(conn
->httpPostStrings
, str3
);
2769 curl_formadd(&conn
->httpPostFirst
,
2770 &conn
->httpPostLast
,
2773 CURLFORM_NAMELENGTH
,
2774 string_length(Field(formItem
, 0)),
2775 CURLFORM_PTRCONTENTS
,
2777 CURLFORM_CONTENTSLENGTH
,
2778 string_length(Field(formItem
, 1)),
2779 CURLFORM_CONTENTTYPE
,
2785 failwith("Incorrect CURLFORM_CONTENT parameters");
2789 case 1: /* CURLFORM_FILECONTENT */
2790 if (Wosize_val(formItem
) < 3)
2792 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2795 if (Is_long(Field(formItem
, 2)) &&
2796 Long_val(Field(formItem
, 2)) == 0)
2798 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2800 String_val(Field(formItem
, 0)),
2801 string_length(Field(formItem
, 0)));
2802 str1
[string_length(Field(formItem
, 0))] = 0;
2803 conn
->httpPostStrings
=
2804 curl_slist_append(conn
->httpPostStrings
, str1
);
2806 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2808 String_val(Field(formItem
, 1)),
2809 string_length(Field(formItem
, 1)));
2810 str2
[string_length(Field(formItem
, 1))] = 0;
2811 conn
->httpPostStrings
=
2812 curl_slist_append(conn
->httpPostStrings
, str2
);
2814 curl_formadd(&conn
->httpPostFirst
,
2815 &conn
->httpPostLast
,
2818 CURLFORM_NAMELENGTH
,
2819 string_length(Field(formItem
, 0)),
2820 CURLFORM_FILECONTENT
,
2824 else if (Is_block(Field(formItem
, 2)))
2826 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2828 String_val(Field(formItem
, 0)),
2829 string_length(Field(formItem
, 0)));
2830 str1
[string_length(Field(formItem
, 0))] = 0;
2831 conn
->httpPostStrings
=
2832 curl_slist_append(conn
->httpPostStrings
, str1
);
2834 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2836 String_val(Field(formItem
, 1)),
2837 string_length(Field(formItem
, 1)));
2838 str2
[string_length(Field(formItem
, 1))] = 0;
2839 conn
->httpPostStrings
=
2840 curl_slist_append(conn
->httpPostStrings
, str2
);
2842 contentType
= Field(formItem
, 2);
2844 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2846 String_val(Field(contentType
, 0)),
2847 string_length(Field(contentType
, 0)));
2848 str3
[string_length(Field(contentType
, 0))] = 0;
2849 conn
->httpPostStrings
=
2850 curl_slist_append(conn
->httpPostStrings
, str3
);
2852 curl_formadd(&conn
->httpPostFirst
,
2853 &conn
->httpPostLast
,
2856 CURLFORM_NAMELENGTH
,
2857 string_length(Field(formItem
, 0)),
2858 CURLFORM_FILECONTENT
,
2860 CURLFORM_CONTENTTYPE
,
2866 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2870 case 2: /* CURLFORM_FILE */
2871 if (Wosize_val(formItem
) < 3)
2873 failwith("Incorrect CURLFORM_FILE parameters");
2876 if (Is_long(Field(formItem
, 2)) &&
2877 Long_val(Field(formItem
, 2)) == 0)
2879 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2881 String_val(Field(formItem
, 0)),
2882 string_length(Field(formItem
, 0)));
2883 str1
[string_length(Field(formItem
, 0))] = 0;
2884 conn
->httpPostStrings
=
2885 curl_slist_append(conn
->httpPostStrings
, str1
);
2887 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2889 String_val(Field(formItem
, 1)),
2890 string_length(Field(formItem
, 1)));
2891 str2
[string_length(Field(formItem
, 1))] = 0;
2892 conn
->httpPostStrings
=
2893 curl_slist_append(conn
->httpPostStrings
, str2
);
2895 curl_formadd(&conn
->httpPostFirst
,
2896 &conn
->httpPostLast
,
2899 CURLFORM_NAMELENGTH
,
2900 string_length(Field(formItem
, 0)),
2905 else if (Is_block(Field(formItem
, 2)))
2907 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2909 String_val(Field(formItem
, 0)),
2910 string_length(Field(formItem
, 0)));
2911 str1
[string_length(Field(formItem
, 0))] = 0;
2912 conn
->httpPostStrings
=
2913 curl_slist_append(conn
->httpPostStrings
, str1
);
2915 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2917 String_val(Field(formItem
, 1)),
2918 string_length(Field(formItem
, 1)));
2919 str2
[string_length(Field(formItem
, 1))] = 0;
2920 conn
->httpPostStrings
=
2921 curl_slist_append(conn
->httpPostStrings
, str2
);
2923 contentType
= Field(formItem
, 2);
2925 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2927 String_val(Field(contentType
, 0)),
2928 string_length(Field(contentType
, 0)));
2929 str3
[string_length(Field(contentType
, 0))] = 0;
2930 conn
->httpPostStrings
=
2931 curl_slist_append(conn
->httpPostStrings
, str3
);
2933 curl_formadd(&conn
->httpPostFirst
,
2934 &conn
->httpPostLast
,
2937 CURLFORM_NAMELENGTH
,
2938 string_length(Field(formItem
, 0)),
2941 CURLFORM_CONTENTTYPE
,
2947 failwith("Incorrect CURLFORM_FILE parameters");
2951 case 3: /* CURLFORM_BUFFER */
2952 if (Wosize_val(formItem
) < 4)
2954 failwith("Incorrect CURLFORM_BUFFER parameters");
2957 if (Is_long(Field(formItem
, 3)) &&
2958 Long_val(Field(formItem
, 3)) == 0)
2960 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2962 String_val(Field(formItem
, 0)),
2963 string_length(Field(formItem
, 0)));
2964 str1
[string_length(Field(formItem
, 0))] = 0;
2965 conn
->httpPostStrings
=
2966 curl_slist_append(conn
->httpPostStrings
, str1
);
2968 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2970 String_val(Field(formItem
, 1)),
2971 string_length(Field(formItem
, 1)));
2972 str2
[string_length(Field(formItem
, 1))] = 0;
2973 conn
->httpPostStrings
=
2974 curl_slist_append(conn
->httpPostStrings
, str2
);
2976 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2978 String_val(Field(formItem
, 2)),
2979 string_length(Field(formItem
, 2)));
2980 str3
[string_length(Field(formItem
, 2))] = 0;
2981 conn
->httpPostStrings
=
2982 curl_slist_append(conn
->httpPostStrings
, str3
);
2984 curl_formadd(&conn
->httpPostFirst
,
2985 &conn
->httpPostLast
,
2988 CURLFORM_NAMELENGTH
,
2989 string_length(Field(formItem
, 0)),
2994 CURLFORM_BUFFERLENGTH
,
2995 string_length(Field(formItem
, 2)),
2998 else if (Is_block(Field(formItem
, 3)))
3000 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
3002 String_val(Field(formItem
, 0)),
3003 string_length(Field(formItem
, 0)));
3004 str1
[string_length(Field(formItem
, 0))] = 0;
3005 conn
->httpPostStrings
=
3006 curl_slist_append(conn
->httpPostStrings
, str1
);
3008 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
3010 String_val(Field(formItem
, 1)),
3011 string_length(Field(formItem
, 1)));
3012 str2
[string_length(Field(formItem
, 1))] = 0;
3013 conn
->httpPostStrings
=
3014 curl_slist_append(conn
->httpPostStrings
, str2
);
3016 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
3018 String_val(Field(formItem
, 2)),
3019 string_length(Field(formItem
, 2)));
3020 str3
[string_length(Field(formItem
, 2))] = 0;
3021 conn
->httpPostStrings
=
3022 curl_slist_append(conn
->httpPostStrings
, str3
);
3024 contentType
= Field(formItem
, 3);
3026 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
3028 String_val(Field(contentType
, 0)),
3029 string_length(Field(contentType
, 0)));
3030 str4
[string_length(Field(contentType
, 0))] = 0;
3031 conn
->httpPostStrings
=
3032 curl_slist_append(conn
->httpPostStrings
, str4
);
3034 curl_formadd(&conn
->httpPostFirst
,
3035 &conn
->httpPostLast
,
3038 CURLFORM_NAMELENGTH
,
3039 string_length(Field(formItem
, 0)),
3044 CURLFORM_BUFFERLENGTH
,
3045 string_length(Field(formItem
, 2)),
3046 CURLFORM_CONTENTTYPE
,
3052 failwith("Incorrect CURLFORM_BUFFER parameters");
3057 listIter
= Field(listIter
, 1);
3060 result
= curl_easy_setopt(conn
->connection
,
3062 conn
->httpPostFirst
);
3064 if (result
!= CURLE_OK
)
3065 raiseError(conn
, result
);
3070 static void handleSSLCert(Connection
*conn
, value option
)
3073 CURLcode result
= CURLE_OK
;
3075 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3077 if (conn
->sslCert
!= NULL
)
3078 free(conn
->sslCert
);
3080 conn
->sslCert
= strdup(String_val(option
));
3082 result
= curl_easy_setopt(conn
->connection
,
3086 if (result
!= CURLE_OK
)
3087 raiseError(conn
, result
);
3092 static void handleSSLCertType(Connection
*conn
, value option
)
3095 CURLcode result
= CURLE_OK
;
3097 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3099 if (conn
->sslCertType
!= NULL
)
3100 free(conn
->sslCertType
);
3102 conn
->sslCertType
= strdup(String_val(option
));
3104 result
= curl_easy_setopt(conn
->connection
,
3105 CURLOPT_SSLCERTTYPE
,
3108 if (result
!= CURLE_OK
)
3109 raiseError(conn
, result
);
3114 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3117 CURLcode result
= CURLE_OK
;
3119 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3121 if (conn
->sslCertPasswd
!= NULL
)
3122 free(conn
->sslCertPasswd
);
3124 conn
->sslCertPasswd
= strdup(String_val(option
));
3126 result
= curl_easy_setopt(conn
->connection
,
3127 CURLOPT_SSLCERTPASSWD
,
3128 conn
->sslCertPasswd
);
3130 if (result
!= CURLE_OK
)
3131 raiseError(conn
, result
);
3136 static void handleSSLKey(Connection
*conn
, value option
)
3139 CURLcode result
= CURLE_OK
;
3141 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3143 if (conn
->sslKey
!= NULL
)
3146 conn
->sslKey
= strdup(String_val(option
));
3148 result
= curl_easy_setopt(conn
->connection
,
3152 if (result
!= CURLE_OK
)
3153 raiseError(conn
, result
);
3158 static void handleSSLKeyType(Connection
*conn
, value option
)
3161 CURLcode result
= CURLE_OK
;
3163 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3165 if (conn
->sslKeyType
!= NULL
)
3166 free(conn
->sslKeyType
);
3168 conn
->sslKeyType
= strdup(String_val(option
));
3170 result
= curl_easy_setopt(conn
->connection
,
3174 if (result
!= CURLE_OK
)
3175 raiseError(conn
, result
);
3180 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3183 CURLcode result
= CURLE_OK
;
3185 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3187 if (conn
->sslKeyPasswd
!= NULL
)
3188 free(conn
->sslKeyPasswd
);
3190 conn
->sslKeyPasswd
= strdup(String_val(option
));
3192 result
= curl_easy_setopt(conn
->connection
,
3193 CURLOPT_SSLKEYPASSWD
,
3194 conn
->sslKeyPasswd
);
3196 if (result
!= CURLE_OK
)
3197 raiseError(conn
, result
);
3202 static void handleSSLEngine(Connection
*conn
, value option
)
3205 CURLcode result
= CURLE_OK
;
3207 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3209 if (conn
->sslEngine
!= NULL
)
3210 free(conn
->sslEngine
);
3212 conn
->sslEngine
= strdup(String_val(option
));
3214 result
= curl_easy_setopt(conn
->connection
,
3218 if (result
!= CURLE_OK
)
3219 raiseError(conn
, result
);
3224 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3227 CURLcode result
= CURLE_OK
;
3229 result
= curl_easy_setopt(conn
->connection
,
3230 CURLOPT_SSLENGINE_DEFAULT
,
3233 if (result
!= CURLE_OK
)
3234 raiseError(conn
, result
);
3239 static void handleCRLF(Connection
*conn
, value option
)
3242 CURLcode result
= CURLE_OK
;
3244 result
= curl_easy_setopt(conn
->connection
,
3248 if (result
!= CURLE_OK
)
3249 raiseError(conn
, result
);
3254 static void handleQuote(Connection
*conn
, value option
)
3257 CAMLlocal1(listIter
);
3258 CURLcode result
= CURLE_OK
;
3260 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3262 free_curl_slist(conn
->quote
);
3267 while (!Is_long(listIter
))
3269 conn
->quote
= curl_slist_append(conn
->quote
, String_val(Field(listIter
, 0)));
3271 listIter
= Field(listIter
, 1);
3274 result
= curl_easy_setopt(conn
->connection
,
3278 if (result
!= CURLE_OK
)
3279 raiseError(conn
, result
);
3284 static void handlePostQuote(Connection
*conn
, value option
)
3287 CAMLlocal1(listIter
);
3288 CURLcode result
= CURLE_OK
;
3290 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3292 free_curl_slist(conn
->postQuote
);
3293 conn
->postQuote
= NULL
;
3297 while (!Is_long(listIter
))
3299 conn
->postQuote
= curl_slist_append(conn
->postQuote
, String_val(Field(listIter
, 0)));
3301 listIter
= Field(listIter
, 1);
3304 result
= curl_easy_setopt(conn
->connection
,
3308 if (result
!= CURLE_OK
)
3309 raiseError(conn
, result
);
3314 static void handleHeaderFunction(Connection
*conn
, value option
)
3317 CURLcode result
= CURLE_OK
;
3319 if (Tag_val(option
) == Closure_tag
)
3320 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3322 failwith("Not a proper closure");
3324 result
= curl_easy_setopt(conn
->connection
,
3325 CURLOPT_HEADERFUNCTION
,
3328 if (result
!= CURLE_OK
)
3329 raiseError(conn
, result
);
3331 result
= curl_easy_setopt(conn
->connection
,
3332 CURLOPT_WRITEHEADER
,
3335 if (result
!= CURLE_OK
)
3336 raiseError(conn
, result
);
3341 static void handleCookieFile(Connection
*conn
, value option
)
3344 CURLcode result
= CURLE_OK
;
3346 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3348 if (conn
->cookieFile
!= NULL
)
3349 free(conn
->cookieFile
);
3351 conn
->cookieFile
= strdup(String_val(option
));
3353 result
= curl_easy_setopt(conn
->connection
,
3357 if (result
!= CURLE_OK
)
3358 raiseError(conn
, result
);
3363 static void handleSSLVersion(Connection
*conn
, value option
)
3366 CURLcode result
= CURLE_OK
;
3368 result
= curl_easy_setopt(conn
->connection
,
3372 if (result
!= CURLE_OK
)
3373 raiseError(conn
, result
);
3378 static void handleTimeCondition(Connection
*conn
, value option
)
3381 CURLcode result
= CURLE_OK
;
3383 switch (Long_val(option
))
3385 case 0: /* TIMECOND_IFMODSINCE */
3386 result
= curl_easy_setopt(conn
->connection
,
3387 CURLOPT_TIMECONDITION
,
3388 CURL_TIMECOND_IFMODSINCE
);
3391 case 1: /* TIMECOND_IFUNMODSINCE */
3392 result
= curl_easy_setopt(conn
->connection
,
3393 CURLOPT_TIMECONDITION
,
3394 CURL_TIMECOND_IFUNMODSINCE
);
3398 failwith("Invalid TIMECOND Option");
3402 if (result
!= CURLE_OK
)
3403 raiseError(conn
, result
);
3408 static void handleTimeValue(Connection
*conn
, value option
)
3411 CURLcode result
= CURLE_OK
;
3413 result
= curl_easy_setopt(conn
->connection
,
3417 if (result
!= CURLE_OK
)
3418 raiseError(conn
, result
);
3423 static void handleCustomRequest(Connection
*conn
, value option
)
3426 CURLcode result
= CURLE_OK
;
3428 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3430 if (conn
->customRequest
!= NULL
)
3431 free(conn
->customRequest
);
3433 conn
->customRequest
= strdup(String_val(option
));
3435 result
= curl_easy_setopt(conn
->connection
,
3436 CURLOPT_CUSTOMREQUEST
,
3437 conn
->customRequest
);
3439 if (result
!= CURLE_OK
)
3440 raiseError(conn
, result
);
3445 static void handleInterface(Connection
*conn
, value option
)
3448 CURLcode result
= CURLE_OK
;
3450 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3452 if (conn
->interface_
!= NULL
)
3453 free(conn
->interface_
);
3455 conn
->interface_
= strdup(String_val(option
));
3457 result
= curl_easy_setopt(conn
->connection
,
3461 if (result
!= CURLE_OK
)
3462 raiseError(conn
, result
);
3467 static void handleKRB4Level(Connection
*conn
, value option
)
3470 CURLcode result
= CURLE_OK
;
3472 switch (Long_val(option
))
3474 case 0: /* KRB4_NONE */
3475 result
= curl_easy_setopt(conn
->connection
,
3480 case 1: /* KRB4_CLEAR */
3481 result
= curl_easy_setopt(conn
->connection
,
3486 case 2: /* KRB4_SAFE */
3487 result
= curl_easy_setopt(conn
->connection
,
3492 case 3: /* KRB4_CONFIDENTIAL */
3493 result
= curl_easy_setopt(conn
->connection
,
3498 case 4: /* KRB4_PRIVATE */
3499 result
= curl_easy_setopt(conn
->connection
,
3505 failwith("Invalid KRB4 Option");
3509 if (result
!= CURLE_OK
)
3510 raiseError(conn
, result
);
3515 static void handleProgressFunction(Connection
*conn
, value option
)
3518 CURLcode result
= CURLE_OK
;
3520 if (Tag_val(option
) == Closure_tag
)
3521 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3523 failwith("Not a proper closure");
3525 result
= curl_easy_setopt(conn
->connection
,
3526 CURLOPT_PROGRESSFUNCTION
,
3528 if (result
!= CURLE_OK
)
3529 raiseError(conn
, result
);
3531 result
= curl_easy_setopt(conn
->connection
,
3532 CURLOPT_PROGRESSDATA
,
3535 if (result
!= CURLE_OK
)
3536 raiseError(conn
, result
);
3541 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3544 CURLcode result
= CURLE_OK
;
3546 result
= curl_easy_setopt(conn
->connection
,
3547 CURLOPT_SSL_VERIFYPEER
,
3550 if (result
!= CURLE_OK
)
3551 raiseError(conn
, result
);
3556 static void handleCAInfo(Connection
*conn
, value option
)
3559 CURLcode result
= CURLE_OK
;
3561 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3563 if (conn
->caInfo
!= NULL
)
3566 conn
->caInfo
= strdup(String_val(option
));
3568 result
= curl_easy_setopt(conn
->connection
,
3572 if (result
!= CURLE_OK
)
3573 raiseError(conn
, result
);
3578 static void handleCAPath(Connection
*conn
, value option
)
3581 CURLcode result
= CURLE_OK
;
3583 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3585 if (conn
->caPath
!= NULL
)
3588 conn
->caPath
= strdup(String_val(option
));
3590 result
= curl_easy_setopt(conn
->connection
,
3594 if (result
!= CURLE_OK
)
3595 raiseError(conn
, result
);
3600 static void handleFileTime(Connection
*conn
, value option
)
3603 CURLcode result
= CURLE_OK
;
3605 result
= curl_easy_setopt(conn
->connection
,
3609 if (result
!= CURLE_OK
)
3610 raiseError(conn
, result
);
3615 static void handleMaxRedirs(Connection
*conn
, value option
)
3618 CURLcode result
= CURLE_OK
;
3620 result
= curl_easy_setopt(conn
->connection
,
3624 if (result
!= CURLE_OK
)
3625 raiseError(conn
, result
);
3630 static void handleMaxConnects(Connection
*conn
, value option
)
3633 CURLcode result
= CURLE_OK
;
3635 result
= curl_easy_setopt(conn
->connection
,
3636 CURLOPT_MAXCONNECTS
,
3639 if (result
!= CURLE_OK
)
3640 raiseError(conn
, result
);
3645 static void handleClosePolicy(Connection
*conn
, value option
)
3648 CURLcode result
= CURLE_OK
;
3650 switch (Long_val(option
))
3652 case 0: /* CLOSEPOLICY_OLDEST */
3653 result
= curl_easy_setopt(conn
->connection
,
3654 CURLOPT_CLOSEPOLICY
,
3655 CURLCLOSEPOLICY_OLDEST
);
3658 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3659 result
= curl_easy_setopt(conn
->connection
,
3660 CURLOPT_CLOSEPOLICY
,
3661 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3665 failwith("Invalid CLOSEPOLICY Option");
3669 if (result
!= CURLE_OK
)
3670 raiseError(conn
, result
);
3675 static void handleFreshConnect(Connection
*conn
, value option
)
3678 CURLcode result
= CURLE_OK
;
3680 result
= curl_easy_setopt(conn
->connection
,
3681 CURLOPT_FRESH_CONNECT
,
3684 if (result
!= CURLE_OK
)
3685 raiseError(conn
, result
);
3690 static void handleForbidReuse(Connection
*conn
, value option
)
3693 CURLcode result
= CURLE_OK
;
3695 result
= curl_easy_setopt(conn
->connection
,
3696 CURLOPT_FORBID_REUSE
,
3699 if (result
!= CURLE_OK
)
3700 raiseError(conn
, result
);
3705 static void handleRandomFile(Connection
*conn
, value option
)
3708 CURLcode result
= CURLE_OK
;
3710 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3712 if (conn
->randomFile
!= NULL
)
3713 free(conn
->randomFile
);
3715 conn
->randomFile
= strdup(String_val(option
));
3717 result
= curl_easy_setopt(conn
->connection
,
3718 CURLOPT_RANDOM_FILE
,
3721 if (result
!= CURLE_OK
)
3722 raiseError(conn
, result
);
3727 static void handleEGDSocket(Connection
*conn
, value option
)
3730 CURLcode result
= CURLE_OK
;
3732 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3734 if (conn
->egdSocket
!= NULL
)
3735 free(conn
->egdSocket
);
3737 conn
->egdSocket
= strdup(String_val(option
));
3739 result
= curl_easy_setopt(conn
->connection
,
3743 if (result
!= CURLE_OK
)
3744 raiseError(conn
, result
);
3749 static void handleConnectTimeout(Connection
*conn
, value option
)
3752 CURLcode result
= CURLE_OK
;
3754 result
= curl_easy_setopt(conn
->connection
,
3755 CURLOPT_CONNECTTIMEOUT
,
3758 if (result
!= CURLE_OK
)
3759 raiseError(conn
, result
);
3764 static void handleHTTPGet(Connection
*conn
, value option
)
3767 CURLcode result
= CURLE_OK
;
3769 result
= curl_easy_setopt(conn
->connection
,
3773 if (result
!= CURLE_OK
)
3774 raiseError(conn
, result
);
3779 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3782 CURLcode result
= CURLE_OK
;
3784 switch (Long_val(option
))
3786 case 0: /* SSLVERIFYHOST_NONE */
3787 case 1: /* SSLVERIFYHOST_EXISTENCE */
3788 case 2: /* SSLVERIFYHOST_HOSTNAME */
3789 result
= curl_easy_setopt(conn
->connection
,
3790 CURLOPT_SSL_VERIFYHOST
,
3791 /* map EXISTENCE to HOSTNAME */
3792 Long_val(option
) == 0 ? 0 : 2);
3796 failwith("Invalid SSLVERIFYHOST Option");
3800 if (result
!= CURLE_OK
)
3801 raiseError(conn
, result
);
3806 static void handleCookieJar(Connection
*conn
, value option
)
3809 CURLcode result
= CURLE_OK
;
3811 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3813 if (conn
->cookieJar
!= NULL
)
3814 free(conn
->cookieJar
);
3816 conn
->cookieJar
= strdup(String_val(option
));
3818 result
= curl_easy_setopt(conn
->connection
,
3822 if (result
!= CURLE_OK
)
3823 raiseError(conn
, result
);
3828 static void handleSSLCipherList(Connection
*conn
, value option
)
3831 CURLcode result
= CURLE_OK
;
3833 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3835 if (conn
->sslCipherList
!= NULL
)
3836 free(conn
->sslCipherList
);
3838 conn
->sslCipherList
= strdup(String_val(option
));
3840 result
= curl_easy_setopt(conn
->connection
,
3841 CURLOPT_SSL_CIPHER_LIST
,
3842 conn
->sslCipherList
);
3844 if (result
!= CURLE_OK
)
3845 raiseError(conn
, result
);
3850 static void handleHTTPVersion(Connection
*conn
, value option
)
3853 CURLcode result
= CURLE_OK
;
3855 switch (Long_val(option
))
3857 case 0: /* HTTP_VERSION_NONE */
3858 result
= curl_easy_setopt(conn
->connection
,
3859 CURLOPT_HTTP_VERSION
,
3860 CURL_HTTP_VERSION_NONE
);
3863 case 1: /* HTTP_VERSION_1_0 */
3864 result
= curl_easy_setopt(conn
->connection
,
3865 CURLOPT_HTTP_VERSION
,
3866 CURL_HTTP_VERSION_1_0
);
3869 case 2: /* HTTP_VERSION_1_1 */
3870 result
= curl_easy_setopt(conn
->connection
,
3871 CURLOPT_HTTP_VERSION
,
3872 CURL_HTTP_VERSION_1_1
);
3876 failwith("Invalid HTTP_VERSION Option");
3880 if (result
!= CURLE_OK
)
3881 raiseError(conn
, result
);
3886 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3889 CURLcode result
= CURLE_OK
;
3891 result
= curl_easy_setopt(conn
->connection
,
3892 CURLOPT_FTP_USE_EPSV
,
3895 if (result
!= CURLE_OK
)
3896 raiseError(conn
, result
);
3901 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3904 CURLcode result
= CURLE_OK
;
3906 result
= curl_easy_setopt(conn
->connection
,
3907 CURLOPT_DNS_CACHE_TIMEOUT
,
3910 if (result
!= CURLE_OK
)
3911 raiseError(conn
, result
);
3916 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3919 CURLcode result
= CURLE_OK
;
3921 result
= curl_easy_setopt(conn
->connection
,
3922 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3925 if (result
!= CURLE_OK
)
3926 raiseError(conn
, result
);
3931 static void handleDebugFunction(Connection
*conn
, value option
)
3934 CURLcode result
= CURLE_OK
;
3936 if (Tag_val(option
) == Closure_tag
)
3937 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3939 failwith("Not a proper closure");
3941 result
= curl_easy_setopt(conn
->connection
,
3942 CURLOPT_DEBUGFUNCTION
,
3944 if (result
!= CURLE_OK
)
3945 raiseError(conn
, result
);
3947 result
= curl_easy_setopt(conn
->connection
,
3951 if (result
!= CURLE_OK
)
3952 raiseError(conn
, result
);
3957 static void handlePrivate(Connection
*conn
, value option
)
3959 #if HAVE_DECL_CURLOPT_PRIVATE
3961 CURLcode result
= CURLE_OK
;
3963 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
3965 if (conn
->private != NULL
)
3966 free(conn
->private);
3968 conn
->private = strdup(String_val(option
));
3970 result
= curl_easy_setopt(conn
->connection
,
3974 if (result
!= CURLE_OK
)
3975 raiseError(conn
, result
);
3979 #pragma message("libcurl does not implement CURLOPT_PRIVATE")
3980 failwith("libcurl does not implement CURLOPT_PRIVATE");
3984 static void handleHTTP200Aliases(Connection
*conn
, value option
)
3986 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3988 CAMLlocal1(listIter
);
3989 CURLcode result
= CURLE_OK
;
3991 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
3993 free_curl_slist(conn
->http200Aliases
);
3994 conn
->http200Aliases
= NULL
;
3998 while (!Is_long(listIter
))
4000 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, String_val(Field(listIter
, 0)));
4002 listIter
= Field(listIter
, 1);
4005 result
= curl_easy_setopt(conn
->connection
,
4006 CURLOPT_HTTP200ALIASES
,
4007 conn
->http200Aliases
);
4009 if (result
!= CURLE_OK
)
4010 raiseError(conn
, result
);
4014 #pragma message("libcurl does not implement CURLOPT_HTTP200ALIASES")
4015 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
4019 static void handleUnrestrictedAuth(Connection
*conn
, value option
)
4021 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
4023 CURLcode result
= CURLE_OK
;
4025 result
= curl_easy_setopt(conn
->connection
,
4026 CURLOPT_UNRESTRICTED_AUTH
,
4029 if (result
!= CURLE_OK
)
4030 raiseError(conn
, result
);
4034 #pragma message("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH")
4035 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4039 static void handleFTPUseEPRT(Connection
*conn
, value option
)
4041 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4043 CURLcode result
= CURLE_OK
;
4045 result
= curl_easy_setopt(conn
->connection
,
4046 CURLOPT_FTP_USE_EPRT
,
4049 if (result
!= CURLE_OK
)
4050 raiseError(conn
, result
);
4054 #pragma message("libcurl does not implement CURLOPT_FTP_USE_EPRT")
4055 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4059 static void handleHTTPAuth(Connection
*conn
, value option
)
4061 #if HAVE_DECL_CURLOPT_HTTPAUTH
4063 CAMLlocal1(listIter
);
4064 CURLcode result
= CURLE_OK
;
4065 long auth
= CURLAUTH_NONE
;
4069 while (!Is_long(listIter
))
4071 switch (Long_val(Field(listIter
, 0)))
4073 case 0: /* CURLAUTH_BASIC */
4074 auth
|= CURLAUTH_BASIC
;
4077 case 1: /* CURLAUTH_DIGEST */
4078 auth
|= CURLAUTH_DIGEST
;
4081 case 2: /* CURLAUTH_GSSNEGOTIATE */
4082 auth
|= CURLAUTH_GSSNEGOTIATE
;
4085 case 3: /* CURLAUTH_NTLM */
4086 auth
|= CURLAUTH_NTLM
;
4089 case 4: /* CURLAUTH_ANY */
4090 auth
|= CURLAUTH_ANY
;
4093 case 5: /* CURLAUTH_ANYSAFE */
4094 auth
|= CURLAUTH_ANYSAFE
;
4098 failwith("Invalid HTTPAUTH Value");
4102 listIter
= Field(listIter
, 1);
4105 result
= curl_easy_setopt(conn
->connection
,
4109 if (result
!= CURLE_OK
)
4110 raiseError(conn
, result
);
4114 #pragma message("libcurl does not implement CURLOPT_HTTPAUTH")
4115 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4119 static void handleFTPCreateMissingDirs(Connection
*conn
, value option
)
4121 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4123 CURLcode result
= CURLE_OK
;
4125 result
= curl_easy_setopt(conn
->connection
,
4126 CURLOPT_FTP_CREATE_MISSING_DIRS
,
4129 if (result
!= CURLE_OK
)
4130 raiseError(conn
, result
);
4134 #pragma message("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS")
4135 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4139 static void handleProxyAuth(Connection
*conn
, value option
)
4141 #if HAVE_DECL_CURLOPT_PROXYAUTH
4143 CAMLlocal1(listIter
);
4144 CURLcode result
= CURLE_OK
;
4145 long auth
= CURLAUTH_NONE
;
4149 while (!Is_long(listIter
))
4151 switch (Long_val(Field(listIter
, 0)))
4153 case 0: /* CURLAUTH_BASIC */
4154 auth
|= CURLAUTH_BASIC
;
4157 case 1: /* CURLAUTH_DIGEST */
4158 auth
|= CURLAUTH_DIGEST
;
4161 case 2: /* CURLAUTH_GSSNEGOTIATE */
4162 auth
|= CURLAUTH_GSSNEGOTIATE
;
4165 case 3: /* CURLAUTH_NTLM */
4166 auth
|= CURLAUTH_NTLM
;
4169 case 4: /* CURLAUTH_ANY */
4170 auth
|= CURLAUTH_ANY
;
4173 case 5: /* CURLAUTH_ANYSAFE */
4174 auth
|= CURLAUTH_ANYSAFE
;
4178 failwith("Invalid HTTPAUTH Value");
4182 listIter
= Field(listIter
, 1);
4185 result
= curl_easy_setopt(conn
->connection
,
4189 if (result
!= CURLE_OK
)
4190 raiseError(conn
, result
);
4194 #pragma message("libcurl does not implement CURLOPT_PROXYAUTH")
4195 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4199 static void handleFTPResponseTimeout(Connection
*conn
, value option
)
4201 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4203 CURLcode result
= CURLE_OK
;
4205 result
= curl_easy_setopt(conn
->connection
,
4206 CURLOPT_FTP_RESPONSE_TIMEOUT
,
4209 if (result
!= CURLE_OK
)
4210 raiseError(conn
, result
);
4214 #pragma message("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT")
4215 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4219 static void handleIPResolve(Connection
*conn
, value option
)
4221 #if HAVE_DECL_CURLOPT_IPRESOLVE
4223 CURLcode result
= CURLE_OK
;
4225 switch (Long_val(option
))
4227 case 0: /* CURL_IPRESOLVE_WHATEVER */
4228 result
= curl_easy_setopt(conn
->connection
,
4230 CURL_IPRESOLVE_WHATEVER
);
4233 case 1: /* CURL_IPRESOLVE_V4 */
4234 result
= curl_easy_setopt(conn
->connection
,
4239 case 2: /* CURL_IPRESOLVE_V6 */
4240 result
= curl_easy_setopt(conn
->connection
,
4246 failwith("Invalid IPRESOLVE Value");
4250 if (result
!= CURLE_OK
)
4251 raiseError(conn
, result
);
4255 #pragma message("libcurl does not implement CURLOPT_IPRESOLVE")
4256 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4260 static void handleMaxFileSize(Connection
*conn
, value option
)
4262 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4264 CURLcode result
= CURLE_OK
;
4266 result
= curl_easy_setopt(conn
->connection
,
4267 CURLOPT_MAXFILESIZE
,
4270 if (result
!= CURLE_OK
)
4271 raiseError(conn
, result
);
4275 #pragma message("libcurl does not implement CURLOPT_MAXFILESIZE")
4276 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4280 static void handleInFileSizeLarge(Connection
*conn
, value option
)
4282 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4284 CURLcode result
= CURLE_OK
;
4286 result
= curl_easy_setopt(conn
->connection
,
4287 CURLOPT_INFILESIZE_LARGE
,
4290 if (result
!= CURLE_OK
)
4291 raiseError(conn
, result
);
4295 #pragma message("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4296 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4300 static void handleResumeFromLarge(Connection
*conn
, value option
)
4302 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4304 CURLcode result
= CURLE_OK
;
4306 result
= curl_easy_setopt(conn
->connection
,
4307 CURLOPT_RESUME_FROM_LARGE
,
4310 if (result
!= CURLE_OK
)
4311 raiseError(conn
, result
);
4315 #pragma message("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4316 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4320 static void handleMaxFileSizeLarge(Connection
*conn
, value option
)
4322 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4324 CURLcode result
= CURLE_OK
;
4326 result
= curl_easy_setopt(conn
->connection
,
4327 CURLOPT_MAXFILESIZE_LARGE
,
4330 if (result
!= CURLE_OK
)
4331 raiseError(conn
, result
);
4335 #pragma message("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE")
4336 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4340 static void handleNETRCFile(Connection
*conn
, value option
)
4342 #if HAVE_DECL_CURLOPT_NETRC_FILE
4344 CURLcode result
= CURLE_OK
;
4346 Store_field(conn
->ocamlValues
, OcamlNETRCFile
, option
);
4348 if (conn
->netrcFile
!= NULL
)
4349 free(conn
->netrcFile
);
4351 conn
->netrcFile
= strdup(String_val(option
));
4353 result
= curl_easy_setopt(conn
->connection
,
4357 if (result
!= CURLE_OK
)
4358 raiseError(conn
, result
);
4362 #pragma message("libcurl does not implement CURLOPT_NETRC_FILE")
4363 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4367 static void handleFTPSSL(Connection
*conn
, value option
)
4369 #if HAVE_DECL_CURLOPT_FTP_SSL
4371 CURLcode result
= CURLE_OK
;
4373 switch (Long_val(option
))
4375 case 0: /* CURLFTPSSL_NONE */
4376 result
= curl_easy_setopt(conn
->connection
,
4381 case 1: /* CURLFTPSSL_TRY */
4382 result
= curl_easy_setopt(conn
->connection
,
4387 case 2: /* CURLFTPSSL_CONTROL */
4388 result
= curl_easy_setopt(conn
->connection
,
4390 CURLFTPSSL_CONTROL
);
4393 case 3: /* CURLFTPSSL_ALL */
4394 result
= curl_easy_setopt(conn
->connection
,
4400 failwith("Invalid FTP_SSL Value");
4404 if (result
!= CURLE_OK
)
4405 raiseError(conn
, result
);
4409 #pragma message("libcurl does not implement CURLOPT_FTP_SSL")
4410 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4414 static void handlePostFieldSizeLarge(Connection
*conn
, value option
)
4416 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4418 CURLcode result
= CURLE_OK
;
4420 result
= curl_easy_setopt(conn
->connection
,
4421 CURLOPT_POSTFIELDSIZE_LARGE
,
4424 if (result
!= CURLE_OK
)
4425 raiseError(conn
, result
);
4429 #pragma message("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE")
4430 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4434 static void handleTCPNoDelay(Connection
*conn
, value option
)
4436 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4438 CURLcode result
= CURLE_OK
;
4440 result
= curl_easy_setopt(conn
->connection
,
4441 CURLOPT_TCP_NODELAY
,
4444 if (result
!= CURLE_OK
)
4445 raiseError(conn
, result
);
4449 #pragma message("libcurl does not implement CURLOPT_TCP_NODELAY")
4450 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4454 static void handleFTPSSLAuth(Connection
*conn
, value option
)
4456 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4458 CURLcode result
= CURLE_OK
;
4460 switch (Long_val(option
))
4462 case 0: /* CURLFTPAUTH_DEFAULT */
4463 result
= curl_easy_setopt(conn
->connection
,
4465 CURLFTPAUTH_DEFAULT
);
4468 case 1: /* CURLFTPAUTH_SSL */
4469 result
= curl_easy_setopt(conn
->connection
,
4474 case 2: /* CURLFTPAUTH_TLS */
4475 result
= curl_easy_setopt(conn
->connection
,
4481 failwith("Invalid FTPSSLAUTH value");
4485 if (result
!= CURLE_OK
)
4486 raiseError(conn
, result
);
4490 #pragma message("libcurl does not implement CURLOPT_FTPSSLAUTH")
4491 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4495 static void handleIOCTLFunction(Connection
*conn
, value option
)
4497 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4499 CURLcode result
= CURLE_OK
;
4501 if (Tag_val(option
) == Closure_tag
)
4502 Store_field(conn
->ocamlValues
, OcamlIOCTLCallback
, option
);
4504 failwith("Not a proper closure");
4506 result
= curl_easy_setopt(conn
->connection
,
4507 CURLOPT_IOCTLFUNCTION
,
4509 if (result
!= CURLE_OK
)
4510 raiseError(conn
, result
);
4512 result
= curl_easy_setopt(conn
->connection
,
4516 if (result
!= CURLE_OK
)
4517 raiseError(conn
, result
);
4521 #pragma message("libcurl does not implement CURLOPT_IOCTLFUNCTION")
4522 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4526 static void handleFTPAccount(Connection
*conn
, value option
)
4528 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4530 CURLcode result
= CURLE_OK
;
4532 Store_field(conn
->ocamlValues
, OcamlFTPAccount
, option
);
4534 if (conn
->ftpaccount
!= NULL
)
4535 free(conn
->ftpaccount
);
4537 conn
->ftpaccount
= strdup(String_val(option
));
4539 result
= curl_easy_setopt(conn
->connection
,
4540 CURLOPT_FTP_ACCOUNT
,
4543 if (result
!= CURLE_OK
)
4544 raiseError(conn
, result
);
4548 #pragma message("libcurl does not implement CURLOPT_FTP_ACCOUNT")
4549 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4553 static void handleCookieList(Connection
*conn
, value option
)
4555 #if HAVE_DECL_CURLOPT_COOKIELIST
4557 CURLcode result
= CURLE_OK
;
4559 Store_field(conn
->ocamlValues
, OcamlCookieList
, option
);
4561 if (conn
->cookielist
!= NULL
)
4562 free(conn
->cookielist
);
4564 conn
->cookielist
= strdup(String_val(option
));
4566 result
= curl_easy_setopt(conn
->connection
,
4570 if (result
!= CURLE_OK
)
4571 raiseError(conn
, result
);
4575 #pragma message("libcurl does not implement CURLOPT_COOKIELIST")
4576 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4580 static void handleIgnoreContentLength(Connection
*conn
, value option
)
4582 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4584 CURLcode result
= CURLE_OK
;
4586 result
= curl_easy_setopt(conn
->connection
,
4587 CURLOPT_IGNORE_CONTENT_LENGTH
,
4590 if (result
!= CURLE_OK
)
4591 raiseError(conn
, result
);
4595 #pragma message("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH")
4596 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4600 static void handleFTPSkipPASVIP(Connection
*conn
, value option
)
4602 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4604 CURLcode result
= CURLE_OK
;
4606 result
= curl_easy_setopt(conn
->connection
,
4607 CURLOPT_FTP_SKIP_PASV_IP
,
4610 if (result
!= CURLE_OK
)
4611 raiseError(conn
, result
);
4615 #pragma message("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP")
4616 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4620 static void handleFTPFileMethod(Connection
*conn
, value option
)
4622 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4624 CURLcode result
= CURLE_OK
;
4626 switch (Long_val(option
))
4628 case 0: /* CURLFTPMETHOD_DEFAULT */
4629 result
= curl_easy_setopt(conn
->connection
,
4630 CURLOPT_FTP_FILEMETHOD
,
4631 CURLFTPMETHOD_DEFAULT
);
4634 case 1: /* CURLFTMETHOD_MULTICWD */
4635 result
= curl_easy_setopt(conn
->connection
,
4636 CURLOPT_FTP_FILEMETHOD
,
4637 CURLFTPMETHOD_MULTICWD
);
4640 case 2: /* CURLFTPMETHOD_NOCWD */
4641 result
= curl_easy_setopt(conn
->connection
,
4642 CURLOPT_FTP_FILEMETHOD
,
4643 CURLFTPMETHOD_NOCWD
);
4646 case 3: /* CURLFTPMETHOD_SINGLECWD */
4647 result
= curl_easy_setopt(conn
->connection
,
4648 CURLOPT_FTP_FILEMETHOD
,
4649 CURLFTPMETHOD_SINGLECWD
);
4652 failwith("Invalid FTP_FILEMETHOD value");
4656 if (result
!= CURLE_OK
)
4657 raiseError(conn
, result
);
4661 #pragma message("libcurl does not implement CURLOPT_FTP_FILEMETHOD")
4662 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4666 static void handleLocalPort(Connection
*conn
, value option
)
4668 #if HAVE_DECL_CURLOPT_LOCALPORT
4670 CURLcode result
= CURLE_OK
;
4672 result
= curl_easy_setopt(conn
->connection
,
4676 if (result
!= CURLE_OK
)
4677 raiseError(conn
, result
);
4681 #pragma message("libcurl does not implement CURLOPT_LOCALPORT")
4682 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4686 static void handleLocalPortRange(Connection
*conn
, value option
)
4688 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4690 CURLcode result
= CURLE_OK
;
4692 result
= curl_easy_setopt(conn
->connection
,
4693 CURLOPT_LOCALPORTRANGE
,
4696 if (result
!= CURLE_OK
)
4697 raiseError(conn
, result
);
4701 #pragma message("libcurl does not implement CURLOPT_LOCALPORTRANGE")
4702 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4706 static void handleConnectOnly(Connection
*conn
, value option
)
4708 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4710 CURLcode result
= CURLE_OK
;
4712 result
= curl_easy_setopt(conn
->connection
,
4713 CURLOPT_CONNECT_ONLY
,
4716 if (result
!= CURLE_OK
)
4717 raiseError(conn
, result
);
4721 #pragma message("libcurl does not implement CURLOPT_CONNECT_ONLY")
4722 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4726 static void handleMaxSendSpeedLarge(Connection
*conn
, value option
)
4728 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4730 CURLcode result
= CURLE_OK
;
4732 result
= curl_easy_setopt(conn
->connection
,
4733 CURLOPT_MAX_SEND_SPEED_LARGE
,
4736 if (result
!= CURLE_OK
)
4737 raiseError(conn
, result
);
4741 #pragma message("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE")
4742 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4746 static void handleMaxRecvSpeedLarge(Connection
*conn
, value option
)
4748 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4750 CURLcode result
= CURLE_OK
;
4752 result
= curl_easy_setopt(conn
->connection
,
4753 CURLOPT_MAX_RECV_SPEED_LARGE
,
4756 if (result
!= CURLE_OK
)
4757 raiseError(conn
, result
);
4761 #pragma message("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE")
4762 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4766 static void handleFTPAlternativeToUser(Connection
*conn
, value option
)
4768 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4770 CURLcode result
= CURLE_OK
;
4772 Store_field(conn
->ocamlValues
, OcamlFTPAlternativeToUser
, option
);
4774 if (conn
->ftpAlternativeToUser
!= NULL
)
4775 free(conn
->ftpAlternativeToUser
);
4777 conn
->ftpAlternativeToUser
= strdup(String_val(option
));
4779 result
= curl_easy_setopt(conn
->connection
,
4780 CURLOPT_FTP_ALTERNATIVE_TO_USER
,
4781 conn
->ftpAlternativeToUser
);
4783 if (result
!= CURLE_OK
)
4784 raiseError(conn
, result
);
4788 #pragma message("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER")
4789 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4793 static void handleSSLSessionIdCache(Connection
*conn
, value option
)
4795 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4797 CURLcode result
= CURLE_OK
;
4799 result
= curl_easy_setopt(conn
->connection
,
4800 CURLOPT_SSL_SESSIONID_CACHE
,
4803 if (result
!= CURLE_OK
)
4804 raiseError(conn
, result
);
4808 #pragma message("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE")
4809 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4813 static void handleSSHAuthTypes(Connection
*conn
, value option
)
4815 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4817 CAMLlocal1(listIter
);
4818 CURLcode result
= CURLE_OK
;
4819 long authTypes
= CURLSSH_AUTH_NONE
;
4823 while (!Is_long(listIter
))
4825 switch (Long_val(Field(listIter
, 0)))
4827 case 0: /* CURLSSH_AUTH_ANY */
4828 authTypes
|= CURLSSH_AUTH_ANY
;
4831 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4832 authTypes
|= CURLSSH_AUTH_PUBLICKEY
;
4835 case 2: /* CURLSSH_AUTH_PASSWORD */
4836 authTypes
|= CURLSSH_AUTH_PASSWORD
;
4839 case 3: /* CURLSSH_AUTH_HOST */
4840 authTypes
|= CURLSSH_AUTH_HOST
;
4843 case 4: /* CURLSSH_AUTH_KEYBOARD */
4844 authTypes
|= CURLSSH_AUTH_KEYBOARD
;
4848 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4852 listIter
= Field(listIter
, 1);
4855 result
= curl_easy_setopt(conn
->connection
,
4856 CURLOPT_SSH_AUTH_TYPES
,
4859 if (result
!= CURLE_OK
)
4860 raiseError(conn
, result
);
4864 #pragma message("libcurl does not implement CURLOPT_SSH_AUTH_TYPES")
4865 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4869 static void handleSSHPublicKeyFile(Connection
*conn
, value option
)
4871 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4873 CURLcode result
= CURLE_OK
;
4875 Store_field(conn
->ocamlValues
, OcamlSSHPublicKeyFile
, option
);
4877 if (conn
->sshPublicKeyFile
!= NULL
)
4878 free(conn
->sshPublicKeyFile
);
4880 conn
->sshPublicKeyFile
= strdup(String_val(option
));
4882 result
= curl_easy_setopt(conn
->connection
,
4883 CURLOPT_SSH_PUBLIC_KEYFILE
,
4884 conn
->sshPublicKeyFile
);
4886 if (result
!= CURLE_OK
)
4887 raiseError(conn
, result
);
4891 #pragma message("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE")
4892 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4896 static void handleSSHPrivateKeyFile(Connection
*conn
, value option
)
4898 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4900 CURLcode result
= CURLE_OK
;
4902 Store_field(conn
->ocamlValues
, OcamlSSHPrivateKeyFile
, option
);
4904 if (conn
->sshPrivateKeyFile
!= NULL
)
4905 free(conn
->sshPrivateKeyFile
);
4907 conn
->sshPrivateKeyFile
= strdup(String_val(option
));
4909 result
= curl_easy_setopt(conn
->connection
,
4910 CURLOPT_SSH_PRIVATE_KEYFILE
,
4911 conn
->sshPrivateKeyFile
);
4913 if (result
!= CURLE_OK
)
4914 raiseError(conn
, result
);
4918 #pragma message("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE")
4919 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4923 static void handleFTPSSLCCC(Connection
*conn
, value option
)
4925 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4927 CURLcode result
= CURLE_OK
;
4929 switch (Long_val(option
))
4931 case 0: /* CURLFTPSSL_CCC_NONE */
4932 result
= curl_easy_setopt(conn
->connection
,
4933 CURLOPT_FTP_SSL_CCC
,
4934 CURLFTPSSL_CCC_NONE
);
4937 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4938 result
= curl_easy_setopt(conn
->connection
,
4939 CURLOPT_FTP_SSL_CCC
,
4940 CURLFTPSSL_CCC_PASSIVE
);
4943 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4944 result
= curl_easy_setopt(conn
->connection
,
4945 CURLOPT_FTP_SSL_CCC
,
4946 CURLFTPSSL_CCC_ACTIVE
);
4950 failwith("Invalid FTPSSL_CCC value");
4954 if (result
!= CURLE_OK
)
4955 raiseError(conn
, result
);
4959 #pragma message("libcurl does not implement CURLOPT_FTP_SSL_CCC")
4960 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4964 static void handleTimeoutMS(Connection
*conn
, value option
)
4966 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4968 CURLcode result
= CURLE_OK
;
4970 result
= curl_easy_setopt(conn
->connection
,
4974 if (result
!= CURLE_OK
)
4975 raiseError(conn
, result
);
4979 #pragma message("libcurl does not implement CURLOPT_TIMEOUT_MS")
4980 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4984 static void handleConnectTimeoutMS(Connection
*conn
, value option
)
4986 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4988 CURLcode result
= CURLE_OK
;
4990 result
= curl_easy_setopt(conn
->connection
,
4991 CURLOPT_CONNECTTIMEOUT_MS
,
4994 if (result
!= CURLE_OK
)
4995 raiseError(conn
, result
);
4999 #pragma message("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS")
5000 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
5004 static void handleHTTPTransferDecoding(Connection
*conn
, value option
)
5006 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
5008 CURLcode result
= CURLE_OK
;
5010 result
= curl_easy_setopt(conn
->connection
,
5011 CURLOPT_HTTP_TRANSFER_DECODING
,
5014 if (result
!= CURLE_OK
)
5015 raiseError(conn
, result
);
5019 #pragma message("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING")
5020 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
5024 static void handleHTTPContentDecoding(Connection
*conn
, value option
)
5026 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
5028 CURLcode result
= CURLE_OK
;
5030 result
= curl_easy_setopt(conn
->connection
,
5031 CURLOPT_HTTP_CONTENT_DECODING
,
5034 if (result
!= CURLE_OK
)
5035 raiseError(conn
, result
);
5039 #pragma message("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING")
5040 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5044 static void handleNewFilePerms(Connection
*conn
, value option
)
5046 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5048 CURLcode result
= CURLE_OK
;
5050 result
= curl_easy_setopt(conn
->connection
,
5051 CURLOPT_NEW_FILE_PERMS
,
5054 if (result
!= CURLE_OK
)
5055 raiseError(conn
, result
);
5059 #pragma message("libcurl does not implement CURLOPT_NEW_FILE_PERMS")
5060 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5064 static void handleNewDirectoryPerms(Connection
*conn
, value option
)
5066 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5068 CURLcode result
= CURLE_OK
;
5070 result
= curl_easy_setopt(conn
->connection
,
5071 CURLOPT_NEW_DIRECTORY_PERMS
,
5074 if (result
!= CURLE_OK
)
5075 raiseError(conn
, result
);
5079 #pragma message("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS")
5080 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5084 static void handlePost301(Connection
*conn
, value option
)
5086 #if HAVE_DECL_CURLOPT_POST301
5088 CURLcode result
= CURLE_OK
;
5090 result
= curl_easy_setopt(conn
->connection
,
5094 if (result
!= CURLE_OK
)
5095 raiseError(conn
, result
);
5099 #pragma message("libcurl does not implement CURLOPT_POST301")
5100 failwith("libcurl does not implement CURLOPT_POST301");
5104 static void handleSSHHostPublicKeyMD5(Connection
*conn
, value option
)
5106 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5108 CURLcode result
= CURLE_OK
;
5110 Store_field(conn
->ocamlValues
, OcamlSSHHostPublicKeyMD5
, option
);
5112 if (conn
->sshHostPublicKeyMD5
!= NULL
)
5113 free(conn
->sshHostPublicKeyMD5
);
5115 conn
->sshHostPublicKeyMD5
= strdup(String_val(option
));
5117 result
= curl_easy_setopt(conn
->connection
,
5118 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
,
5119 conn
->sshHostPublicKeyMD5
);
5121 if (result
!= CURLE_OK
)
5122 raiseError(conn
, result
);
5126 #pragma message("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5")
5127 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5131 static void handleCopyPostFields(Connection
*conn
, value option
)
5133 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5135 CURLcode result
= CURLE_OK
;
5137 Store_field(conn
->ocamlValues
, OcamlCopyPostFields
, option
);
5139 if (conn
->copyPostFields
!= NULL
)
5140 free(conn
->copyPostFields
);
5142 conn
->copyPostFields
= strdup(String_val(option
));
5144 result
= curl_easy_setopt(conn
->connection
,
5145 CURLOPT_COPYPOSTFIELDS
,
5146 conn
->copyPostFields
);
5148 if (result
!= CURLE_OK
)
5149 raiseError(conn
, result
);
5153 #pragma message("libcurl does not implement CURLOPT_COPYPOSTFIELDS")
5154 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5158 static void handleProxyTransferMode(Connection
*conn
, value option
)
5160 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5162 CURLcode result
= CURLE_OK
;
5164 result
= curl_easy_setopt(conn
->connection
,
5165 CURLOPT_PROXY_TRANSFER_MODE
,
5168 if (result
!= CURLE_OK
)
5169 raiseError(conn
, result
);
5173 #pragma message("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE")
5174 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5178 static void handleSeekFunction(Connection
*conn
, value option
)
5180 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5182 CURLcode result
= CURLE_OK
;
5184 if (Tag_val(option
) == Closure_tag
)
5185 Store_field(conn
->ocamlValues
, OcamlSeekFunctionCallback
, option
);
5187 failwith("Not a proper closure");
5189 result
= curl_easy_setopt(conn
->connection
,
5190 CURLOPT_SEEKFUNCTION
,
5193 if (result
!= CURLE_OK
)
5194 raiseError(conn
, result
);
5196 result
= curl_easy_setopt(conn
->connection
,
5200 if (result
!= CURLE_OK
)
5201 raiseError(conn
, result
);
5205 #pragma message("libcurl does not implement CURLOPT_SEEKFUNCTION")
5206 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5210 static void handleAutoReferer(Connection
*conn
, value option
)
5212 #if HAVE_DECL_CURLOPT_AUTOREFERER
5214 CURLcode result
= curl_easy_setopt(conn
->connection
,
5215 CURLOPT_AUTOREFERER
,
5218 if (result
!= CURLE_OK
)
5219 raiseError(conn
, result
);
5223 #pragma message("libcurl does not implement CURLOPT_AUTOREFERER")
5224 failwith("libcurl does not implement CURLOPT_AUTOREFERER");
5228 static void handleOpenSocketFunction(Connection
*conn
, value option
)
5230 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
5232 CURLcode result
= CURLE_OK
;
5234 Store_field(conn
->ocamlValues
, OcamlOpenSocketFunctionCallback
, option
);
5236 result
= curl_easy_setopt(conn
->connection
,
5237 CURLOPT_OPENSOCKETDATA
,
5240 if (result
!= CURLE_OK
)
5241 raiseError(conn
, result
);
5243 result
= curl_easy_setopt(conn
->connection
,
5244 CURLOPT_OPENSOCKETFUNCTION
,
5245 openSocketFunction
);
5247 if (result
!= CURLE_OK
)
5248 raiseError(conn
, result
);
5252 #pragma message("libcurl does not implement CURLOPT_OPENSOCKETFUNCTION")
5253 failwith("libcurl does not implement CURLOPT_OPENSOCKETFUNCTION");
5257 static void handleProxyType(Connection
*conn
, value option
)
5259 #if HAVE_DECL_CURLOPT_PROXYTYPE
5261 CURLcode result
= CURLE_OK
;
5264 switch (Long_val(option
))
5266 case 0: proxy_type
= CURLPROXY_HTTP
; break;
5267 case 1: proxy_type
= CURLPROXY_HTTP_1_0
; break;
5268 case 2: proxy_type
= CURLPROXY_SOCKS4
; break;
5269 case 3: proxy_type
= CURLPROXY_SOCKS5
; break;
5270 case 4: proxy_type
= CURLPROXY_SOCKS4A
; break;
5271 case 5: proxy_type
= CURLPROXY_SOCKS5_HOSTNAME
; break;
5273 failwith("Invalid curl proxy type");
5276 result
= curl_easy_setopt(conn
->connection
,
5280 if (result
!= CURLE_OK
)
5281 raiseError(conn
, result
);
5285 #pragma message("libcurl does not implement CURLOPT_PROXYTYPE")
5286 failwith("libcurl does not implement CURLOPT_PROXYTYPE");
5290 #if HAVE_DECL_CURLOPT_PROTOCOLS && HAVE_DECL_CURLOPT_REDIR_PROTOCOLS
5295 CURLPROTO_HTTP
, CURLPROTO_HTTPS
, CURLPROTO_FTP
, CURLPROTO_FTPS
, CURLPROTO_SCP
, CURLPROTO_SFTP
,
5296 CURLPROTO_TELNET
, CURLPROTO_LDAP
, CURLPROTO_LDAPS
, CURLPROTO_DICT
, CURLPROTO_FILE
, CURLPROTO_TFTP
,
5297 /* factor out with autoconf? */
5298 #if defined(CURLPROTO_IMAP)
5303 #if defined(CURLPROTO_IMAPS)
5308 #if defined(CURLPROTO_POP3)
5313 #if defined(CURLPROTO_POP3S)
5318 #if defined(CURLPROTO_SMTP)
5323 #if defined(CURLPROTO_SMTPS)
5328 #if defined(CURLPROTO_RTSP)
5333 #if defined(CURLPROTO_RTMP)
5338 #if defined(CURLPROTO_RTMPT)
5343 #if defined(CURLPROTO_RTMPE)
5348 #if defined(CURLPROTO_RTMPTE)
5353 #if defined(CURLPROTO_RTMPS)
5358 #if defined(CURLPROTO_RTMPTS)
5363 #if defined(CURLPROTO_GOPHER)
5370 static void handleProtocolsOption(CURLoption curlopt
, Connection
*conn
, value option
)
5373 CURLcode result
= CURLE_OK
;
5377 while (Val_emptylist
!= option
)
5379 index
= Int_val(Field(option
, 0));
5380 if ((index
< 0) || ((size_t)index
>= sizeof(protoMap
) / sizeof(protoMap
[0])))
5381 failwith("Invalid curl protocol");
5383 protocols
= protocols
| protoMap
[index
];
5385 option
= Field(option
, 1);
5388 result
= curl_easy_setopt(conn
->connection
,
5392 if (result
!= CURLE_OK
)
5393 raiseError(conn
, result
);
5398 static void handleProtocols(Connection
*conn
, value option
)
5400 handleProtocolsOption(CURLOPT_PROTOCOLS
, conn
, option
);
5403 static void handleRedirProtocols(Connection
*conn
, value option
)
5405 handleProtocolsOption(CURLOPT_REDIR_PROTOCOLS
, conn
, option
);
5409 #pragma message("libcurl does not implement CURLOPT_PROTOCOLS or CURLOPT_REDIR_PROTOCOLS")
5410 static void handleProtocols(Connection
*conn
, value option
)
5412 failwith("libcurl does not implement CURLOPT_PROTOCOLS");
5414 static void handleRedirProtocols(Connection
*conn
, value option
)
5416 failwith("libcurl does not implement CURLOPT_REDIR_PROTOCOLS");
5420 #if HAVE_DECL_CURLOPT_RESOLVE
5421 static void handleResolve(Connection
*conn
, value option
)
5426 CURLcode result
= CURLE_OK
;
5428 free_curl_slist(conn
->resolve
);
5429 conn
->resolve
= NULL
;
5433 while (head
!= Val_emptylist
)
5435 conn
->resolve
= curl_slist_append(conn
->resolve
, String_val(Field(head
,0)));
5436 head
= Field(head
, 1);
5439 result
= curl_easy_setopt(conn
->connection
,
5443 if (result
!= CURLE_OK
)
5444 raiseError(conn
, result
);
5450 #pragma message("libcurl does not implement CURLOPT_RESOLVE")
5451 static void handleResolve(Connection
*conn
, value option
)
5453 failwith("libcurl does not implement CURLOPT_RESOLVE");
5457 #if HAVE_DECL_CURLOPT_DNS_SERVERS
5458 static void handleDnsServers(Connection
*conn
, value option
)
5462 CURLcode result
= CURLE_OK
;
5463 free_if(conn
->dns_servers
);
5465 conn
->dns_servers
= strdup(String_val(option
));
5467 result
= curl_easy_setopt(conn
->connection
,
5468 CURLOPT_DNS_SERVERS
,
5471 if (result
!= CURLE_OK
)
5472 raiseError(conn
, result
);
5477 #pragma message("libcurl does not implement CURLOPT_DNS_SERVERS")
5478 static void handleDnsServers(Connection
*conn
, value option
)
5480 failwith("libcurl does not implement CURLOPT_DNS_SERVERS");
5485 ** curl_easy_setopt helper function
5488 CAMLprim value
helper_curl_easy_setopt(value conn
, value option
)
5490 CAMLparam2(conn
, option
);
5492 Connection
*connection
= Connection_val(conn
);
5494 checkConnection(connection
);
5496 if (Is_long(option
))
5500 sprintf(error
, "Unimplemented Option: %s",
5501 findOption(unimplementedOptionMap
,
5502 (CURLoption
)(Long_val(option
))));
5507 if (!Is_block(option
))
5508 failwith("Not a block");
5510 if (Wosize_val(option
) < 1)
5511 failwith("Insufficient data in block");
5513 data
= Field(option
, 0);
5515 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5516 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5519 failwith("Invalid CURLOPT Option");
5521 CAMLreturn(Val_unit
);
5525 ** curl_easy_perform helper function
5528 CAMLprim value
helper_curl_easy_perform(value conn
)
5531 CURLcode result
= CURLE_OK
;
5532 Connection
*connection
= Connection_val(conn
);
5534 checkConnection(connection
);
5536 enter_blocking_section();
5537 result
= curl_easy_perform(connection
->connection
);
5538 leave_blocking_section();
5540 if (result
!= CURLE_OK
)
5541 raiseError(connection
, result
);
5543 CAMLreturn(Val_unit
);
5547 ** curl_easy_cleanup helper function
5550 CAMLprim value
helper_curl_easy_cleanup(value conn
)
5553 Connection
*connection
= Connection_val(conn
);
5555 checkConnection(connection
);
5557 removeConnection(connection
);
5559 CAMLreturn(Val_unit
);
5563 ** curl_easy_duphandle helper function
5566 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5570 Connection
*connection
= Connection_val(conn
);
5572 checkConnection(connection
);
5574 result
= caml_alloc(1, Abstract_tag
);
5575 Field(result
, 0) = (value
)duplicateConnection(connection
);
5581 ** curl_easy_getinfo helper function
5584 enum GetInfoResultType
{
5585 StringValue
, LongValue
, DoubleValue
, StringListValue
5588 value
convertStringList(struct curl_slist
*slist
)
5591 CAMLlocal3(result
, current
, next
);
5592 struct curl_slist
*p
= slist
;
5594 result
= Val_int(0);
5595 current
= Val_int(0);
5600 next
= alloc_tuple(2);
5601 Store_field(next
, 0, copy_string(p
->data
));
5602 Store_field(next
, 1, Val_int(0));
5604 if (result
== Val_int(0))
5607 if (current
!= Val_int(0))
5608 Store_field(current
, 1, next
);
5615 curl_slist_free_all(slist
);
5620 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5622 CAMLparam2(conn
, option
);
5624 CURLcode curlResult
;
5625 Connection
*connection
= Connection_val(conn
);
5626 enum GetInfoResultType resultType
;
5627 char *strValue
= NULL
;
5630 struct curl_slist
*stringListValue
= NULL
;
5632 checkConnection(connection
);
5634 switch(Long_val(option
))
5636 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5637 case 0: /* CURLINFO_EFFECTIVE_URL */
5638 resultType
= StringValue
;
5640 curlResult
= curl_easy_getinfo(connection
->connection
,
5641 CURLINFO_EFFECTIVE_URL
,
5645 #pragma message("libcurl does not provide CURLINFO_EFFECTIVE_URL")
5648 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5649 case 1: /* CURLINFO_HTTP_CODE */
5650 case 2: /* CURLINFO_RESPONSE_CODE */
5651 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5652 resultType
= LongValue
;
5654 curlResult
= curl_easy_getinfo(connection
->connection
,
5655 CURLINFO_RESPONSE_CODE
,
5658 resultType
= LongValue
;
5660 curlResult
= curl_easy_getinfo(connection
->connection
,
5667 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5668 case 3: /* CURLINFO_TOTAL_TIME */
5669 resultType
= DoubleValue
;
5671 curlResult
= curl_easy_getinfo(connection
->connection
,
5672 CURLINFO_TOTAL_TIME
,
5677 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5678 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5679 resultType
= DoubleValue
;
5681 curlResult
= curl_easy_getinfo(connection
->connection
,
5682 CURLINFO_NAMELOOKUP_TIME
,
5687 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5688 case 5: /* CURLINFO_CONNECT_TIME */
5689 resultType
= DoubleValue
;
5691 curlResult
= curl_easy_getinfo(connection
->connection
,
5692 CURLINFO_CONNECT_TIME
,
5697 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5698 case 6: /* CURLINFO_PRETRANSFER_TIME */
5699 resultType
= DoubleValue
;
5701 curlResult
= curl_easy_getinfo(connection
->connection
,
5702 CURLINFO_PRETRANSFER_TIME
,
5707 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5708 case 7: /* CURLINFO_SIZE_UPLOAD */
5709 resultType
= DoubleValue
;
5711 curlResult
= curl_easy_getinfo(connection
->connection
,
5712 CURLINFO_SIZE_UPLOAD
,
5717 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5718 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5719 resultType
= DoubleValue
;
5721 curlResult
= curl_easy_getinfo(connection
->connection
,
5722 CURLINFO_SIZE_DOWNLOAD
,
5727 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5728 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5729 resultType
= DoubleValue
;
5731 curlResult
= curl_easy_getinfo(connection
->connection
,
5732 CURLINFO_SPEED_DOWNLOAD
,
5737 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5738 case 10: /* CURLINFO_SPEED_UPLOAD */
5739 resultType
= DoubleValue
;
5741 curlResult
= curl_easy_getinfo(connection
->connection
,
5742 CURLINFO_SPEED_UPLOAD
,
5748 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5749 case 11: /* CURLINFO_HEADER_SIZE */
5750 resultType
= LongValue
;
5752 curlResult
= curl_easy_getinfo(connection
->connection
,
5753 CURLINFO_HEADER_SIZE
,
5758 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5759 case 12: /* CURLINFO_REQUEST_SIZE */
5760 resultType
= LongValue
;
5762 curlResult
= curl_easy_getinfo(connection
->connection
,
5763 CURLINFO_REQUEST_SIZE
,
5768 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5769 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5770 resultType
= LongValue
;
5772 curlResult
= curl_easy_getinfo(connection
->connection
,
5773 CURLINFO_SSL_VERIFYRESULT
,
5778 #if HAVE_DECL_CURLINFO_FILETIME
5779 case 14: /* CURLINFO_FILETIME */
5780 resultType
= DoubleValue
;
5782 curlResult
= curl_easy_getinfo(connection
->connection
,
5786 doubleValue
= longValue
;
5790 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5791 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5792 resultType
= DoubleValue
;
5794 curlResult
= curl_easy_getinfo(connection
->connection
,
5795 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5800 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5801 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5802 resultType
= DoubleValue
;
5804 curlResult
= curl_easy_getinfo(connection
->connection
,
5805 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5810 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5811 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5812 resultType
= DoubleValue
;
5814 curlResult
= curl_easy_getinfo(connection
->connection
,
5815 CURLINFO_STARTTRANSFER_TIME
,
5820 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5821 case 18: /* CURLINFO_CONTENT_TYPE */
5822 resultType
= StringValue
;
5824 curlResult
= curl_easy_getinfo(connection
->connection
,
5825 CURLINFO_CONTENT_TYPE
,
5830 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5831 case 19: /* CURLINFO_REDIRECT_TIME */
5832 resultType
= DoubleValue
;
5834 curlResult
= curl_easy_getinfo(connection
->connection
,
5835 CURLINFO_REDIRECT_TIME
,
5840 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5841 case 20: /* CURLINFO_REDIRECT_COUNT */
5842 resultType
= LongValue
;
5844 curlResult
= curl_easy_getinfo(connection
->connection
,
5845 CURLINFO_REDIRECT_COUNT
,
5850 #if HAVE_DECL_CURLINFO_PRIVATE
5851 case 21: /* CURLINFO_PRIVATE */
5852 resultType
= StringValue
;
5854 curlResult
= curl_easy_getinfo(connection
->connection
,
5860 #if HAVE_DECL_CURLINFO_HTTP_CONNECTCODE
5861 case 22: /* CURLINFO_HTTP_CONNECTCODE */
5862 resultType
= LongValue
;
5864 curlResult
= curl_easy_getinfo(connection
->connection
,
5865 CURLINFO_HTTP_CONNECTCODE
,
5870 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5871 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5872 resultType
= LongValue
;
5874 curlResult
= curl_easy_getinfo(connection
->connection
,
5875 CURLINFO_HTTPAUTH_AVAIL
,
5880 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5881 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5882 resultType
= LongValue
;
5884 curlResult
= curl_easy_getinfo(connection
->connection
,
5885 CURLINFO_PROXYAUTH_AVAIL
,
5890 #if HAVE_DECL_CURLINFO_OS_ERRNO
5891 case 25: /* CURLINFO_OS_ERRNO */
5892 resultType
= LongValue
;
5894 curlResult
= curl_easy_getinfo(connection
->connection
,
5900 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5901 case 26: /* CURLINFO_NUM_CONNECTS */
5902 resultType
= LongValue
;
5904 curlResult
= curl_easy_getinfo(connection
->connection
,
5905 CURLINFO_NUM_CONNECTS
,
5910 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5911 case 27: /* CURLINFO_SSL_ENGINES */
5912 resultType
= StringListValue
;
5914 curlResult
= curl_easy_getinfo(connection
->connection
,
5915 CURLINFO_SSL_ENGINES
,
5920 #if HAVE_DECL_CURLINFO_COOKIELIST
5921 case 28: /* CURLINFO_COOKIELIST */
5922 resultType
= StringListValue
;
5924 curlResult
= curl_easy_getinfo(connection
->connection
,
5925 CURLINFO_COOKIELIST
,
5930 #if HAVE_DECL_CURLINFO_LASTSOCKET
5931 case 29: /* CURLINFO_LASTSOCKET */
5932 resultType
= LongValue
;
5934 curlResult
= curl_easy_getinfo(connection
->connection
,
5935 CURLINFO_LASTSOCKET
,
5940 #if HAVE_DECL_CURLINFO_FTP_ENTRY_PATH
5941 case 30: /* CURLINFO_FTP_ENTRY_PATH */
5942 resultType
= StringValue
;
5944 curlResult
= curl_easy_getinfo(connection
->connection
,
5945 CURLINFO_FTP_ENTRY_PATH
,
5950 #if HAVE_DECL_CURLINFO_REDIRECT_URL
5951 case 31: /* CURLINFO_REDIRECT_URL */
5952 resultType
= StringValue
;
5954 curlResult
= curl_easy_getinfo(connection
->connection
,
5955 CURLINFO_REDIRECT_URL
,
5959 #pragma message("libcurl does not provide CURLINFO_REDIRECT_URL")
5962 #if HAVE_DECL_CURLINFO_PRIMARY_IP
5963 case 32: /* CURLINFO_PRIMARY_IP */
5964 resultType
= StringValue
;
5966 curlResult
= curl_easy_getinfo(connection
->connection
,
5967 CURLINFO_PRIMARY_IP
,
5971 #pragma message("libcurl does not provide CURLINFO_PRIMARY_IP")
5974 #if HAVE_DECL_CURLINFO_LOCAL_IP
5975 case 33: /* CURLINFO_LOCAL_IP */
5976 resultType
= StringValue
;
5978 curlResult
= curl_easy_getinfo(connection
->connection
,
5983 #pragma message("libcurl does not provide CURLINFO_LOCAL_IP")
5986 #if HAVE_DECL_CURLINFO_LOCAL_PORT
5987 case 34: /* CURLINFO_LOCAL_PORT */
5988 resultType
= LongValue
;
5990 curlResult
= curl_easy_getinfo(connection
->connection
,
5991 CURLINFO_LOCAL_PORT
,
5995 #pragma message("libcurl does not provide CURLINFO_LOCAL_PORT")
5998 #if HAVE_DECL_CURLINFO_CONDITION_UNMET
5999 case 35: /* CURLINFO_CONDITION_UNMET */
6000 resultType
= LongValue
;
6002 curlResult
= curl_easy_getinfo(connection
->connection
,
6003 CURLINFO_CONDITION_UNMET
,
6007 #pragma message("libcurl does not provide CURLINFO_CONDITION_UNMET")
6011 failwith("Invalid CURLINFO Option");
6015 if (curlResult
!= CURLE_OK
)
6016 raiseError(connection
, curlResult
);
6021 result
= alloc(1, StringValue
);
6022 Store_field(result
, 0, copy_string(strValue
?strValue
:""));
6026 result
= alloc(1, LongValue
);
6027 Store_field(result
, 0, Val_long(longValue
));
6031 result
= alloc(1, DoubleValue
);
6032 Store_field(result
, 0, copy_double(doubleValue
));
6035 case StringListValue
:
6036 result
= alloc(1, StringListValue
);
6037 Store_field(result
, 0, convertStringList(stringListValue
));
6045 ** curl_escape helper function
6048 CAMLprim value
helper_curl_escape(value str
)
6054 curlResult
= curl_escape(String_val(str
), string_length(str
));
6055 result
= copy_string(curlResult
);
6062 ** curl_unescape helper function
6065 CAMLprim value
helper_curl_unescape(value str
)
6071 curlResult
= curl_unescape(String_val(str
), string_length(str
));
6072 result
= copy_string(curlResult
);
6079 ** curl_getdate helper function
6082 CAMLprim value
helper_curl_getdate(value str
, value now
)
6084 CAMLparam2(str
, now
);
6089 curlNow
= (time_t)Double_val(now
);
6090 curlResult
= curl_getdate(String_val(str
), &curlNow
);
6091 result
= copy_double((double)curlResult
);
6097 ** curl_version helper function
6100 CAMLprim value
helper_curl_version(void)
6106 str
= curl_version();
6107 result
= copy_string(str
);
6112 struct CURLVersionBitsMapping
6118 struct CURLVersionBitsMapping versionBitsMap
[] =
6120 {CURL_VERSION_IPV6
, "ipv6"},
6121 {CURL_VERSION_KERBEROS4
, "kerberos4"},
6122 {CURL_VERSION_SSL
, "ssl"},
6123 {CURL_VERSION_LIBZ
, "libz"},
6124 {CURL_VERSION_NTLM
, "ntlm"},
6125 {CURL_VERSION_GSSNEGOTIATE
, "gssnegotiate"},
6126 {CURL_VERSION_DEBUG
, "debug"},
6127 {CURL_VERSION_CURLDEBUG
, "curldebug"},
6128 {CURL_VERSION_ASYNCHDNS
, "asynchdns"},
6129 {CURL_VERSION_SPNEGO
, "spnego"},
6130 {CURL_VERSION_LARGEFILE
, "largefile"},
6131 {CURL_VERSION_IDN
, "idn"},
6132 {CURL_VERSION_SSPI
, "sspi"},
6133 {CURL_VERSION_CONV
, "conv"},
6134 #if HAVE_DECL_CURL_VERSION_TLSAUTH_SRP
6135 {CURL_VERSION_TLSAUTH_SRP
, "srp"},
6137 #if HAVE_DECL_CURL_VERSION_NTLM_WB
6138 {CURL_VERSION_NTLM_WB
, "wb"},
6142 CAMLprim value
caml_curl_version_info(value unit
)
6145 CAMLlocal4(v
, vlist
, vnum
, vfeatures
);
6146 const char* const* p
= NULL
;
6149 curl_version_info_data
* data
= curl_version_info(CURLVERSION_NOW
);
6150 if (NULL
== data
) caml_failwith("curl_version_info");
6152 vlist
= Val_emptylist
;
6153 for (p
= data
->protocols
; NULL
!= *p
; p
++)
6155 vlist
= Val_cons(vlist
, caml_copy_string(*p
));
6158 vfeatures
= Val_emptylist
;
6159 for (i
= 0; i
< sizeof(versionBitsMap
)/sizeof(versionBitsMap
[0]); i
++)
6161 if (0 != (versionBitsMap
[i
].code
& data
->features
))
6162 vfeatures
= Val_cons(vfeatures
, caml_copy_string(versionBitsMap
[i
].name
));
6165 vnum
= caml_alloc_tuple(3);
6166 Store_field(vnum
,0,Val_int(0xFF & (data
->version_num
>> 16)));
6167 Store_field(vnum
,1,Val_int(0xFF & (data
->version_num
>> 8)));
6168 Store_field(vnum
,2,Val_int(0xFF & (data
->version_num
)));
6170 v
= caml_alloc_tuple(12);
6171 Store_field(v
,0,caml_copy_string(data
->version
));
6172 Store_field(v
,1,vnum
);
6173 Store_field(v
,2,caml_copy_string(data
->host
));
6174 Store_field(v
,3,vfeatures
);
6175 Store_field(v
,4,data
->ssl_version
? Val_some(caml_copy_string(data
->ssl_version
)) : Val_none
);
6176 Store_field(v
,5,data
->libz_version
? Val_some(caml_copy_string(data
->libz_version
)) : Val_none
);
6177 Store_field(v
,6,vlist
);
6178 Store_field(v
,7,caml_copy_string((data
->age
>= 1 && data
->ares
) ? data
->ares
: ""));
6179 Store_field(v
,8,Val_int((data
->age
>= 1) ? data
->ares_num
: 0));
6180 Store_field(v
,9,caml_copy_string((data
->age
>= 2 && data
->libidn
) ? data
->libidn
: ""));
6181 Store_field(v
,10,Val_int((data
->age
>= 3) ? data
->iconv_ver_num
: 0));
6182 Store_field(v
,11,caml_copy_string((data
->age
>= 3 && data
->libssh_version
) ? data
->libssh_version
: ""));
6187 CAMLprim value
caml_curl_pause(value conn
, value opts
)
6189 CAMLparam2(conn
, opts
);
6190 CAMLlocal4(v
, vlist
, vnum
, vfeatures
);
6191 Connection
*connection
= Connection_val(conn
);
6195 while (Val_emptylist
!= opts
)
6197 switch (Int_val(Field(opts
,0)))
6199 case 0: bitmask
|= CURLPAUSE_SEND
; break;
6200 case 1: bitmask
|= CURLPAUSE_RECV
; break;
6201 case 2: bitmask
|= CURLPAUSE_ALL
; break;
6202 default: caml_failwith("wrong pauseOption");
6204 opts
= Field(opts
,1);
6207 result
= curl_easy_pause(connection
->connection
,bitmask
);
6208 if (result
!= CURLE_OK
)
6209 raiseError(connection
, result
);
6211 CAMLreturn(Val_unit
);
6215 * Curl multi stack support
6217 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
6218 * Other exported functions are prefixed with caml_curlm_, some of them
6219 * can/should be decomposed into smaller parts.
6222 struct ml_multi_handle
6225 value values
; /* callbacks */
6230 curlmopt_socket_function
,
6231 curlmopt_timer_function
,
6233 /* last, not used */
6237 typedef struct ml_multi_handle ml_multi_handle
;
6239 #define Multi_val(v) (*(ml_multi_handle**)Data_custom_val(v))
6240 #define CURLM_val(v) (Multi_val(v)->handle)
6242 static struct custom_operations curl_multi_ops
= {
6244 custom_finalize_default
,
6245 custom_compare_default
,
6246 custom_hash_default
,
6247 custom_serialize_default
,
6248 custom_deserialize_default
,
6249 #if defined(custom_compare_ext_default)
6250 custom_compare_ext_default
,
6254 CAMLprim value
caml_curl_multi_init(value unit
)
6258 ml_multi_handle
* multi
= (ml_multi_handle
*)caml_stat_alloc(sizeof(ml_multi_handle
));
6259 CURLM
* h
= curl_multi_init();
6263 caml_stat_free(multi
);
6264 failwith("caml_curl_multi_init");
6268 multi
->values
= caml_alloc(multi_values_total
, 0);
6269 caml_register_generational_global_root(&multi
->values
);
6271 v
= caml_alloc_custom(&curl_multi_ops
, sizeof(ml_multi_handle
*), 0, 1);
6272 Multi_val(v
) = multi
;
6277 CAMLprim value
caml_curl_multi_cleanup(value handle
)
6280 ml_multi_handle
* h
= Multi_val(handle
);
6283 CAMLreturn(Val_unit
);
6285 caml_remove_generational_global_root(&h
->values
);
6287 if (CURLM_OK
!= curl_multi_cleanup(h
->handle
))
6288 failwith("caml_curl_multi_cleanup");
6290 Multi_val(handle
) = (ml_multi_handle
*)NULL
;
6292 CAMLreturn(Val_unit
);
6295 static CURL
* curlm_remove_finished(CURLM
* multi_handle
, CURLcode
* result
)
6297 int msgs_in_queue
= 0;
6301 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
6302 if (NULL
== msg
) return NULL
;
6303 if (CURLMSG_DONE
== msg
->msg
)
6305 CURL
* easy_handle
= msg
->easy_handle
;
6306 if (result
) *result
= msg
->data
.result
;
6307 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
6309 /*failwith("curlm_remove_finished");*/
6316 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
6318 CAMLparam1(v_multi
);
6319 CAMLlocal2(v_easy
, v_tuple
);
6321 CURLM
* multi_handle
;
6324 multi_handle
= CURLM_val(v_multi
);
6326 caml_enter_blocking_section();
6327 handle
= curlm_remove_finished(multi_handle
,&result
);
6328 caml_leave_blocking_section();
6332 CAMLreturn(Val_none
);
6336 /* not good: same handle, but different block */
6337 v_easy
= caml_alloc(1, Abstract_tag
);
6338 Field(v_easy
, 0) = (value
)findConnection(handle
);
6339 v_tuple
= caml_alloc(2, 0);
6340 Store_field(v_tuple
,0,v_easy
);
6341 Store_field(v_tuple
,1,Val_int(result
)); /* CURLcode */
6342 CAMLreturn(Val_some(v_tuple
));
6346 static int curlm_wait_data(CURLM
* multi_handle
)
6348 struct timeval timeout
;
6360 /* set a suitable timeout */
6362 timeout
.tv_usec
= 0;
6364 /* get file descriptors from the transfers */
6365 ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
6367 if (ret
== CURLM_OK
&& maxfd
>= 0)
6369 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
6370 if (-1 != rc
) return 0;
6375 CAMLprim value
caml_curlm_wait_data(value v_multi
)
6377 CAMLparam1(v_multi
);
6379 CURLM
* h
= CURLM_val(v_multi
);
6381 caml_enter_blocking_section();
6382 ret
= curlm_wait_data(h
);
6383 caml_leave_blocking_section();
6385 CAMLreturn(Val_bool(0 == ret
));
6388 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
6390 CAMLparam2(v_multi
,v_easy
);
6391 CURLM
* multi
= CURLM_val(v_multi
);
6392 CURL
* easy
= Connection_val(v_easy
)->connection
;
6394 /* may invoke callbacks so need to be consistent with locks */
6395 caml_enter_blocking_section();
6396 if (CURLM_OK
!= curl_multi_add_handle(multi
, easy
))
6398 caml_leave_blocking_section();
6399 failwith("caml_curl_multi_add_handle");
6401 caml_leave_blocking_section();
6403 CAMLreturn(Val_unit
);
6406 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
6408 CAMLparam1(v_multi
);
6409 int still_running
= 0;
6410 CURLM
* h
= CURLM_val(v_multi
);
6412 caml_enter_blocking_section();
6413 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
6414 caml_leave_blocking_section();
6416 CAMLreturn(Val_int(still_running
));
6419 CAMLprim value
helper_curl_easy_strerror(value v_code
)
6422 CAMLreturn(caml_copy_string(curl_easy_strerror(Int_val(v_code
))));
6426 * Wrappers for the curl_multi_socket_action infrastructure
6427 * Based on curl hiperfifo.c example
6430 /* FIXME win32unix */
6431 #define Socket_val(v) Int_val(v)
6432 #define Val_socket(v) Val_int(v)
6434 static void raise_error(char const* msg
)
6436 static value
* exception
= NULL
;
6438 if (NULL
== exception
)
6440 exception
= caml_named_value("Curl.Multi.Error");
6441 if (NULL
== exception
) caml_invalid_argument("Curl.Multi.Error");
6444 caml_raise_with_string(*exception
, msg
);
6447 static void check_mcode(CURLMcode code
)
6449 char const *s
= NULL
;
6452 case CURLM_OK
: return;
6453 case CURLM_CALL_MULTI_PERFORM
: s
="CURLM_CALL_MULTI_PERFORM"; break;
6454 case CURLM_BAD_HANDLE
: s
="CURLM_BAD_HANDLE"; break;
6455 case CURLM_BAD_EASY_HANDLE
: s
="CURLM_BAD_EASY_HANDLE"; break;
6456 case CURLM_OUT_OF_MEMORY
: s
="CURLM_OUT_OF_MEMORY"; break;
6457 case CURLM_INTERNAL_ERROR
: s
="CURLM_INTERNAL_ERROR"; break;
6458 case CURLM_UNKNOWN_OPTION
: s
="CURLM_UNKNOWN_OPTION"; break;
6459 case CURLM_LAST
: s
="CURLM_LAST"; break;
6460 case CURLM_BAD_SOCKET
: s
="CURLM_BAD_SOCKET"; break;
6461 default : s
="CURLM_unknown"; break;
6466 CAMLprim value
caml_curl_multi_socket_action(value v_multi
, value v_fd
, value v_kind
)
6468 CAMLparam3(v_multi
, v_fd
, v_kind
);
6469 CURLM
* h
= CURLM_val(v_multi
);
6470 int still_running
= 0;
6471 CURLMcode rc
= CURLM_OK
;
6472 int socket
= Socket_val(v_fd
);
6475 switch (Int_val(v_kind
))
6478 case 1 : kind
|= CURL_CSELECT_IN
; break;
6479 case 2 : kind
|= CURL_CSELECT_OUT
; break;
6480 case 3 : kind
|= CURL_CSELECT_IN
| CURL_CSELECT_OUT
; break;
6482 raise_error("caml_curl_multi_socket_action");
6485 /* fprintf(stdout,"fd %u kind %u\n",Socket_val(v_fd), kind); fflush(stdout); */
6487 caml_enter_blocking_section();
6489 rc
= curl_multi_socket_action(h
, socket
, kind
, &still_running
);
6490 } while (rc
== CURLM_CALL_MULTI_PERFORM
);
6491 caml_leave_blocking_section();
6495 CAMLreturn(Val_int(still_running
));
6498 CAMLprim value
caml_curl_multi_socket_all(value v_multi
)
6500 CAMLparam1(v_multi
);
6501 int still_running
= 0;
6502 CURLMcode rc
= CURLM_OK
;
6503 CURLM
* h
= CURLM_val(v_multi
);
6505 caml_enter_blocking_section();
6507 rc
= curl_multi_socket_all(h
, &still_running
);
6508 } while (rc
== CURLM_CALL_MULTI_PERFORM
);
6509 caml_leave_blocking_section();
6513 CAMLreturn(Val_int(still_running
));
6516 static int curlm_sock_cb_nolock(CURL
*e
, curl_socket_t sock
, int what
, ml_multi_handle
* multi
, void *sockp
)
6521 (void)sockp
; /* not used */
6523 /* v_what = Val_int(what); */
6526 case CURL_POLL_NONE
: v_what
= Val_int(0); break;
6527 case CURL_POLL_IN
: v_what
= Val_int(1); break;
6528 case CURL_POLL_OUT
: v_what
= Val_int(2); break;
6529 case CURL_POLL_INOUT
: v_what
= Val_int(3); break;
6530 case CURL_POLL_REMOVE
: v_what
= Val_int(4); break;
6532 fprintf(stderr
, "curlm_sock_cb sock=%d what=%d\n", sock
, what
);
6534 raise_error("curlm_sock_cb"); /* FIXME exception from callback */
6537 caml_callback2(Field(multi
->values
,curlmopt_socket_function
),
6538 Val_socket(sock
), v_what
);
6543 static int curlm_sock_cb(CURL
*e
, curl_socket_t sock
, int what
, void *cbp
, void *sockp
)
6546 caml_leave_blocking_section();
6547 ret
= curlm_sock_cb_nolock(e
, sock
, what
, (ml_multi_handle
*)cbp
, sockp
);
6548 caml_enter_blocking_section();
6552 CAMLprim value
caml_curl_multi_socketfunction(value v_multi
, value v_cb
)
6554 CAMLparam2(v_multi
, v_cb
);
6555 ml_multi_handle
* multi
= Multi_val(v_multi
);
6557 Store_field(multi
->values
, curlmopt_socket_function
, v_cb
);
6559 curl_multi_setopt(multi
->handle
, CURLMOPT_SOCKETFUNCTION
, curlm_sock_cb
);
6560 curl_multi_setopt(multi
->handle
, CURLMOPT_SOCKETDATA
, multi
);
6562 CAMLreturn(Val_unit
);
6565 static void curlm_timer_cb_nolock(ml_multi_handle
*multi
, long timeout_ms
)
6568 caml_callback(Field(multi
->values
,curlmopt_timer_function
), Val_long(timeout_ms
));
6572 static int curlm_timer_cb(CURLM
*multi
, long timeout_ms
, void *userp
)
6576 caml_leave_blocking_section();
6577 curlm_timer_cb_nolock((ml_multi_handle
*)userp
, timeout_ms
);
6578 caml_enter_blocking_section();
6582 CAMLprim value
caml_curl_multi_timerfunction(value v_multi
, value v_cb
)
6584 CAMLparam2(v_multi
, v_cb
);
6585 ml_multi_handle
* multi
= Multi_val(v_multi
);
6587 Store_field(multi
->values
, curlmopt_timer_function
, v_cb
);
6589 curl_multi_setopt(multi
->handle
, CURLMOPT_TIMERFUNCTION
, curlm_timer_cb
);
6590 curl_multi_setopt(multi
->handle
, CURLMOPT_TIMERDATA
, multi
);
6592 CAMLreturn(Val_unit
);
6595 CAMLprim value
caml_curl_multi_timeout(value v_multi
)
6597 CAMLparam1(v_multi
);
6599 CURLMcode rc
= CURLM_OK
;
6600 ml_multi_handle
* multi
= Multi_val(v_multi
);
6602 rc
= curl_multi_timeout(multi
->handle
, &ms
);
6606 CAMLreturn(Val_long(ms
));