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 #warning "No config file given."
33 void leave_blocking_section(void);
34 void enter_blocking_section(void);
36 #define Val_none Val_int(0)
43 some
= caml_alloc(1, 0);
44 Store_field( some
, 0, v
);
48 static value
Val_pair(value v1
, value v2
)
52 pair
= caml_alloc_small(2,0);
58 static value
Val_cons(value list
, value v
) { return Val_pair(v
,list
); }
60 typedef struct Connection Connection
;
61 typedef struct ConnectionList ConnectionList
;
63 #define Connection_val(v) ((Connection *)Field(v, 0))
76 OcamlProgressCallback
,
80 OcamlSeekFunctionCallback
,
81 OcamlOpenSocketFunctionCallback
,
113 OcamlFTPAlternativeToUser
,
114 OcamlSSHPublicKeyFile
,
115 OcamlSSHPrivateKeyFile
,
116 OcamlSSHHostPublicKeyMD5
,
119 /* Not used, last for size */
143 struct curl_slist
*httpHeader
;
144 struct curl_httppost
*httpPostFirst
;
145 struct curl_httppost
*httpPostLast
;
146 struct curl_slist
*httpPostStrings
;
154 struct curl_slist
*quote
;
155 struct curl_slist
*postQuote
;
166 struct curl_slist
*http200Aliases
;
170 char *ftpAlternativeToUser
;
171 char *sshPublicKeyFile
;
172 char *sshPrivateKeyFile
;
173 char *sshHostPublicKeyMD5
;
174 char *copyPostFields
;
177 struct ConnectionList
183 static ConnectionList connectionList
= {NULL
, NULL
};
185 typedef struct CURLErrorMapping CURLErrorMapping
;
187 struct CURLErrorMapping
193 CURLErrorMapping errorMap
[] =
195 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
196 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL
},
198 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
200 #if HAVE_DECL_CURLE_FAILED_INIT
201 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT
},
203 {"CURLE_FAILED_INIT", -1},
205 #if HAVE_DECL_CURLE_URL_MALFORMAT
206 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT
},
208 {"CURLE_URL_MALFORMAT", -1},
210 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
211 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER
},
213 {"CURLE_URL_MALFORMAT_USER", -1},
215 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
216 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY
},
218 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
220 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
221 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST
},
223 {"CURLE_COULDNT_RESOLVE_HOST", -1},
225 #if HAVE_DECL_CURLE_COULDNT_CONNECT
226 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT
},
228 {"CURLE_COULDNT_CONNECT", -1},
230 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
231 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY
},
233 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
235 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
236 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED
},
238 {"CURLE_FTP_ACCESS_DENIED", -1},
240 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
241 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT
},
243 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
245 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
246 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY
},
248 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
250 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
251 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY
},
253 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
255 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
256 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY
},
258 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
260 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
261 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT
},
263 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
265 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
266 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST
},
268 {"CURLE_FTP_CANT_GET_HOST", -1},
270 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
271 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT
},
273 {"CURLE_FTP_CANT_RECONNECT", -1},
275 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
276 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY
},
278 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
280 #if HAVE_DECL_CURLE_PARTIAL_FILE
281 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE
},
283 {"CURLE_PARTIAL_FILE", -1},
285 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
286 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE
},
288 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
290 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
291 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR
},
293 {"CURLE_FTP_WRITE_ERROR", -1},
295 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
296 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR
},
298 {"CURLE_FTP_QUOTE_ERROR", -1},
300 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
301 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND
},
303 {"CURLE_HTTP_NOT_FOUND", -1},
305 #if HAVE_DECL_CURLE_WRITE_ERROR
306 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR
},
308 {"CURLE_WRITE_ERROR", -1},
310 #if HAVE_DECL_CURLE_MALFORMAT_USER
311 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER
},
313 {"CURLE_MALFORMAT_USER", -1},
315 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
316 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE
},
318 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
320 #if HAVE_DECL_CURLE_READ_ERROR
321 {"CURLE_READ_ERROR", CURLE_READ_ERROR
},
323 {"CURLE_READ_ERROR", -1},
325 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
326 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY
},
328 {"CURLE_OUT_OF_MEMORY", -1},
330 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
331 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED
},
333 {"CURLE_OPERATION_TIMEOUTED", -1},
335 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
336 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII
},
338 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
340 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
341 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED
},
343 {"CURLE_FTP_PORT_FAILED", -1},
345 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
346 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST
},
348 {"CURLE_FTP_COULDNT_USE_REST", -1},
350 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
351 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE
},
353 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
355 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
356 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR
},
358 {"CURLE_HTTP_RANGE_ERROR", -1},
360 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
361 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR
},
363 {"CURLE_HTTP_POST_ERROR", -1},
365 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
366 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR
},
368 {"CURLE_SSL_CONNECT_ERROR", -1},
370 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
371 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME
},
373 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
375 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
376 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE
},
378 {"CURLE_FILE_COULDNT_READ_FILE", -1},
380 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
381 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND
},
383 {"CURLE_LDAP_CANNOT_BIND", -1},
385 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
386 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED
},
388 {"CURLE_LDAP_SEARCH_FAILED", -1},
390 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
391 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND
},
393 {"CURLE_LIBRARY_NOT_FOUND", -1},
395 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
396 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND
},
398 {"CURLE_FUNCTION_NOT_FOUND", -1},
400 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
401 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK
},
403 {"CURLE_ABORTED_BY_CALLBACK", -1},
405 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
406 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT
},
408 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
410 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
411 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER
},
413 {"CURLE_BAD_CALLING_ORDER", -1},
415 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
416 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED
},
418 {"CURLE_HTTP_PORT_FAILED", -1},
420 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
421 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED
},
423 {"CURLE_BAD_PASSWORD_ENTERED", -1},
425 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
426 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS
},
428 {"CURLE_TOO_MANY_REDIRECTS", -1},
430 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
431 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION
},
433 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
435 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
436 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX
},
438 {"CURLE_TELNET_OPTION_SYNTAX", -1},
440 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
441 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE
},
443 {"CURLE_SSL_PEER_CERTIFICATE", -1},
445 #if HAVE_DECL_CURLE_GOT_NOTHING
446 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING
},
448 {"CURLE_GOT_NOTHING", -1},
450 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
451 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND
},
453 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
455 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
456 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED
},
458 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
460 #if HAVE_DECL_CURLE_SEND_ERROR
461 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR
},
463 {"CURLE_SEND_ERROR", -1},
465 #if HAVE_DECL_CURLE_RECV_ERROR
466 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR
},
468 {"CURLE_RECV_ERROR", -1},
470 #if HAVE_DECL_CURLE_SHARE_IN_USE
471 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE
},
473 {"CURLE_SHARE_IN_USE", -1},
475 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
476 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM
},
478 {"CURLE_SSL_CERTPROBLEN", -1},
480 #if HAVE_DECL_CURLE_SSL_CIPHER
481 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER
},
483 {"CURLE_SSL_CIPHER", -1},
485 #if HAVE_DECL_CURLE_SSL_CACERT
486 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT
},
488 {"CURLE_SSL_CACERT", -1},
490 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
491 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING
},
493 {"CURLE_BAD_CONTENT_ENCODING", -1},
495 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
496 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL
},
498 {"CURLE_LDAP_INVALID_URL", -1},
500 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
501 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED
},
503 {"CURLE_FILESIZE_EXCEEDED", -1},
505 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
506 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED
},
508 {"CURLE_FTP_SSL_FAILED", -1},
510 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
511 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND
},
513 {"CURLE_SEND_FAIL_REWIND", -1},
515 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
516 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED
},
518 {"CURLE_SSL_ENGINE_INITFAILED", -1},
520 #if HAVE_DECL_CURLE_LOGIN_DENIED
521 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED
},
523 {"CURLE_LOGIN_DENIED", -1},
525 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
526 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND
},
528 {"CURLE_TFTP_NOTFOUND", -1},
530 #if HAVE_DECL_CURLE_TFTP_PERM
531 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM
},
533 {"CURLE_TFTP_PERM", -1},
535 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
536 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL
},
538 {"CURLE_REMOTE_DISK_FULL", -1},
540 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
541 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL
},
543 {"CURLE_TFTP_ILLEGAL", -1},
545 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
546 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID
},
548 {"CURLE_TFTP_UNKNOWNID", -1},
550 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
551 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS
},
553 {"CURLE_REMOTE_FILE_EXISTS", -1},
555 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
556 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER
},
558 {"CURLE_TFTP_NOSUCHUSER", -1},
560 #if HAVE_DECL_CURLE_CONV_FAILED
561 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED
},
563 {"CURLE_CONV_FAILED", -1},
565 #if HAVE_DECL_CURLE_CONV_REQUIRED
566 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED
},
568 {"CURLE_CONV_REQUIRED", -1},
570 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
571 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE
},
573 {"CURLE_SSL_CACERT_BADFILE", -1},
575 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
576 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND
},
578 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
580 #if HAVE_DECL_CURLE_SSH
581 {"CURLE_SSH", CURLE_SSH
},
585 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
586 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED
},
588 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
590 #if HAVE_DECL_CURLE_AGAIN
591 {"CURLE_AGAIN", CURLE_AGAIN
},
595 {"CURLE_OK", CURLE_OK
},
599 typedef struct CURLOptionMapping CURLOptionMapping
;
601 struct CURLOptionMapping
603 void (*optionHandler
)(Connection
*, value
);
608 CURLOptionMapping unimplementedOptionMap
[] =
610 {NULL
, "CURLOPT_STDERR", CURLOPT_STDERR
},
614 static void handleWriteFunction(Connection
*, value
);
615 static void handleReadFunction(Connection
*, value
);
616 static void handleInFileSize(Connection
*, value
);
617 static void handleURL(Connection
*, value
);
618 static void handleProxy(Connection
*, value
);
619 static void handleProxyPort(Connection
*, value
);
620 static void handleHTTPProxyTunnel(Connection
*, value
);
621 static void handleVerbose(Connection
*, value
);
622 static void handleHeader(Connection
*, value
);
623 static void handleNoProgress(Connection
*, value
);
624 static void handleNoSignal(Connection
*, value
);
625 static void handleNoBody(Connection
*, value
);
626 static void handleFailOnError(Connection
*, value
);
627 static void handleUpload(Connection
*, value
);
628 static void handlePost(Connection
*, value
);
629 static void handleFTPListOnly(Connection
*, value
);
630 static void handleFTPAppend(Connection
*, value
);
631 static void handleNETRC(Connection
*, value
);
632 static void handleEncoding(Connection
*, value
);
633 static void handleFollowLocation(Connection
*, value
);
634 static void handleTransferText(Connection
*, value
);
635 static void handlePut(Connection
*, value
);
636 static void handleUserPwd(Connection
*, value
);
637 static void handleProxyUserPwd(Connection
*, value
);
638 static void handleRange(Connection
*, value
);
639 static void handleErrorBuffer(Connection
*, value
);
640 static void handleTimeout(Connection
*, value
);
641 static void handlePostFields(Connection
*, value
);
642 static void handlePostFieldSize(Connection
*, value
);
643 static void handleReferer(Connection
*, value
);
644 static void handleUserAgent(Connection
*, value
);
645 static void handleFTPPort(Connection
*, value
);
646 static void handleLowSpeedLimit(Connection
*, value
);
647 static void handleLowSpeedTime(Connection
*, value
);
648 static void handleResumeFrom(Connection
*, value
);
649 static void handleCookie(Connection
*, value
);
650 static void handleHTTPHeader(Connection
*, value
);
651 static void handleHTTPPost(Connection
*, value
);
652 static void handleSSLCert(Connection
*, value
);
653 static void handleSSLCertType(Connection
*, value
);
654 static void handleSSLCertPasswd(Connection
*, value
);
655 static void handleSSLKey(Connection
*, value
);
656 static void handleSSLKeyType(Connection
*, value
);
657 static void handleSSLKeyPasswd(Connection
*, value
);
658 static void handleSSLEngine(Connection
*, value
);
659 static void handleSSLEngineDefault(Connection
*, value
);
660 static void handleCRLF(Connection
*, value
);
661 static void handleQuote(Connection
*, value
);
662 static void handlePostQuote(Connection
*, value
);
663 static void handleHeaderFunction(Connection
*, value
);
664 static void handleCookieFile(Connection
*, value
);
665 static void handleSSLVersion(Connection
*, value
);
666 static void handleTimeCondition(Connection
*, value
);
667 static void handleTimeValue(Connection
*, value
);
668 static void handleCustomRequest(Connection
*, value
);
669 static void handleInterface(Connection
*, value
);
670 static void handleKRB4Level(Connection
*, value
);
671 static void handleProgressFunction(Connection
*, value
);
672 static void handleSSLVerifyPeer(Connection
*, value
);
673 static void handleCAInfo(Connection
*, value
);
674 static void handleCAPath(Connection
*, value
);
675 static void handleFileTime(Connection
*, value
);
676 static void handleMaxRedirs(Connection
*, value
);
677 static void handleMaxConnects(Connection
*, value
);
678 static void handleClosePolicy(Connection
*, value
);
679 static void handleFreshConnect(Connection
*, value
);
680 static void handleForbidReuse(Connection
*, value
);
681 static void handleRandomFile(Connection
*, value
);
682 static void handleEGDSocket(Connection
*, value
);
683 static void handleConnectTimeout(Connection
*, value
);
684 static void handleHTTPGet(Connection
*, value
);
685 static void handleSSLVerifyHost(Connection
*, value
);
686 static void handleCookieJar(Connection
*, value
);
687 static void handleSSLCipherList(Connection
*, value
);
688 static void handleHTTPVersion(Connection
*, value
);
689 static void handleFTPUseEPSV(Connection
*, value
);
690 static void handleDNSCacheTimeout(Connection
*, value
);
691 static void handleDNSUseGlobalCache(Connection
*, value
);
692 static void handleDebugFunction(Connection
*, value
);
693 static void handlePrivate(Connection
*, value
);
694 static void handleHTTP200Aliases(Connection
*, value
);
695 static void handleUnrestrictedAuth(Connection
*, value
);
696 static void handleFTPUseEPRT(Connection
*, value
);
697 static void handleHTTPAuth(Connection
*, value
);
698 static void handleFTPCreateMissingDirs(Connection
*, value
);
699 static void handleProxyAuth(Connection
*, value
);
700 static void handleFTPResponseTimeout(Connection
*, value
);
701 static void handleIPResolve(Connection
*, value
);
702 static void handleMaxFileSize(Connection
*, value
);
703 static void handleInFileSizeLarge(Connection
*, value
);
704 static void handleResumeFromLarge(Connection
*, value
);
705 static void handleMaxFileSizeLarge(Connection
*, value
);
706 static void handleNETRCFile(Connection
*, value
);
707 static void handleFTPSSL(Connection
*, value
);
708 static void handlePostFieldSizeLarge(Connection
*, value
);
709 static void handleTCPNoDelay(Connection
*, value
);
710 static void handleFTPSSLAuth(Connection
*, value
);
711 static void handleIOCTLFunction(Connection
*, value
);
712 static void handleFTPAccount(Connection
*, value
);
713 static void handleCookieList(Connection
*, value
);
714 static void handleIgnoreContentLength(Connection
*, value
);
715 static void handleFTPSkipPASVIP(Connection
*, value
);
716 static void handleFTPFileMethod(Connection
*, value
);
717 static void handleLocalPort(Connection
*, value
);
718 static void handleLocalPortRange(Connection
*, value
);
719 static void handleConnectOnly(Connection
*, value
);
720 static void handleMaxSendSpeedLarge(Connection
*, value
);
721 static void handleMaxRecvSpeedLarge(Connection
*, value
);
722 static void handleFTPAlternativeToUser(Connection
*, value
);
723 static void handleSSLSessionIdCache(Connection
*, value
);
724 static void handleSSHAuthTypes(Connection
*, value
);
725 static void handleSSHPublicKeyFile(Connection
*, value
);
726 static void handleSSHPrivateKeyFile(Connection
*, value
);
727 static void handleFTPSSLCCC(Connection
*, value
);
728 static void handleTimeoutMS(Connection
*, value
);
729 static void handleConnectTimeoutMS(Connection
*, value
);
730 static void handleHTTPTransferDecoding(Connection
*, value
);
731 static void handleHTTPContentDecoding(Connection
*, value
);
732 static void handleNewFilePerms(Connection
*, value
);
733 static void handleNewDirectoryPerms(Connection
*, value
);
734 static void handlePost301(Connection
*, value
);
735 static void handleSSHHostPublicKeyMD5(Connection
*, value
);
736 static void handleCopyPostFields(Connection
*, value
);
737 static void handleProxyTransferMode(Connection
*, value
);
738 static void handleSeekFunction(Connection
*, value
);
739 static void handleAutoReferer(Connection
*, value
);
740 static void handleOpenSocketFunction(Connection
*, value
);
741 static void handleProxyType(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},
1079 static char *findOption(CURLOptionMapping optionMap
[],
1082 return optionMap
[option
].name
;
1085 static void free_curl_slist(struct curl_slist
*slist
)
1090 curl_slist_free_all(slist
);
1093 static void raiseError(Connection
*conn
, CURLcode code
)
1096 CAMLlocal1(exceptionData
);
1098 char *errorString
= "Unknown Error";
1101 for (i
= 0; errorMap
[i
].name
!= NULL
; i
++)
1103 if (errorMap
[i
].error
== code
)
1105 errorString
= errorMap
[i
].name
;
1110 exceptionData
= caml_alloc(3, 0);
1112 Store_field(exceptionData
, 0, Val_int(code
));
1113 Store_field(exceptionData
, 1, Val_int(code
));
1114 Store_field(exceptionData
, 2, copy_string(errorString
));
1116 if (conn
!= NULL
&& conn
->errorBuffer
!= NULL
)
1118 Store_field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0,
1119 copy_string(conn
->errorBuffer
));
1122 exception
= caml_named_value("CurlException");
1124 if (exception
== NULL
)
1125 caml_failwith("CurlException not registered");
1127 raise_with_arg(*exception
, exceptionData
);
1132 static void resetOcamlValues(Connection
* connection
)
1136 for (i
= 0; i
< OcamlValuesSize
; i
++)
1137 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1140 static Connection
*newConnection(void)
1142 Connection
*connection
;
1144 connection
= (Connection
*)malloc(sizeof(Connection
));
1146 enter_blocking_section();
1147 connection
->connection
= curl_easy_init();
1148 leave_blocking_section();
1150 connection
->next
= NULL
;
1151 connection
->prev
= NULL
;
1153 if (connectionList
.tail
== NULL
)
1155 connectionList
.tail
= connection
;
1156 connectionList
.head
= connection
;
1160 connection
->prev
= connectionList
.head
;
1161 connectionList
.head
->next
= connection
;
1162 connectionList
.head
= connection
;
1165 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1166 resetOcamlValues(connection
);
1167 register_global_root(&connection
->ocamlValues
);
1169 connection
->url
= NULL
;
1170 connection
->proxy
= NULL
;
1171 connection
->userPwd
= NULL
;
1172 connection
->proxyUserPwd
= NULL
;
1173 connection
->range
= NULL
;
1174 connection
->errorBuffer
= NULL
;
1175 connection
->postFields
= NULL
;
1176 connection
->postFieldSize
= -1;
1177 connection
->referer
= NULL
;
1178 connection
->userAgent
= NULL
;
1179 connection
->ftpPort
= NULL
;
1180 connection
->cookie
= NULL
;
1181 connection
->httpHeader
= NULL
;
1182 connection
->httpPostFirst
= NULL
;
1183 connection
->httpPostLast
= NULL
;
1184 connection
->httpPostStrings
= NULL
;
1185 connection
->sslCert
= NULL
;
1186 connection
->sslCertType
= NULL
;
1187 connection
->sslCertPasswd
= NULL
;
1188 connection
->sslKey
= NULL
;
1189 connection
->sslKeyType
= NULL
;
1190 connection
->sslKeyPasswd
= NULL
;
1191 connection
->sslEngine
= NULL
;
1192 connection
->quote
= NULL
;
1193 connection
->postQuote
= NULL
;
1194 connection
->cookieFile
= NULL
;
1195 connection
->customRequest
= NULL
;
1196 connection
->interface
= NULL
;
1197 connection
->caInfo
= NULL
;
1198 connection
->caPath
= NULL
;
1199 connection
->randomFile
= NULL
;
1200 connection
->egdSocket
= NULL
;
1201 connection
->cookieJar
= NULL
;
1202 connection
->sslCipherList
= NULL
;
1203 connection
->private = NULL
;
1204 connection
->http200Aliases
= NULL
;
1205 connection
->netrcFile
= NULL
;
1206 connection
->ftpaccount
= NULL
;
1207 connection
->cookielist
= NULL
;
1208 connection
->ftpAlternativeToUser
= NULL
;
1209 connection
->sshPublicKeyFile
= NULL
;
1210 connection
->sshPrivateKeyFile
= NULL
;
1211 connection
->copyPostFields
= NULL
;
1216 static Connection
*duplicateConnection(Connection
*original
)
1218 Connection
*connection
;
1220 connection
= (Connection
*)malloc(sizeof(Connection
));
1222 enter_blocking_section();
1223 connection
->connection
= curl_easy_duphandle(original
->connection
);
1224 leave_blocking_section();
1226 connection
->next
= NULL
;
1227 connection
->prev
= NULL
;
1229 if (connectionList
.tail
== NULL
)
1231 connectionList
.tail
= connection
;
1232 connectionList
.head
= connection
;
1236 connection
->prev
= connectionList
.head
;
1237 connectionList
.head
->next
= connection
;
1238 connectionList
.head
= connection
;
1241 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1242 resetOcamlValues(connection
);
1243 register_global_root(&connection
->ocamlValues
);
1245 Store_field(connection
->ocamlValues
, OcamlWriteCallback
,
1246 Field(original
->ocamlValues
, OcamlWriteCallback
));
1247 Store_field(connection
->ocamlValues
, OcamlReadCallback
,
1248 Field(original
->ocamlValues
, OcamlReadCallback
));
1249 Store_field(connection
->ocamlValues
, OcamlErrorBuffer
,
1250 Field(original
->ocamlValues
, OcamlErrorBuffer
));
1251 Store_field(connection
->ocamlValues
, OcamlPostFields
,
1252 Field(original
->ocamlValues
, OcamlPostFields
));
1253 Store_field(connection
->ocamlValues
, OcamlHTTPHeader
,
1254 Field(original
->ocamlValues
, OcamlHTTPHeader
));
1255 Store_field(connection
->ocamlValues
, OcamlQuote
,
1256 Field(original
->ocamlValues
, OcamlQuote
));
1257 Store_field(connection
->ocamlValues
, OcamlPostQuote
,
1258 Field(original
->ocamlValues
, OcamlPostQuote
));
1259 Store_field(connection
->ocamlValues
, OcamlHeaderCallback
,
1260 Field(original
->ocamlValues
, OcamlHeaderCallback
));
1261 Store_field(connection
->ocamlValues
, OcamlProgressCallback
,
1262 Field(original
->ocamlValues
, OcamlProgressCallback
));
1263 Store_field(connection
->ocamlValues
, OcamlDebugCallback
,
1264 Field(original
->ocamlValues
, OcamlDebugCallback
));
1265 Store_field(connection
->ocamlValues
, OcamlHTTP200Aliases
,
1266 Field(original
->ocamlValues
, OcamlHTTP200Aliases
));
1267 Store_field(connection
->ocamlValues
, OcamlIOCTLCallback
,
1268 Field(original
->ocamlValues
, OcamlIOCTLCallback
));
1269 Store_field(connection
->ocamlValues
, OcamlSeekFunctionCallback
,
1270 Field(original
->ocamlValues
, OcamlSeekFunctionCallback
));
1272 connection
->url
= NULL
;
1273 connection
->proxy
= NULL
;
1274 connection
->userPwd
= NULL
;
1275 connection
->proxyUserPwd
= NULL
;
1276 connection
->range
= NULL
;
1277 connection
->errorBuffer
= NULL
;
1278 connection
->postFields
= NULL
;
1279 connection
->postFieldSize
= -1;
1280 connection
->referer
= NULL
;
1281 connection
->userAgent
= NULL
;
1282 connection
->ftpPort
= NULL
;
1283 connection
->cookie
= NULL
;
1284 connection
->httpHeader
= NULL
;
1285 connection
->httpPostFirst
= NULL
;
1286 connection
->httpPostLast
= NULL
;
1287 connection
->httpPostStrings
= NULL
;
1288 connection
->sslCert
= NULL
;
1289 connection
->sslCertType
= NULL
;
1290 connection
->sslCertPasswd
= NULL
;
1291 connection
->sslKey
= NULL
;
1292 connection
->sslKeyType
= NULL
;
1293 connection
->sslKeyPasswd
= NULL
;
1294 connection
->sslEngine
= NULL
;
1295 connection
->quote
= NULL
;
1296 connection
->postQuote
= NULL
;
1297 connection
->cookieFile
= NULL
;
1298 connection
->customRequest
= NULL
;
1299 connection
->interface
= NULL
;
1300 connection
->caInfo
= NULL
;
1301 connection
->caPath
= NULL
;
1302 connection
->randomFile
= NULL
;
1303 connection
->egdSocket
= NULL
;
1304 connection
->cookieJar
= NULL
;
1305 connection
->sslCipherList
= NULL
;
1306 connection
->private = NULL
;
1307 connection
->http200Aliases
= NULL
;
1308 connection
->netrcFile
= NULL
;
1309 connection
->ftpaccount
= NULL
;
1310 connection
->cookielist
= NULL
;
1311 connection
->sshPublicKeyFile
= NULL
;
1312 connection
->sshPrivateKeyFile
= NULL
;
1313 connection
->copyPostFields
= NULL
;
1315 if (Field(original
->ocamlValues
, OcamlURL
) != Val_unit
)
1316 handleURL(connection
, Field(original
->ocamlValues
,
1318 if (Field(original
->ocamlValues
, OcamlProxy
) != Val_unit
)
1319 handleProxy(connection
, Field(original
->ocamlValues
,
1321 if (Field(original
->ocamlValues
, OcamlUserPWD
) != Val_unit
)
1322 handleUserPwd(connection
, Field(original
->ocamlValues
,
1324 if (Field(original
->ocamlValues
, OcamlProxyUserPWD
) != Val_unit
)
1325 handleProxyUserPwd(connection
, Field(original
->ocamlValues
,
1326 OcamlProxyUserPWD
));
1327 if (Field(original
->ocamlValues
, OcamlRange
) != Val_unit
)
1328 handleRange(connection
, Field(original
->ocamlValues
,
1330 if (Field(original
->ocamlValues
, OcamlErrorBuffer
) != Val_unit
)
1331 handleErrorBuffer(connection
, Field(original
->ocamlValues
,
1333 if (Field(original
->ocamlValues
, OcamlPostFields
) != Val_unit
)
1334 handlePostFields(connection
, Field(original
->ocamlValues
,
1336 if (Field(original
->ocamlValues
, OcamlReferer
) != Val_unit
)
1337 handleReferer(connection
, Field(original
->ocamlValues
,
1339 if (Field(original
->ocamlValues
, OcamlUserAgent
) != Val_unit
)
1340 handleUserAgent(connection
, Field(original
->ocamlValues
,
1342 if (Field(original
->ocamlValues
, OcamlFTPPort
) != Val_unit
)
1343 handleFTPPort(connection
, Field(original
->ocamlValues
,
1345 if (Field(original
->ocamlValues
, OcamlCookie
) != Val_unit
)
1346 handleCookie(connection
, Field(original
->ocamlValues
,
1348 if (Field(original
->ocamlValues
, OcamlHTTPHeader
) != Val_unit
)
1349 handleHTTPHeader(connection
, Field(original
->ocamlValues
,
1351 if (Field(original
->ocamlValues
, OcamlHTTPPost
) != Val_unit
)
1352 handleHTTPPost(connection
, Field(original
->ocamlValues
,
1354 if (Field(original
->ocamlValues
, OcamlSSLCert
) != Val_unit
)
1355 handleSSLCert(connection
, Field(original
->ocamlValues
,
1357 if (Field(original
->ocamlValues
, OcamlSSLCertType
) != Val_unit
)
1358 handleSSLCertType(connection
, Field(original
->ocamlValues
,
1360 if (Field(original
->ocamlValues
, OcamlSSLCertPasswd
) != Val_unit
)
1361 handleSSLCertPasswd(connection
, Field(original
->ocamlValues
,
1362 OcamlSSLCertPasswd
));
1363 if (Field(original
->ocamlValues
, OcamlSSLKey
) != Val_unit
)
1364 handleSSLKey(connection
, Field(original
->ocamlValues
,
1366 if (Field(original
->ocamlValues
, OcamlSSLKeyType
) != Val_unit
)
1367 handleSSLKeyType(connection
, Field(original
->ocamlValues
,
1369 if (Field(original
->ocamlValues
, OcamlSSLKeyPasswd
) != Val_unit
)
1370 handleSSLKeyPasswd(connection
, Field(original
->ocamlValues
,
1371 OcamlSSLKeyPasswd
));
1372 if (Field(original
->ocamlValues
, OcamlSSLEngine
) != Val_unit
)
1373 handleSSLEngine(connection
, Field(original
->ocamlValues
,
1375 if (Field(original
->ocamlValues
, OcamlQuote
) != Val_unit
)
1376 handleQuote(connection
, Field(original
->ocamlValues
,
1378 if (Field(original
->ocamlValues
, OcamlPostQuote
) != Val_unit
)
1379 handlePostQuote(connection
, Field(original
->ocamlValues
,
1381 if (Field(original
->ocamlValues
, OcamlCookieFile
) != Val_unit
)
1382 handleCookieFile(connection
, Field(original
->ocamlValues
,
1384 if (Field(original
->ocamlValues
, OcamlCustomRequest
) != Val_unit
)
1385 handleCustomRequest(connection
, Field(original
->ocamlValues
,
1386 OcamlCustomRequest
));
1387 if (Field(original
->ocamlValues
, OcamlInterface
) != Val_unit
)
1388 handleInterface(connection
, Field(original
->ocamlValues
,
1390 if (Field(original
->ocamlValues
, OcamlCAInfo
) != Val_unit
)
1391 handleCAInfo(connection
, Field(original
->ocamlValues
,
1393 if (Field(original
->ocamlValues
, OcamlCAPath
) != Val_unit
)
1394 handleCAPath(connection
, Field(original
->ocamlValues
,
1396 if (Field(original
->ocamlValues
, OcamlRandomFile
) != Val_unit
)
1397 handleRandomFile(connection
, Field(original
->ocamlValues
,
1399 if (Field(original
->ocamlValues
, OcamlEGDSocket
) != Val_unit
)
1400 handleEGDSocket(connection
, Field(original
->ocamlValues
,
1402 if (Field(original
->ocamlValues
, OcamlCookieJar
) != Val_unit
)
1403 handleCookieJar(connection
, Field(original
->ocamlValues
,
1405 if (Field(original
->ocamlValues
, OcamlSSLCipherList
) != Val_unit
)
1406 handleSSLCipherList(connection
, Field(original
->ocamlValues
,
1407 OcamlSSLCipherList
));
1408 if (Field(original
->ocamlValues
, OcamlPrivate
) != Val_unit
)
1409 handlePrivate(connection
, Field(original
->ocamlValues
,
1411 if (Field(original
->ocamlValues
, OcamlHTTP200Aliases
) != Val_unit
)
1412 handleHTTP200Aliases(connection
, Field(original
->ocamlValues
,
1413 OcamlHTTP200Aliases
));
1414 if (Field(original
->ocamlValues
, OcamlNETRCFile
) != Val_unit
)
1415 handleNETRCFile(connection
, Field(original
->ocamlValues
,
1417 if (Field(original
->ocamlValues
, OcamlFTPAccount
) != Val_unit
)
1418 handleFTPAccount(connection
, Field(original
->ocamlValues
,
1420 if (Field(original
->ocamlValues
, OcamlCookieList
) != Val_unit
)
1421 handleCookieList(connection
, Field(original
->ocamlValues
,
1423 if (Field(original
->ocamlValues
, OcamlFTPAlternativeToUser
) != Val_unit
)
1424 handleFTPAlternativeToUser(connection
,
1425 Field(original
->ocamlValues
,
1426 OcamlFTPAlternativeToUser
));
1427 if (Field(original
->ocamlValues
, OcamlSSHPublicKeyFile
) != Val_unit
)
1428 handleSSHPublicKeyFile(connection
,
1429 Field(original
->ocamlValues
,
1430 OcamlSSHPublicKeyFile
));
1431 if (Field(original
->ocamlValues
, OcamlSSHPrivateKeyFile
) != Val_unit
)
1432 handleSSHPrivateKeyFile(connection
,
1433 Field(original
->ocamlValues
,
1434 OcamlSSHPrivateKeyFile
));
1435 if (Field(original
->ocamlValues
, OcamlCopyPostFields
) != Val_unit
)
1436 handleCopyPostFields(connection
,
1437 Field(original
->ocamlValues
,
1438 OcamlCopyPostFields
));
1443 static void free_if(void* p
) { if (NULL
!= p
) free(p
); }
1445 static void removeConnection(Connection
*connection
)
1447 enter_blocking_section();
1448 curl_easy_cleanup(connection
->connection
);
1449 leave_blocking_section();
1451 if (connectionList
.tail
== connection
)
1452 connectionList
.tail
= connectionList
.tail
->next
;
1453 if (connectionList
.head
== connection
)
1454 connectionList
.head
= connectionList
.head
->prev
;
1456 if (connection
->next
!= NULL
)
1457 connection
->next
->prev
= connection
->prev
;
1458 if (connection
->prev
!= NULL
)
1459 connection
->prev
->next
= connection
->next
;
1461 remove_global_root(&connection
->ocamlValues
);
1463 free_if(connection
->url
);
1464 free_if(connection
->proxy
);
1465 free_if(connection
->userPwd
);
1466 free_if(connection
->proxyUserPwd
);
1467 free_if(connection
->range
);
1468 free_if(connection
->errorBuffer
);
1469 free_if(connection
->postFields
);
1470 free_if(connection
->referer
);
1471 free_if(connection
->userAgent
);
1472 free_if(connection
->ftpPort
);
1473 free_if(connection
->cookie
);
1474 free_curl_slist(connection
->httpHeader
);
1475 if (connection
->httpPostFirst
!= NULL
)
1476 curl_formfree(connection
->httpPostFirst
);
1477 free_curl_slist(connection
->httpPostStrings
);
1478 free_if(connection
->sslCert
);
1479 free_if(connection
->sslCertType
);
1480 free_if(connection
->sslCertPasswd
);
1481 free_if(connection
->sslKey
);
1482 free_if(connection
->sslKeyType
);
1483 free_if(connection
->sslKeyPasswd
);
1484 free_if(connection
->sslEngine
);
1485 free_curl_slist(connection
->quote
);
1486 free_curl_slist(connection
->postQuote
);
1487 free_if(connection
->cookieFile
);
1488 free_if(connection
->customRequest
);
1489 free_if(connection
->interface
);
1490 free_if(connection
->caInfo
);
1491 free_if(connection
->caPath
);
1492 free_if(connection
->randomFile
);
1493 free_if(connection
->egdSocket
);
1494 free_if(connection
->cookieJar
);
1495 free_if(connection
->sslCipherList
);
1496 free_if(connection
->private);
1497 free_curl_slist(connection
->http200Aliases
);
1498 free_if(connection
->netrcFile
);
1499 free_if(connection
->ftpaccount
);
1500 free_if(connection
->cookielist
);
1501 free_if(connection
->ftpAlternativeToUser
);
1502 free_if(connection
->sshPublicKeyFile
);
1503 free_if(connection
->sshPrivateKeyFile
);
1504 free_if(connection
->copyPostFields
);
1509 static void checkConnection(Connection
*connection
)
1513 Connection
*listIter
;
1515 listIter
= connectionList
.tail
;
1517 while (listIter
!= NULL
)
1519 if (listIter
== connection
)
1522 listIter
= listIter
->next
;
1525 failwith("Invalid Connection");
1528 static Connection
* findConnection(CURL
* h
)
1530 Connection
*listIter
;
1532 listIter
= connectionList
.tail
;
1534 while (listIter
!= NULL
)
1536 if (listIter
->connection
== h
)
1539 listIter
= listIter
->next
;
1542 failwith("Unknown handle");
1545 #define WRAP_DATA_CALLBACK(f) \
1546 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1549 leave_blocking_section();\
1550 result = f##_nolock(ptr,size,nmemb,data);\
1551 enter_blocking_section();\
1555 static size_t writeFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1558 CAMLlocal2(result
, str
);
1559 Connection
*conn
= (Connection
*)data
;
1562 checkConnection(conn
);
1564 str
= alloc_string(size
*nmemb
);
1566 for (i
= 0; i
< size
*nmemb
; i
++)
1567 Byte(str
, i
) = ptr
[i
];
1569 result
= callback(Field(conn
->ocamlValues
, OcamlWriteCallback
), str
);
1571 CAMLreturnT(size_t, Int_val(result
));
1574 WRAP_DATA_CALLBACK(writeFunction
)
1576 static size_t readFunction_nolock(void *ptr
, size_t size
, size_t nmemb
, void *data
)
1580 Connection
*conn
= (Connection
*)data
;
1583 checkConnection(conn
);
1585 result
= callback(Field(conn
->ocamlValues
, OcamlReadCallback
),
1586 Val_int(size
*nmemb
));
1588 length
= string_length(result
);
1590 if (length
>= size
*nmemb
)
1591 length
= size
*nmemb
;
1593 memcpy(ptr
, String_val(result
), length
);
1595 CAMLreturnT(size_t,length
);
1598 WRAP_DATA_CALLBACK(readFunction
)
1600 static size_t headerFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1603 CAMLlocal2(result
,str
);
1604 Connection
*conn
= (Connection
*)data
;
1607 checkConnection(conn
);
1609 str
= alloc_string(size
*nmemb
);
1611 for (i
= 0; i
< size
*nmemb
; i
++)
1612 Byte(str
, i
) = ptr
[i
];
1614 result
= callback(Field(conn
->ocamlValues
, OcamlHeaderCallback
), str
);
1616 CAMLreturnT(size_t, Int_val(result
));
1619 WRAP_DATA_CALLBACK(headerFunction
)
1621 static int progressFunction_nolock(void *data
,
1629 CAMLlocalN(callbackData
, 4);
1630 Connection
*conn
= (Connection
*)data
;
1632 checkConnection(conn
);
1634 callbackData
[0] = copy_double(dlTotal
);
1635 callbackData
[1] = copy_double(dlNow
);
1636 callbackData
[2] = copy_double(ulTotal
);
1637 callbackData
[3] = copy_double(ulNow
);
1639 result
= callbackN(Field(conn
->ocamlValues
, OcamlProgressCallback
),
1642 CAMLreturnT(int, Bool_val(result
));
1645 static int progressFunction(void *data
,
1652 leave_blocking_section();
1653 r
= progressFunction_nolock(data
,dlTotal
,dlNow
,ulTotal
,ulNow
);
1654 enter_blocking_section();
1658 static int debugFunction_nolock(CURL
*debugConnection
,
1659 curl_infotype infoType
,
1661 size_t bufferLength
,
1665 CAMLlocal3(camlDebugConnection
, camlInfoType
, camlMessage
);
1667 Connection
*conn
= (Connection
*)data
;
1669 checkConnection(conn
);
1671 camlDebugConnection
= (value
)conn
;
1672 camlInfoType
= Val_long(infoType
);
1673 camlMessage
= alloc_string(bufferLength
);
1675 for (i
= 0; i
< bufferLength
; i
++)
1676 Byte(camlMessage
, i
) = buffer
[i
];
1678 callback3(Field(conn
->ocamlValues
, OcamlDebugCallback
),
1679 camlDebugConnection
,
1683 CAMLreturnT(int, 0);
1686 static int debugFunction(CURL
*debugConnection
,
1687 curl_infotype infoType
,
1689 size_t bufferLength
,
1693 leave_blocking_section();
1694 r
= debugFunction_nolock(debugConnection
, infoType
, buffer
, bufferLength
, data
);
1695 enter_blocking_section();
1699 static curlioerr
ioctlFunction_nolock(CURL
*ioctl
,
1704 CAMLlocal3(camlResult
, camlConnection
, camlCmd
);
1705 Connection
*conn
= (Connection
*)data
;
1706 curlioerr result
= CURLIOE_OK
;
1708 checkConnection(conn
);
1710 if (cmd
== CURLIOCMD_NOP
)
1711 camlCmd
= Val_long(0);
1712 else if (cmd
== CURLIOCMD_RESTARTREAD
)
1713 camlCmd
= Val_long(1);
1715 failwith("Invalid IOCTL Cmd!");
1717 camlConnection
= caml_alloc(1, Abstract_tag
);
1718 Field(camlConnection
, 0) = (value
)conn
;
1720 camlResult
= callback2(Field(conn
->ocamlValues
, OcamlIOCTLCallback
),
1724 switch (Long_val(camlResult
))
1726 case 0: /* CURLIOE_OK */
1727 result
= CURLIOE_OK
;
1730 case 1: /* CURLIOE_UNKNOWNCMD */
1731 result
= CURLIOE_UNKNOWNCMD
;
1734 case 2: /* CURLIOE_FAILRESTART */
1735 result
= CURLIOE_FAILRESTART
;
1738 default: /* Incorrect return value, but let's handle it */
1739 result
= CURLIOE_FAILRESTART
;
1743 CAMLreturnT(curlioerr
, result
);
1746 static curlioerr
ioctlFunction(CURL
*ioctl
,
1751 leave_blocking_section();
1752 r
= ioctlFunction_nolock(ioctl
, cmd
, data
);
1753 enter_blocking_section();
1757 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1758 static int seekFunction_nolock(void *data
,
1763 CAMLlocal3(camlResult
, camlOffset
, camlOrigin
);
1764 Connection
*conn
= (Connection
*)data
;
1767 camlOffset
= copy_int64(offset
);
1769 if (origin
== SEEK_SET
)
1770 camlOrigin
= Val_long(0);
1771 else if (origin
== SEEK_CUR
)
1772 camlOrigin
= Val_long(1);
1773 else if (origin
== SEEK_END
)
1774 camlOrigin
= Val_long(2);
1776 camlOrigin
= Val_long(0);
1778 camlResult
= callback2(Field(conn
->ocamlValues
,
1779 OcamlSeekFunctionCallback
),
1783 result
= Int_val(camlResult
);
1785 CAMLreturnT(int, result
);
1788 static int seekFunction(void *data
,
1793 leave_blocking_section();
1794 r
= seekFunction_nolock(data
,offset
,origin
);
1795 enter_blocking_section();
1801 #ifdef HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
1802 static int openSocketFunction_nolock(void *data
,
1803 curlsocktype purpose
,
1804 struct curl_sockaddr
*addr
)
1807 Connection
*conn
= (Connection
*)data
;
1810 sock
= socket(addr
->family
, addr
->socktype
, addr
->protocol
);
1815 callback(Field(conn
->ocamlValues
, OcamlOpenSocketFunctionCallback
), Val_int(sock
));
1818 CAMLreturnT(int, sock
);
1821 static int openSocketFunction(void *data
,
1822 curlsocktype purpose
,
1823 struct curl_sockaddr
*address
)
1826 leave_blocking_section();
1827 r
= openSocketFunction_nolock(data
,purpose
,address
);
1828 enter_blocking_section();
1835 ** curl_global_init helper function
1838 CAMLprim value
helper_curl_global_init(value initOption
)
1840 CAMLparam1(initOption
);
1842 switch (Long_val(initOption
))
1844 case 0: /* CURLINIT_GLOBALALL */
1845 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL
)));
1848 case 1: /* CURLINIT_GLOBALSSL */
1849 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL
)));
1852 case 2: /* CURLINIT_GLOBALWIN32 */
1853 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32
)));
1856 case 3: /* CURLINIT_GLOBALNOTHING */
1857 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING
)));
1861 failwith("Invalid Initialization Option");
1865 /* Keep compiler happy, we should never get here due to failwith() */
1866 CAMLreturn(Val_unit
);
1870 ** curl_global_cleanup helper function
1873 CAMLprim value
helper_curl_global_cleanup(void)
1877 curl_global_cleanup();
1879 CAMLreturn(Val_unit
);
1883 ** curl_easy_init helper function
1886 CAMLprim value
helper_curl_easy_init(void)
1891 Connection
*conn
= newConnection();
1893 result
= caml_alloc(1, Abstract_tag
);
1894 Field(result
, 0) = (value
)conn
;
1899 CAMLprim value
helper_curl_easy_reset(value conn
)
1902 Connection
*connection
= Connection_val(conn
);
1904 checkConnection(connection
);
1905 curl_easy_reset(connection
->connection
);
1906 resetOcamlValues(connection
);
1908 CAMLreturn(Val_unit
);
1912 ** curl_easy_setopt helper utility functions
1915 static void handleWriteFunction(Connection
*conn
, value option
)
1918 CURLcode result
= CURLE_OK
;
1920 if (Tag_val(option
) == Closure_tag
)
1921 Store_field(conn
->ocamlValues
, OcamlWriteCallback
, option
);
1923 failwith("Not a proper closure");
1925 result
= curl_easy_setopt(conn
->connection
,
1926 CURLOPT_WRITEFUNCTION
,
1929 if (result
!= CURLE_OK
)
1930 raiseError(conn
, result
);
1932 result
= curl_easy_setopt(conn
->connection
,
1936 if (result
!= CURLE_OK
)
1937 raiseError(conn
, result
);
1942 static void handleReadFunction(Connection
*conn
, value option
)
1945 CURLcode result
= CURLE_OK
;
1947 if (Tag_val(option
) == Closure_tag
)
1948 Store_field(conn
->ocamlValues
, OcamlReadCallback
, option
);
1950 failwith("Not a proper closure");
1952 result
= curl_easy_setopt(conn
->connection
,
1953 CURLOPT_READFUNCTION
,
1956 if (result
!= CURLE_OK
)
1957 raiseError(conn
, result
);
1959 result
= curl_easy_setopt(conn
->connection
,
1963 if (result
!= CURLE_OK
)
1964 raiseError(conn
, result
);
1969 static void handleURL(Connection
*conn
, value option
)
1972 CURLcode result
= CURLE_OK
;
1974 Store_field(conn
->ocamlValues
, OcamlURL
, option
);
1976 if (conn
->url
!= NULL
)
1979 conn
->url
= strdup(String_val(option
));
1981 result
= curl_easy_setopt(conn
->connection
,
1985 if (result
!= CURLE_OK
)
1986 raiseError(conn
, result
);
1991 static void handleInFileSize(Connection
*conn
, value option
)
1994 CURLcode result
= CURLE_OK
;
1996 result
= curl_easy_setopt(conn
->connection
,
2000 if (result
!= CURLE_OK
)
2001 raiseError(conn
, result
);
2006 static void handleProxy(Connection
*conn
, value option
)
2009 CURLcode result
= CURLE_OK
;
2011 Store_field(conn
->ocamlValues
, OcamlProxy
, option
);
2013 if (conn
->proxy
!= NULL
)
2016 conn
->proxy
= strdup(String_val(option
));
2018 result
= curl_easy_setopt(conn
->connection
,
2022 if (result
!= CURLE_OK
)
2023 raiseError(conn
, result
);
2028 static void handleProxyPort(Connection
*conn
, value option
)
2031 CURLcode result
= CURLE_OK
;
2033 result
= curl_easy_setopt(conn
->connection
,
2037 if (result
!= CURLE_OK
)
2038 raiseError(conn
, result
);
2043 static void handleHTTPProxyTunnel(Connection
*conn
, value option
)
2046 CURLcode result
= CURLE_OK
;
2048 result
= curl_easy_setopt(conn
->connection
,
2049 CURLOPT_HTTPPROXYTUNNEL
,
2052 if (result
!= CURLE_OK
)
2053 raiseError(conn
, result
);
2058 static void handleVerbose(Connection
*conn
, value option
)
2061 CURLcode result
= CURLE_OK
;
2063 result
= curl_easy_setopt(conn
->connection
,
2067 if (result
!= CURLE_OK
)
2068 raiseError(conn
, result
);
2073 static void handleHeader(Connection
*conn
, value option
)
2076 CURLcode result
= CURLE_OK
;
2078 result
= curl_easy_setopt(conn
->connection
,
2082 if (result
!= CURLE_OK
)
2083 raiseError(conn
, result
);
2088 static void handleNoProgress(Connection
*conn
, value option
)
2091 CURLcode result
= CURLE_OK
;
2093 result
= curl_easy_setopt(conn
->connection
,
2097 if (result
!= CURLE_OK
)
2098 raiseError(conn
, result
);
2103 static void handleNoSignal(Connection
*conn
, value option
)
2105 #if HAVE_DECL_CURLOPT_NOSIGNAL
2107 CURLcode result
= CURLE_OK
;
2109 result
= curl_easy_setopt(conn
->connection
,
2113 if (result
!= CURLE_OK
)
2114 raiseError(conn
, result
);
2118 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2119 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2123 static void handleNoBody(Connection
*conn
, value option
)
2126 CURLcode result
= CURLE_OK
;
2128 result
= curl_easy_setopt(conn
->connection
,
2132 if (result
!= CURLE_OK
)
2133 raiseError(conn
, result
);
2138 static void handleFailOnError(Connection
*conn
, value option
)
2141 CURLcode result
= CURLE_OK
;
2143 result
= curl_easy_setopt(conn
->connection
,
2144 CURLOPT_FAILONERROR
,
2147 if (result
!= CURLE_OK
)
2148 raiseError(conn
, result
);
2153 static void handleUpload(Connection
*conn
, value option
)
2156 CURLcode result
= CURLE_OK
;
2158 result
= curl_easy_setopt(conn
->connection
,
2162 if (result
!= CURLE_OK
)
2163 raiseError(conn
, result
);
2168 static void handlePost(Connection
*conn
, value option
)
2171 CURLcode result
= CURLE_OK
;
2173 result
= curl_easy_setopt(conn
->connection
,
2177 if (result
!= CURLE_OK
)
2178 raiseError(conn
, result
);
2183 static void handleFTPListOnly(Connection
*conn
, value option
)
2186 CURLcode result
= CURLE_OK
;
2188 result
= curl_easy_setopt(conn
->connection
,
2189 CURLOPT_FTPLISTONLY
,
2192 if (result
!= CURLE_OK
)
2193 raiseError(conn
, result
);
2198 static void handleFTPAppend(Connection
*conn
, value option
)
2201 CURLcode result
= CURLE_OK
;
2203 result
= curl_easy_setopt(conn
->connection
,
2207 if (result
!= CURLE_OK
)
2208 raiseError(conn
, result
);
2213 static void handleNETRC(Connection
*conn
, value option
)
2216 CURLcode result
= CURLE_OK
;
2219 switch (Long_val(option
))
2221 case 0: /* CURL_NETRC_OPTIONAL */
2222 netrc
= CURL_NETRC_OPTIONAL
;
2225 case 1:/* CURL_NETRC_IGNORED */
2226 netrc
= CURL_NETRC_IGNORED
;
2229 case 2: /* CURL_NETRC_REQUIRED */
2230 netrc
= CURL_NETRC_REQUIRED
;
2234 failwith("Invalid NETRC Option");
2238 result
= curl_easy_setopt(conn
->connection
,
2242 if (result
!= CURLE_OK
)
2243 raiseError(conn
, result
);
2248 static void handleEncoding(Connection
*conn
, value option
)
2250 #if HAVE_DECL_CURLOPT_ENCODING
2252 CURLcode result
= CURLE_OK
;
2254 switch (Long_val(option
))
2256 case 0: /* CURL_ENCODING_NONE */
2257 result
= curl_easy_setopt(conn
->connection
,
2262 case 1: /* CURL_ENCODING_DEFLATE */
2263 result
= curl_easy_setopt(conn
->connection
,
2268 case 2: /* CURL_ENCODING_GZIP */
2269 result
= curl_easy_setopt(conn
->connection
,
2274 case 3: /* CURL_ENCODING_ANY */
2275 result
= curl_easy_setopt(conn
->connection
,
2281 failwith("Invalid Encoding Option");
2285 if (result
!= CURLE_OK
)
2286 raiseError(conn
, result
);
2290 #warning "libcurl does not implement CURLOPT_ENCODING"
2291 failwith("libcurl does not implement CURLOPT_ENCODING");
2295 static void handleFollowLocation(Connection
*conn
, value option
)
2298 CURLcode result
= CURLE_OK
;
2300 result
= curl_easy_setopt(conn
->connection
,
2301 CURLOPT_FOLLOWLOCATION
,
2304 if (result
!= CURLE_OK
)
2305 raiseError(conn
, result
);
2310 static void handleTransferText(Connection
*conn
, value option
)
2313 CURLcode result
= CURLE_OK
;
2315 result
= curl_easy_setopt(conn
->connection
,
2316 CURLOPT_TRANSFERTEXT
,
2319 if (result
!= CURLE_OK
)
2320 raiseError(conn
, result
);
2325 static void handlePut(Connection
*conn
, value option
)
2328 CURLcode result
= CURLE_OK
;
2330 result
= curl_easy_setopt(conn
->connection
,
2334 if (result
!= CURLE_OK
)
2335 raiseError(conn
, result
);
2340 static void handleUserPwd(Connection
*conn
, value option
)
2343 CURLcode result
= CURLE_OK
;
2345 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2347 if (conn
->userPwd
!= NULL
)
2348 free(conn
->userPwd
);
2350 conn
->userPwd
= strdup(String_val(option
));
2352 result
= curl_easy_setopt(conn
->connection
,
2356 if (result
!= CURLE_OK
)
2357 raiseError(conn
, result
);
2362 static void handleProxyUserPwd(Connection
*conn
, value option
)
2365 CURLcode result
= CURLE_OK
;
2367 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2369 if (conn
->proxyUserPwd
!= NULL
)
2370 free(conn
->proxyUserPwd
);
2372 conn
->proxyUserPwd
= strdup(String_val(option
));
2374 result
= curl_easy_setopt(conn
->connection
,
2375 CURLOPT_PROXYUSERPWD
,
2376 conn
->proxyUserPwd
);
2378 if (result
!= CURLE_OK
)
2379 raiseError(conn
, result
);
2384 static void handleRange(Connection
*conn
, value option
)
2387 CURLcode result
= CURLE_OK
;
2389 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2391 if (conn
->range
!= NULL
)
2394 conn
->range
= strdup(String_val(option
));
2396 result
= curl_easy_setopt(conn
->connection
,
2400 if (result
!= CURLE_OK
)
2401 raiseError(conn
, result
);
2406 static void handleErrorBuffer(Connection
*conn
, value option
)
2409 CURLcode result
= CURLE_OK
;
2411 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2413 if (conn
->errorBuffer
!= NULL
)
2414 free(conn
->errorBuffer
);
2416 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2418 result
= curl_easy_setopt(conn
->connection
,
2419 CURLOPT_ERRORBUFFER
,
2422 if (result
!= CURLE_OK
)
2423 raiseError(conn
, result
);
2428 static void handleTimeout(Connection
*conn
, value option
)
2431 CURLcode result
= CURLE_OK
;
2433 result
= curl_easy_setopt(conn
->connection
,
2437 if (result
!= CURLE_OK
)
2438 raiseError(conn
, result
);
2443 static void handlePostFields(Connection
*conn
, value option
)
2446 CURLcode result
= CURLE_OK
;
2448 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2450 if (conn
->postFields
!= NULL
)
2451 free(conn
->postFields
);
2453 conn
->postFields
= malloc(string_length(option
)+1);
2454 memcpy(conn
->postFields
, String_val(option
), string_length(option
)+1);
2456 result
= curl_easy_setopt(conn
->connection
,
2460 if (result
!= CURLE_OK
)
2461 raiseError(conn
, result
);
2466 static void handlePostFieldSize(Connection
*conn
, value option
)
2469 CURLcode result
= CURLE_OK
;
2471 result
= curl_easy_setopt(conn
->connection
,
2472 CURLOPT_POSTFIELDSIZE
,
2475 if (result
!= CURLE_OK
)
2476 raiseError(conn
, result
);
2481 static void handleReferer(Connection
*conn
, value option
)
2484 CURLcode result
= CURLE_OK
;
2486 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2488 if (conn
->referer
!= NULL
)
2489 free(conn
->referer
);
2491 conn
->referer
= strdup(String_val(option
));
2493 result
= curl_easy_setopt(conn
->connection
,
2497 if (result
!= CURLE_OK
)
2498 raiseError(conn
, result
);
2503 static void handleUserAgent(Connection
*conn
, value option
)
2506 CURLcode result
= CURLE_OK
;
2508 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2510 if (conn
->userAgent
!= NULL
)
2511 free(conn
->userAgent
);
2513 conn
->userAgent
= strdup(String_val(option
));
2515 result
= curl_easy_setopt(conn
->connection
,
2519 if (result
!= CURLE_OK
)
2520 raiseError(conn
, result
);
2525 static void handleFTPPort(Connection
*conn
, value option
)
2528 CURLcode result
= CURLE_OK
;
2530 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2532 if (conn
->ftpPort
!= NULL
)
2533 free(conn
->ftpPort
);
2535 conn
->ftpPort
= strdup(String_val(option
));
2537 result
= curl_easy_setopt(conn
->connection
,
2541 if (result
!= CURLE_OK
)
2542 raiseError(conn
, result
);
2547 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2550 CURLcode result
= CURLE_OK
;
2552 result
= curl_easy_setopt(conn
->connection
,
2553 CURLOPT_LOW_SPEED_LIMIT
,
2556 if (result
!= CURLE_OK
)
2557 raiseError(conn
, result
);
2562 static void handleLowSpeedTime(Connection
*conn
, value option
)
2565 CURLcode result
= CURLE_OK
;
2567 result
= curl_easy_setopt(conn
->connection
,
2568 CURLOPT_LOW_SPEED_TIME
,
2571 if (result
!= CURLE_OK
)
2572 raiseError(conn
, result
);
2577 static void handleResumeFrom(Connection
*conn
, value option
)
2580 CURLcode result
= CURLE_OK
;
2582 result
= curl_easy_setopt(conn
->connection
,
2583 CURLOPT_RESUME_FROM
,
2586 if (result
!= CURLE_OK
)
2587 raiseError(conn
, result
);
2592 static void handleCookie(Connection
*conn
, value option
)
2595 CURLcode result
= CURLE_OK
;
2597 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2599 if (conn
->cookie
!= NULL
)
2602 conn
->cookie
= strdup(String_val(option
));
2604 result
= curl_easy_setopt(conn
->connection
,
2608 if (result
!= CURLE_OK
)
2609 raiseError(conn
, result
);
2614 static void handleHTTPHeader(Connection
*conn
, value option
)
2617 CAMLlocal1(listIter
);
2618 CURLcode result
= CURLE_OK
;
2620 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2622 free_curl_slist(conn
->httpHeader
);
2623 conn
->httpHeader
= NULL
;
2627 while (!Is_long(listIter
))
2629 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, String_val(Field(listIter
, 0)));
2631 listIter
= Field(listIter
, 1);
2634 result
= curl_easy_setopt(conn
->connection
,
2638 if (result
!= CURLE_OK
)
2639 raiseError(conn
, result
);
2644 static void handleHTTPPost(Connection
*conn
, value option
)
2647 CAMLlocal3(listIter
, formItem
, contentType
);
2648 CURLcode result
= CURLE_OK
;
2649 char *str1
, *str2
, *str3
, *str4
;
2653 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2655 if (conn
->httpPostFirst
!= NULL
)
2656 curl_formfree(conn
->httpPostFirst
);
2658 conn
->httpPostFirst
= NULL
;
2659 conn
->httpPostLast
= NULL
;
2661 free_curl_slist(conn
->httpPostStrings
);
2662 conn
->httpPostStrings
= NULL
;
2664 while (!Is_long(listIter
))
2666 formItem
= Field(listIter
, 0);
2668 switch (Tag_val(formItem
))
2670 case 0: /* CURLFORM_CONTENT */
2671 if (Wosize_val(formItem
) < 3)
2673 failwith("Incorrect CURLFORM_CONTENT parameters");
2676 if (Is_long(Field(formItem
, 2)) &&
2677 Long_val(Field(formItem
, 2)) == 0)
2679 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2681 String_val(Field(formItem
, 0)),
2682 string_length(Field(formItem
, 0)));
2683 str1
[string_length(Field(formItem
, 0))] = 0;
2684 conn
->httpPostStrings
=
2685 curl_slist_append(conn
->httpPostStrings
, str1
);
2687 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2689 String_val(Field(formItem
, 1)),
2690 string_length(Field(formItem
, 1)));
2691 str2
[string_length(Field(formItem
, 1))] = 0;
2692 conn
->httpPostStrings
=
2693 curl_slist_append(conn
->httpPostStrings
, str2
);
2695 curl_formadd(&conn
->httpPostFirst
,
2696 &conn
->httpPostLast
,
2699 CURLFORM_NAMELENGTH
,
2700 string_length(Field(formItem
, 0)),
2701 CURLFORM_PTRCONTENTS
,
2703 CURLFORM_CONTENTSLENGTH
,
2704 string_length(Field(formItem
, 1)),
2707 else if (Is_block(Field(formItem
, 2)))
2709 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2711 String_val(Field(formItem
, 0)),
2712 string_length(Field(formItem
, 0)));
2713 str1
[string_length(Field(formItem
, 0))] = 0;
2714 conn
->httpPostStrings
=
2715 curl_slist_append(conn
->httpPostStrings
, str1
);
2717 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2719 String_val(Field(formItem
, 1)),
2720 string_length(Field(formItem
, 1)));
2721 str2
[string_length(Field(formItem
, 1))] = 0;
2722 conn
->httpPostStrings
=
2723 curl_slist_append(conn
->httpPostStrings
, str2
);
2725 contentType
= Field(formItem
, 2);
2727 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2729 String_val(Field(contentType
, 0)),
2730 string_length(Field(contentType
, 0)));
2731 str3
[string_length(Field(contentType
, 0))] = 0;
2732 conn
->httpPostStrings
=
2733 curl_slist_append(conn
->httpPostStrings
, str3
);
2735 curl_formadd(&conn
->httpPostFirst
,
2736 &conn
->httpPostLast
,
2739 CURLFORM_NAMELENGTH
,
2740 string_length(Field(formItem
, 0)),
2741 CURLFORM_PTRCONTENTS
,
2743 CURLFORM_CONTENTSLENGTH
,
2744 string_length(Field(formItem
, 1)),
2745 CURLFORM_CONTENTTYPE
,
2751 failwith("Incorrect CURLFORM_CONTENT parameters");
2755 case 1: /* CURLFORM_FILECONTENT */
2756 if (Wosize_val(formItem
) < 3)
2758 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2761 if (Is_long(Field(formItem
, 2)) &&
2762 Long_val(Field(formItem
, 2)) == 0)
2764 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2766 String_val(Field(formItem
, 0)),
2767 string_length(Field(formItem
, 0)));
2768 str1
[string_length(Field(formItem
, 0))] = 0;
2769 conn
->httpPostStrings
=
2770 curl_slist_append(conn
->httpPostStrings
, str1
);
2772 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2774 String_val(Field(formItem
, 1)),
2775 string_length(Field(formItem
, 1)));
2776 str2
[string_length(Field(formItem
, 1))] = 0;
2777 conn
->httpPostStrings
=
2778 curl_slist_append(conn
->httpPostStrings
, str2
);
2780 curl_formadd(&conn
->httpPostFirst
,
2781 &conn
->httpPostLast
,
2784 CURLFORM_NAMELENGTH
,
2785 string_length(Field(formItem
, 0)),
2786 CURLFORM_FILECONTENT
,
2790 else if (Is_block(Field(formItem
, 2)))
2792 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2794 String_val(Field(formItem
, 0)),
2795 string_length(Field(formItem
, 0)));
2796 str1
[string_length(Field(formItem
, 0))] = 0;
2797 conn
->httpPostStrings
=
2798 curl_slist_append(conn
->httpPostStrings
, str1
);
2800 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2802 String_val(Field(formItem
, 1)),
2803 string_length(Field(formItem
, 1)));
2804 str2
[string_length(Field(formItem
, 1))] = 0;
2805 conn
->httpPostStrings
=
2806 curl_slist_append(conn
->httpPostStrings
, str2
);
2808 contentType
= Field(formItem
, 2);
2810 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2812 String_val(Field(contentType
, 0)),
2813 string_length(Field(contentType
, 0)));
2814 str3
[string_length(Field(contentType
, 0))] = 0;
2815 conn
->httpPostStrings
=
2816 curl_slist_append(conn
->httpPostStrings
, str3
);
2818 curl_formadd(&conn
->httpPostFirst
,
2819 &conn
->httpPostLast
,
2822 CURLFORM_NAMELENGTH
,
2823 string_length(Field(formItem
, 0)),
2824 CURLFORM_FILECONTENT
,
2826 CURLFORM_CONTENTTYPE
,
2832 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2836 case 2: /* CURLFORM_FILE */
2837 if (Wosize_val(formItem
) < 3)
2839 failwith("Incorrect CURLFORM_FILE parameters");
2842 if (Is_long(Field(formItem
, 2)) &&
2843 Long_val(Field(formItem
, 2)) == 0)
2845 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2847 String_val(Field(formItem
, 0)),
2848 string_length(Field(formItem
, 0)));
2849 str1
[string_length(Field(formItem
, 0))] = 0;
2850 conn
->httpPostStrings
=
2851 curl_slist_append(conn
->httpPostStrings
, str1
);
2853 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2855 String_val(Field(formItem
, 1)),
2856 string_length(Field(formItem
, 1)));
2857 str2
[string_length(Field(formItem
, 1))] = 0;
2858 conn
->httpPostStrings
=
2859 curl_slist_append(conn
->httpPostStrings
, str2
);
2861 curl_formadd(&conn
->httpPostFirst
,
2862 &conn
->httpPostLast
,
2865 CURLFORM_NAMELENGTH
,
2866 string_length(Field(formItem
, 0)),
2871 else if (Is_block(Field(formItem
, 2)))
2873 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2875 String_val(Field(formItem
, 0)),
2876 string_length(Field(formItem
, 0)));
2877 str1
[string_length(Field(formItem
, 0))] = 0;
2878 conn
->httpPostStrings
=
2879 curl_slist_append(conn
->httpPostStrings
, str1
);
2881 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2883 String_val(Field(formItem
, 1)),
2884 string_length(Field(formItem
, 1)));
2885 str2
[string_length(Field(formItem
, 1))] = 0;
2886 conn
->httpPostStrings
=
2887 curl_slist_append(conn
->httpPostStrings
, str2
);
2889 contentType
= Field(formItem
, 2);
2891 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2893 String_val(Field(contentType
, 0)),
2894 string_length(Field(contentType
, 0)));
2895 str3
[string_length(Field(contentType
, 0))] = 0;
2896 conn
->httpPostStrings
=
2897 curl_slist_append(conn
->httpPostStrings
, str3
);
2899 curl_formadd(&conn
->httpPostFirst
,
2900 &conn
->httpPostLast
,
2903 CURLFORM_NAMELENGTH
,
2904 string_length(Field(formItem
, 0)),
2907 CURLFORM_CONTENTTYPE
,
2913 failwith("Incorrect CURLFORM_FILE parameters");
2917 case 3: /* CURLFORM_BUFFER */
2918 if (Wosize_val(formItem
) < 4)
2920 failwith("Incorrect CURLFORM_BUFFER parameters");
2923 if (Is_long(Field(formItem
, 3)) &&
2924 Long_val(Field(formItem
, 3)) == 0)
2926 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2928 String_val(Field(formItem
, 0)),
2929 string_length(Field(formItem
, 0)));
2930 str1
[string_length(Field(formItem
, 0))] = 0;
2931 conn
->httpPostStrings
=
2932 curl_slist_append(conn
->httpPostStrings
, str1
);
2934 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2936 String_val(Field(formItem
, 1)),
2937 string_length(Field(formItem
, 1)));
2938 str2
[string_length(Field(formItem
, 1))] = 0;
2939 conn
->httpPostStrings
=
2940 curl_slist_append(conn
->httpPostStrings
, str2
);
2942 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2944 String_val(Field(formItem
, 2)),
2945 string_length(Field(formItem
, 2)));
2946 str3
[string_length(Field(formItem
, 2))] = 0;
2947 conn
->httpPostStrings
=
2948 curl_slist_append(conn
->httpPostStrings
, str3
);
2950 curl_formadd(&conn
->httpPostFirst
,
2951 &conn
->httpPostLast
,
2954 CURLFORM_NAMELENGTH
,
2955 string_length(Field(formItem
, 0)),
2960 CURLFORM_BUFFERLENGTH
,
2961 string_length(Field(formItem
, 2)),
2964 else if (Is_block(Field(formItem
, 3)))
2966 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2968 String_val(Field(formItem
, 0)),
2969 string_length(Field(formItem
, 0)));
2970 str1
[string_length(Field(formItem
, 0))] = 0;
2971 conn
->httpPostStrings
=
2972 curl_slist_append(conn
->httpPostStrings
, str1
);
2974 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2976 String_val(Field(formItem
, 1)),
2977 string_length(Field(formItem
, 1)));
2978 str2
[string_length(Field(formItem
, 1))] = 0;
2979 conn
->httpPostStrings
=
2980 curl_slist_append(conn
->httpPostStrings
, str2
);
2982 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2984 String_val(Field(formItem
, 2)),
2985 string_length(Field(formItem
, 2)));
2986 str3
[string_length(Field(formItem
, 2))] = 0;
2987 conn
->httpPostStrings
=
2988 curl_slist_append(conn
->httpPostStrings
, str3
);
2990 contentType
= Field(formItem
, 3);
2992 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2994 String_val(Field(contentType
, 0)),
2995 string_length(Field(contentType
, 0)));
2996 str4
[string_length(Field(contentType
, 0))] = 0;
2997 conn
->httpPostStrings
=
2998 curl_slist_append(conn
->httpPostStrings
, str4
);
3000 curl_formadd(&conn
->httpPostFirst
,
3001 &conn
->httpPostLast
,
3004 CURLFORM_NAMELENGTH
,
3005 string_length(Field(formItem
, 0)),
3010 CURLFORM_BUFFERLENGTH
,
3011 string_length(Field(formItem
, 2)),
3012 CURLFORM_CONTENTTYPE
,
3018 failwith("Incorrect CURLFORM_BUFFER parameters");
3023 listIter
= Field(listIter
, 1);
3026 result
= curl_easy_setopt(conn
->connection
,
3028 conn
->httpPostFirst
);
3030 if (result
!= CURLE_OK
)
3031 raiseError(conn
, result
);
3036 static void handleSSLCert(Connection
*conn
, value option
)
3039 CURLcode result
= CURLE_OK
;
3041 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3043 if (conn
->sslCert
!= NULL
)
3044 free(conn
->sslCert
);
3046 conn
->sslCert
= strdup(String_val(option
));
3048 result
= curl_easy_setopt(conn
->connection
,
3052 if (result
!= CURLE_OK
)
3053 raiseError(conn
, result
);
3058 static void handleSSLCertType(Connection
*conn
, value option
)
3061 CURLcode result
= CURLE_OK
;
3063 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3065 if (conn
->sslCertType
!= NULL
)
3066 free(conn
->sslCertType
);
3068 conn
->sslCertType
= strdup(String_val(option
));
3070 result
= curl_easy_setopt(conn
->connection
,
3071 CURLOPT_SSLCERTTYPE
,
3074 if (result
!= CURLE_OK
)
3075 raiseError(conn
, result
);
3080 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3083 CURLcode result
= CURLE_OK
;
3085 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3087 if (conn
->sslCertPasswd
!= NULL
)
3088 free(conn
->sslCertPasswd
);
3090 conn
->sslCertPasswd
= strdup(String_val(option
));
3092 result
= curl_easy_setopt(conn
->connection
,
3093 CURLOPT_SSLCERTPASSWD
,
3094 conn
->sslCertPasswd
);
3096 if (result
!= CURLE_OK
)
3097 raiseError(conn
, result
);
3102 static void handleSSLKey(Connection
*conn
, value option
)
3105 CURLcode result
= CURLE_OK
;
3107 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3109 if (conn
->sslKey
!= NULL
)
3112 conn
->sslKey
= strdup(String_val(option
));
3114 result
= curl_easy_setopt(conn
->connection
,
3118 if (result
!= CURLE_OK
)
3119 raiseError(conn
, result
);
3124 static void handleSSLKeyType(Connection
*conn
, value option
)
3127 CURLcode result
= CURLE_OK
;
3129 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3131 if (conn
->sslKeyType
!= NULL
)
3132 free(conn
->sslKeyType
);
3134 conn
->sslKeyType
= strdup(String_val(option
));
3136 result
= curl_easy_setopt(conn
->connection
,
3140 if (result
!= CURLE_OK
)
3141 raiseError(conn
, result
);
3146 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3149 CURLcode result
= CURLE_OK
;
3151 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3153 if (conn
->sslKeyPasswd
!= NULL
)
3154 free(conn
->sslKeyPasswd
);
3156 conn
->sslKeyPasswd
= strdup(String_val(option
));
3158 result
= curl_easy_setopt(conn
->connection
,
3159 CURLOPT_SSLKEYPASSWD
,
3160 conn
->sslKeyPasswd
);
3162 if (result
!= CURLE_OK
)
3163 raiseError(conn
, result
);
3168 static void handleSSLEngine(Connection
*conn
, value option
)
3171 CURLcode result
= CURLE_OK
;
3173 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3175 if (conn
->sslEngine
!= NULL
)
3176 free(conn
->sslEngine
);
3178 conn
->sslEngine
= strdup(String_val(option
));
3180 result
= curl_easy_setopt(conn
->connection
,
3184 if (result
!= CURLE_OK
)
3185 raiseError(conn
, result
);
3190 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3193 CURLcode result
= CURLE_OK
;
3195 result
= curl_easy_setopt(conn
->connection
,
3196 CURLOPT_SSLENGINE_DEFAULT
,
3199 if (result
!= CURLE_OK
)
3200 raiseError(conn
, result
);
3205 static void handleCRLF(Connection
*conn
, value option
)
3208 CURLcode result
= CURLE_OK
;
3210 result
= curl_easy_setopt(conn
->connection
,
3214 if (result
!= CURLE_OK
)
3215 raiseError(conn
, result
);
3220 static void handleQuote(Connection
*conn
, value option
)
3223 CAMLlocal1(listIter
);
3224 CURLcode result
= CURLE_OK
;
3226 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3228 free_curl_slist(conn
->quote
);
3233 while (!Is_long(listIter
))
3235 conn
->quote
= curl_slist_append(conn
->quote
, String_val(Field(listIter
, 0)));
3237 listIter
= Field(listIter
, 1);
3240 result
= curl_easy_setopt(conn
->connection
,
3244 if (result
!= CURLE_OK
)
3245 raiseError(conn
, result
);
3250 static void handlePostQuote(Connection
*conn
, value option
)
3253 CAMLlocal1(listIter
);
3254 CURLcode result
= CURLE_OK
;
3256 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3258 free_curl_slist(conn
->postQuote
);
3259 conn
->postQuote
= NULL
;
3263 while (!Is_long(listIter
))
3265 conn
->postQuote
= curl_slist_append(conn
->postQuote
, String_val(Field(listIter
, 0)));
3267 listIter
= Field(listIter
, 1);
3270 result
= curl_easy_setopt(conn
->connection
,
3274 if (result
!= CURLE_OK
)
3275 raiseError(conn
, result
);
3280 static void handleHeaderFunction(Connection
*conn
, value option
)
3283 CURLcode result
= CURLE_OK
;
3285 if (Tag_val(option
) == Closure_tag
)
3286 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3288 failwith("Not a proper closure");
3290 result
= curl_easy_setopt(conn
->connection
,
3291 CURLOPT_HEADERFUNCTION
,
3294 if (result
!= CURLE_OK
)
3295 raiseError(conn
, result
);
3297 result
= curl_easy_setopt(conn
->connection
,
3298 CURLOPT_WRITEHEADER
,
3301 if (result
!= CURLE_OK
)
3302 raiseError(conn
, result
);
3307 static void handleCookieFile(Connection
*conn
, value option
)
3310 CURLcode result
= CURLE_OK
;
3312 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3314 if (conn
->cookieFile
!= NULL
)
3315 free(conn
->cookieFile
);
3317 conn
->cookieFile
= strdup(String_val(option
));
3319 result
= curl_easy_setopt(conn
->connection
,
3323 if (result
!= CURLE_OK
)
3324 raiseError(conn
, result
);
3329 static void handleSSLVersion(Connection
*conn
, value option
)
3332 CURLcode result
= CURLE_OK
;
3334 result
= curl_easy_setopt(conn
->connection
,
3338 if (result
!= CURLE_OK
)
3339 raiseError(conn
, result
);
3344 static void handleTimeCondition(Connection
*conn
, value option
)
3347 CURLcode result
= CURLE_OK
;
3349 switch (Long_val(option
))
3351 case 0: /* TIMECOND_IFMODSINCE */
3352 result
= curl_easy_setopt(conn
->connection
,
3353 CURLOPT_TIMECONDITION
,
3354 CURL_TIMECOND_IFMODSINCE
);
3357 case 1: /* TIMECOND_IFUNMODSINCE */
3358 result
= curl_easy_setopt(conn
->connection
,
3359 CURLOPT_TIMECONDITION
,
3360 CURL_TIMECOND_IFUNMODSINCE
);
3364 failwith("Invalid TIMECOND Option");
3368 if (result
!= CURLE_OK
)
3369 raiseError(conn
, result
);
3374 static void handleTimeValue(Connection
*conn
, value option
)
3377 CURLcode result
= CURLE_OK
;
3379 result
= curl_easy_setopt(conn
->connection
,
3383 if (result
!= CURLE_OK
)
3384 raiseError(conn
, result
);
3389 static void handleCustomRequest(Connection
*conn
, value option
)
3392 CURLcode result
= CURLE_OK
;
3394 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3396 if (conn
->customRequest
!= NULL
)
3397 free(conn
->customRequest
);
3399 conn
->customRequest
= strdup(String_val(option
));
3401 result
= curl_easy_setopt(conn
->connection
,
3402 CURLOPT_CUSTOMREQUEST
,
3403 conn
->customRequest
);
3405 if (result
!= CURLE_OK
)
3406 raiseError(conn
, result
);
3411 static void handleInterface(Connection
*conn
, value option
)
3414 CURLcode result
= CURLE_OK
;
3416 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3418 if (conn
->interface
!= NULL
)
3419 free(conn
->interface
);
3421 conn
->interface
= strdup(String_val(option
));
3423 result
= curl_easy_setopt(conn
->connection
,
3427 if (result
!= CURLE_OK
)
3428 raiseError(conn
, result
);
3433 static void handleKRB4Level(Connection
*conn
, value option
)
3436 CURLcode result
= CURLE_OK
;
3438 switch (Long_val(option
))
3440 case 0: /* KRB4_NONE */
3441 result
= curl_easy_setopt(conn
->connection
,
3446 case 1: /* KRB4_CLEAR */
3447 result
= curl_easy_setopt(conn
->connection
,
3452 case 2: /* KRB4_SAFE */
3453 result
= curl_easy_setopt(conn
->connection
,
3458 case 3: /* KRB4_CONFIDENTIAL */
3459 result
= curl_easy_setopt(conn
->connection
,
3464 case 4: /* KRB4_PRIVATE */
3465 result
= curl_easy_setopt(conn
->connection
,
3471 failwith("Invalid KRB4 Option");
3475 if (result
!= CURLE_OK
)
3476 raiseError(conn
, result
);
3481 static void handleProgressFunction(Connection
*conn
, value option
)
3484 CURLcode result
= CURLE_OK
;
3486 if (Tag_val(option
) == Closure_tag
)
3487 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3489 failwith("Not a proper closure");
3491 result
= curl_easy_setopt(conn
->connection
,
3492 CURLOPT_PROGRESSFUNCTION
,
3494 if (result
!= CURLE_OK
)
3495 raiseError(conn
, result
);
3497 result
= curl_easy_setopt(conn
->connection
,
3498 CURLOPT_PROGRESSDATA
,
3501 if (result
!= CURLE_OK
)
3502 raiseError(conn
, result
);
3507 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3510 CURLcode result
= CURLE_OK
;
3512 result
= curl_easy_setopt(conn
->connection
,
3513 CURLOPT_SSL_VERIFYPEER
,
3516 if (result
!= CURLE_OK
)
3517 raiseError(conn
, result
);
3522 static void handleCAInfo(Connection
*conn
, value option
)
3525 CURLcode result
= CURLE_OK
;
3527 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3529 if (conn
->caInfo
!= NULL
)
3532 conn
->caInfo
= strdup(String_val(option
));
3534 result
= curl_easy_setopt(conn
->connection
,
3538 if (result
!= CURLE_OK
)
3539 raiseError(conn
, result
);
3544 static void handleCAPath(Connection
*conn
, value option
)
3547 CURLcode result
= CURLE_OK
;
3549 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3551 if (conn
->caPath
!= NULL
)
3554 conn
->caPath
= strdup(String_val(option
));
3556 result
= curl_easy_setopt(conn
->connection
,
3560 if (result
!= CURLE_OK
)
3561 raiseError(conn
, result
);
3566 static void handleFileTime(Connection
*conn
, value option
)
3569 CURLcode result
= CURLE_OK
;
3571 result
= curl_easy_setopt(conn
->connection
,
3575 if (result
!= CURLE_OK
)
3576 raiseError(conn
, result
);
3581 static void handleMaxRedirs(Connection
*conn
, value option
)
3584 CURLcode result
= CURLE_OK
;
3586 result
= curl_easy_setopt(conn
->connection
,
3590 if (result
!= CURLE_OK
)
3591 raiseError(conn
, result
);
3596 static void handleMaxConnects(Connection
*conn
, value option
)
3599 CURLcode result
= CURLE_OK
;
3601 result
= curl_easy_setopt(conn
->connection
,
3602 CURLOPT_MAXCONNECTS
,
3605 if (result
!= CURLE_OK
)
3606 raiseError(conn
, result
);
3611 static void handleClosePolicy(Connection
*conn
, value option
)
3614 CURLcode result
= CURLE_OK
;
3616 switch (Long_val(option
))
3618 case 0: /* CLOSEPOLICY_OLDEST */
3619 result
= curl_easy_setopt(conn
->connection
,
3620 CURLOPT_CLOSEPOLICY
,
3621 CURLCLOSEPOLICY_OLDEST
);
3624 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3625 result
= curl_easy_setopt(conn
->connection
,
3626 CURLOPT_CLOSEPOLICY
,
3627 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3631 failwith("Invalid CLOSEPOLICY Option");
3635 if (result
!= CURLE_OK
)
3636 raiseError(conn
, result
);
3641 static void handleFreshConnect(Connection
*conn
, value option
)
3644 CURLcode result
= CURLE_OK
;
3646 result
= curl_easy_setopt(conn
->connection
,
3647 CURLOPT_FRESH_CONNECT
,
3650 if (result
!= CURLE_OK
)
3651 raiseError(conn
, result
);
3656 static void handleForbidReuse(Connection
*conn
, value option
)
3659 CURLcode result
= CURLE_OK
;
3661 result
= curl_easy_setopt(conn
->connection
,
3662 CURLOPT_FORBID_REUSE
,
3665 if (result
!= CURLE_OK
)
3666 raiseError(conn
, result
);
3671 static void handleRandomFile(Connection
*conn
, value option
)
3674 CURLcode result
= CURLE_OK
;
3676 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3678 if (conn
->randomFile
!= NULL
)
3679 free(conn
->randomFile
);
3681 conn
->randomFile
= strdup(String_val(option
));
3683 result
= curl_easy_setopt(conn
->connection
,
3684 CURLOPT_RANDOM_FILE
,
3687 if (result
!= CURLE_OK
)
3688 raiseError(conn
, result
);
3693 static void handleEGDSocket(Connection
*conn
, value option
)
3696 CURLcode result
= CURLE_OK
;
3698 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3700 if (conn
->egdSocket
!= NULL
)
3701 free(conn
->egdSocket
);
3703 conn
->egdSocket
= strdup(String_val(option
));
3705 result
= curl_easy_setopt(conn
->connection
,
3709 if (result
!= CURLE_OK
)
3710 raiseError(conn
, result
);
3715 static void handleConnectTimeout(Connection
*conn
, value option
)
3718 CURLcode result
= CURLE_OK
;
3720 result
= curl_easy_setopt(conn
->connection
,
3721 CURLOPT_CONNECTTIMEOUT
,
3724 if (result
!= CURLE_OK
)
3725 raiseError(conn
, result
);
3730 static void handleHTTPGet(Connection
*conn
, value option
)
3733 CURLcode result
= CURLE_OK
;
3735 result
= curl_easy_setopt(conn
->connection
,
3739 if (result
!= CURLE_OK
)
3740 raiseError(conn
, result
);
3745 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3748 CURLcode result
= CURLE_OK
;
3750 switch (Long_val(option
))
3752 case 0: /* SSLVERIFYHOST_NONE */
3753 case 1: /* SSLVERIFYHOST_EXISTENCE */
3754 case 2: /* SSLVERIFYHOST_HOSTNAME */
3755 result
= curl_easy_setopt(conn
->connection
,
3756 CURLOPT_SSL_VERIFYHOST
,
3761 failwith("Invalid SSLVERIFYHOST Option");
3765 if (result
!= CURLE_OK
)
3766 raiseError(conn
, result
);
3771 static void handleCookieJar(Connection
*conn
, value option
)
3774 CURLcode result
= CURLE_OK
;
3776 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3778 if (conn
->cookieJar
!= NULL
)
3779 free(conn
->cookieJar
);
3781 conn
->cookieJar
= strdup(String_val(option
));
3783 result
= curl_easy_setopt(conn
->connection
,
3787 if (result
!= CURLE_OK
)
3788 raiseError(conn
, result
);
3793 static void handleSSLCipherList(Connection
*conn
, value option
)
3796 CURLcode result
= CURLE_OK
;
3798 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3800 if (conn
->sslCipherList
!= NULL
)
3801 free(conn
->sslCipherList
);
3803 conn
->sslCipherList
= strdup(String_val(option
));
3805 result
= curl_easy_setopt(conn
->connection
,
3806 CURLOPT_SSL_CIPHER_LIST
,
3807 conn
->sslCipherList
);
3809 if (result
!= CURLE_OK
)
3810 raiseError(conn
, result
);
3815 static void handleHTTPVersion(Connection
*conn
, value option
)
3818 CURLcode result
= CURLE_OK
;
3820 switch (Long_val(option
))
3822 case 0: /* HTTP_VERSION_NONE */
3823 result
= curl_easy_setopt(conn
->connection
,
3824 CURLOPT_HTTP_VERSION
,
3825 CURL_HTTP_VERSION_NONE
);
3828 case 1: /* HTTP_VERSION_1_0 */
3829 result
= curl_easy_setopt(conn
->connection
,
3830 CURLOPT_HTTP_VERSION
,
3831 CURL_HTTP_VERSION_1_0
);
3834 case 2: /* HTTP_VERSION_1_1 */
3835 result
= curl_easy_setopt(conn
->connection
,
3836 CURLOPT_HTTP_VERSION
,
3837 CURL_HTTP_VERSION_1_1
);
3841 failwith("Invalid HTTP_VERSION Option");
3845 if (result
!= CURLE_OK
)
3846 raiseError(conn
, result
);
3851 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3854 CURLcode result
= CURLE_OK
;
3856 result
= curl_easy_setopt(conn
->connection
,
3857 CURLOPT_FTP_USE_EPSV
,
3860 if (result
!= CURLE_OK
)
3861 raiseError(conn
, result
);
3866 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3869 CURLcode result
= CURLE_OK
;
3871 result
= curl_easy_setopt(conn
->connection
,
3872 CURLOPT_DNS_CACHE_TIMEOUT
,
3875 if (result
!= CURLE_OK
)
3876 raiseError(conn
, result
);
3881 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3884 CURLcode result
= CURLE_OK
;
3886 result
= curl_easy_setopt(conn
->connection
,
3887 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3890 if (result
!= CURLE_OK
)
3891 raiseError(conn
, result
);
3896 static void handleDebugFunction(Connection
*conn
, value option
)
3899 CURLcode result
= CURLE_OK
;
3901 if (Tag_val(option
) == Closure_tag
)
3902 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3904 failwith("Not a proper closure");
3906 result
= curl_easy_setopt(conn
->connection
,
3907 CURLOPT_DEBUGFUNCTION
,
3909 if (result
!= CURLE_OK
)
3910 raiseError(conn
, result
);
3912 result
= curl_easy_setopt(conn
->connection
,
3916 if (result
!= CURLE_OK
)
3917 raiseError(conn
, result
);
3922 static void handlePrivate(Connection
*conn
, value option
)
3924 #if HAVE_DECL_CURLOPT_PRIVATE
3926 CURLcode result
= CURLE_OK
;
3928 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
3930 if (conn
->private != NULL
)
3931 free(conn
->private);
3933 conn
->private = strdup(String_val(option
));
3935 result
= curl_easy_setopt(conn
->connection
,
3939 if (result
!= CURLE_OK
)
3940 raiseError(conn
, result
);
3944 #warning "libcurl does not implement CURLOPT_PRIVATE"
3945 failwith("libcurl does not implement CURLOPT_PRIVATE");
3949 static void handleHTTP200Aliases(Connection
*conn
, value option
)
3951 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3953 CAMLlocal1(listIter
);
3954 CURLcode result
= CURLE_OK
;
3956 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
3958 free_curl_slist(conn
->http200Aliases
);
3959 conn
->http200Aliases
= NULL
;
3963 while (!Is_long(listIter
))
3965 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, String_val(Field(listIter
, 0)));
3967 listIter
= Field(listIter
, 1);
3970 result
= curl_easy_setopt(conn
->connection
,
3971 CURLOPT_HTTP200ALIASES
,
3972 conn
->http200Aliases
);
3974 if (result
!= CURLE_OK
)
3975 raiseError(conn
, result
);
3979 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
3980 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
3984 static void handleUnrestrictedAuth(Connection
*conn
, value option
)
3986 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
3988 CURLcode result
= CURLE_OK
;
3990 result
= curl_easy_setopt(conn
->connection
,
3991 CURLOPT_UNRESTRICTED_AUTH
,
3994 if (result
!= CURLE_OK
)
3995 raiseError(conn
, result
);
3999 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4000 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4004 static void handleFTPUseEPRT(Connection
*conn
, value option
)
4006 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4008 CURLcode result
= CURLE_OK
;
4010 result
= curl_easy_setopt(conn
->connection
,
4011 CURLOPT_FTP_USE_EPRT
,
4014 if (result
!= CURLE_OK
)
4015 raiseError(conn
, result
);
4019 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4020 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4024 static void handleHTTPAuth(Connection
*conn
, value option
)
4026 #if HAVE_DECL_CURLOPT_HTTPAUTH
4028 CAMLlocal1(listIter
);
4029 CURLcode result
= CURLE_OK
;
4030 long auth
= CURLAUTH_NONE
;
4034 while (!Is_long(listIter
))
4036 switch (Long_val(Field(listIter
, 0)))
4038 case 0: /* CURLAUTH_BASIC */
4039 auth
|= CURLAUTH_BASIC
;
4042 case 1: /* CURLAUTH_DIGEST */
4043 auth
|= CURLAUTH_DIGEST
;
4046 case 2: /* CURLAUTH_GSSNEGOTIATE */
4047 auth
|= CURLAUTH_GSSNEGOTIATE
;
4050 case 3: /* CURLAUTH_NTLM */
4051 auth
|= CURLAUTH_NTLM
;
4054 case 4: /* CURLAUTH_ANY */
4055 auth
|= CURLAUTH_ANY
;
4058 case 5: /* CURLAUTH_ANYSAFE */
4059 auth
|= CURLAUTH_ANYSAFE
;
4063 failwith("Invalid HTTPAUTH Value");
4067 listIter
= Field(listIter
, 1);
4070 result
= curl_easy_setopt(conn
->connection
,
4074 if (result
!= CURLE_OK
)
4075 raiseError(conn
, result
);
4079 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4080 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4084 static void handleFTPCreateMissingDirs(Connection
*conn
, value option
)
4086 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4088 CURLcode result
= CURLE_OK
;
4090 result
= curl_easy_setopt(conn
->connection
,
4091 CURLOPT_FTP_CREATE_MISSING_DIRS
,
4094 if (result
!= CURLE_OK
)
4095 raiseError(conn
, result
);
4099 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4100 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4104 static void handleProxyAuth(Connection
*conn
, value option
)
4106 #if HAVE_DECL_CURLOPT_PROXYAUTH
4108 CAMLlocal1(listIter
);
4109 CURLcode result
= CURLE_OK
;
4110 long auth
= CURLAUTH_NONE
;
4114 while (!Is_long(listIter
))
4116 switch (Long_val(Field(listIter
, 0)))
4118 case 0: /* CURLAUTH_BASIC */
4119 auth
|= CURLAUTH_BASIC
;
4122 case 1: /* CURLAUTH_DIGEST */
4123 auth
|= CURLAUTH_DIGEST
;
4126 case 2: /* CURLAUTH_GSSNEGOTIATE */
4127 auth
|= CURLAUTH_GSSNEGOTIATE
;
4130 case 3: /* CURLAUTH_NTLM */
4131 auth
|= CURLAUTH_NTLM
;
4134 case 4: /* CURLAUTH_ANY */
4135 auth
|= CURLAUTH_ANY
;
4138 case 5: /* CURLAUTH_ANYSAFE */
4139 auth
|= CURLAUTH_ANYSAFE
;
4143 failwith("Invalid HTTPAUTH Value");
4147 listIter
= Field(listIter
, 1);
4150 result
= curl_easy_setopt(conn
->connection
,
4154 if (result
!= CURLE_OK
)
4155 raiseError(conn
, result
);
4159 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4160 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4164 static void handleFTPResponseTimeout(Connection
*conn
, value option
)
4166 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4168 CURLcode result
= CURLE_OK
;
4170 result
= curl_easy_setopt(conn
->connection
,
4171 CURLOPT_FTP_RESPONSE_TIMEOUT
,
4174 if (result
!= CURLE_OK
)
4175 raiseError(conn
, result
);
4179 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4180 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4184 static void handleIPResolve(Connection
*conn
, value option
)
4186 #if HAVE_DECL_CURLOPT_IPRESOLVE
4188 CURLcode result
= CURLE_OK
;
4190 switch (Long_val(option
))
4192 case 0: /* CURL_IPRESOLVE_WHATEVER */
4193 result
= curl_easy_setopt(conn
->connection
,
4195 CURL_IPRESOLVE_WHATEVER
);
4198 case 1: /* CURL_IPRESOLVE_V4 */
4199 result
= curl_easy_setopt(conn
->connection
,
4204 case 2: /* CURL_IPRESOLVE_V6 */
4205 result
= curl_easy_setopt(conn
->connection
,
4211 failwith("Invalid IPRESOLVE Value");
4215 if (result
!= CURLE_OK
)
4216 raiseError(conn
, result
);
4220 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4221 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4225 static void handleMaxFileSize(Connection
*conn
, value option
)
4227 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4229 CURLcode result
= CURLE_OK
;
4231 result
= curl_easy_setopt(conn
->connection
,
4232 CURLOPT_MAXFILESIZE
,
4235 if (result
!= CURLE_OK
)
4236 raiseError(conn
, result
);
4240 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4241 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4245 static void handleInFileSizeLarge(Connection
*conn
, value option
)
4247 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4249 CURLcode result
= CURLE_OK
;
4251 result
= curl_easy_setopt(conn
->connection
,
4252 CURLOPT_INFILESIZE_LARGE
,
4255 if (result
!= CURLE_OK
)
4256 raiseError(conn
, result
);
4260 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4261 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4265 static void handleResumeFromLarge(Connection
*conn
, value option
)
4267 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4269 CURLcode result
= CURLE_OK
;
4271 result
= curl_easy_setopt(conn
->connection
,
4272 CURLOPT_RESUME_FROM_LARGE
,
4275 if (result
!= CURLE_OK
)
4276 raiseError(conn
, result
);
4280 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4281 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4285 static void handleMaxFileSizeLarge(Connection
*conn
, value option
)
4287 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4289 CURLcode result
= CURLE_OK
;
4291 result
= curl_easy_setopt(conn
->connection
,
4292 CURLOPT_MAXFILESIZE_LARGE
,
4295 if (result
!= CURLE_OK
)
4296 raiseError(conn
, result
);
4300 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4301 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4305 static void handleNETRCFile(Connection
*conn
, value option
)
4307 #if HAVE_DECL_CURLOPT_NETRC_FILE
4309 CURLcode result
= CURLE_OK
;
4311 Store_field(conn
->ocamlValues
, OcamlNETRCFile
, option
);
4313 if (conn
->netrcFile
!= NULL
)
4314 free(conn
->netrcFile
);
4316 conn
->netrcFile
= strdup(String_val(option
));
4318 result
= curl_easy_setopt(conn
->connection
,
4322 if (result
!= CURLE_OK
)
4323 raiseError(conn
, result
);
4327 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4328 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4332 static void handleFTPSSL(Connection
*conn
, value option
)
4334 #if HAVE_DECL_CURLOPT_FTP_SSL
4336 CURLcode result
= CURLE_OK
;
4338 switch (Long_val(option
))
4340 case 0: /* CURLFTPSSL_NONE */
4341 result
= curl_easy_setopt(conn
->connection
,
4346 case 1: /* CURLFTPSSL_TRY */
4347 result
= curl_easy_setopt(conn
->connection
,
4352 case 2: /* CURLFTPSSL_CONTROL */
4353 result
= curl_easy_setopt(conn
->connection
,
4355 CURLFTPSSL_CONTROL
);
4358 case 3: /* CURLFTPSSL_ALL */
4359 result
= curl_easy_setopt(conn
->connection
,
4365 failwith("Invalid FTP_SSL Value");
4369 if (result
!= CURLE_OK
)
4370 raiseError(conn
, result
);
4374 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4375 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4379 static void handlePostFieldSizeLarge(Connection
*conn
, value option
)
4381 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4383 CURLcode result
= CURLE_OK
;
4385 result
= curl_easy_setopt(conn
->connection
,
4386 CURLOPT_POSTFIELDSIZE_LARGE
,
4389 if (result
!= CURLE_OK
)
4390 raiseError(conn
, result
);
4394 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4395 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4399 static void handleTCPNoDelay(Connection
*conn
, value option
)
4401 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4403 CURLcode result
= CURLE_OK
;
4405 result
= curl_easy_setopt(conn
->connection
,
4406 CURLOPT_TCP_NODELAY
,
4409 if (result
!= CURLE_OK
)
4410 raiseError(conn
, result
);
4414 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4415 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4419 static void handleFTPSSLAuth(Connection
*conn
, value option
)
4421 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4423 CURLcode result
= CURLE_OK
;
4425 switch (Long_val(option
))
4427 case 0: /* CURLFTPAUTH_DEFAULT */
4428 result
= curl_easy_setopt(conn
->connection
,
4430 CURLFTPAUTH_DEFAULT
);
4433 case 1: /* CURLFTPAUTH_SSL */
4434 result
= curl_easy_setopt(conn
->connection
,
4439 case 2: /* CURLFTPAUTH_TLS */
4440 result
= curl_easy_setopt(conn
->connection
,
4446 failwith("Invalid FTPSSLAUTH value");
4450 if (result
!= CURLE_OK
)
4451 raiseError(conn
, result
);
4455 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4456 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4460 static void handleIOCTLFunction(Connection
*conn
, value option
)
4462 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4464 CURLcode result
= CURLE_OK
;
4466 if (Tag_val(option
) == Closure_tag
)
4467 Store_field(conn
->ocamlValues
, OcamlIOCTLCallback
, option
);
4469 failwith("Not a proper closure");
4471 result
= curl_easy_setopt(conn
->connection
,
4472 CURLOPT_IOCTLFUNCTION
,
4474 if (result
!= CURLE_OK
)
4475 raiseError(conn
, result
);
4477 result
= curl_easy_setopt(conn
->connection
,
4481 if (result
!= CURLE_OK
)
4482 raiseError(conn
, result
);
4486 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4487 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4491 static void handleFTPAccount(Connection
*conn
, value option
)
4493 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4495 CURLcode result
= CURLE_OK
;
4497 Store_field(conn
->ocamlValues
, OcamlFTPAccount
, option
);
4499 if (conn
->ftpaccount
!= NULL
)
4500 free(conn
->ftpaccount
);
4502 conn
->ftpaccount
= strdup(String_val(option
));
4504 result
= curl_easy_setopt(conn
->connection
,
4505 CURLOPT_FTP_ACCOUNT
,
4508 if (result
!= CURLE_OK
)
4509 raiseError(conn
, result
);
4513 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4514 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4518 static void handleCookieList(Connection
*conn
, value option
)
4520 #if HAVE_DECL_CURLOPT_COOKIELIST
4522 CURLcode result
= CURLE_OK
;
4524 Store_field(conn
->ocamlValues
, OcamlCookieList
, option
);
4526 if (conn
->cookielist
!= NULL
)
4527 free(conn
->cookielist
);
4529 conn
->cookielist
= strdup(String_val(option
));
4531 result
= curl_easy_setopt(conn
->connection
,
4535 if (result
!= CURLE_OK
)
4536 raiseError(conn
, result
);
4540 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4541 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4545 static void handleIgnoreContentLength(Connection
*conn
, value option
)
4547 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4549 CURLcode result
= CURLE_OK
;
4551 result
= curl_easy_setopt(conn
->connection
,
4552 CURLOPT_IGNORE_CONTENT_LENGTH
,
4555 if (result
!= CURLE_OK
)
4556 raiseError(conn
, result
);
4560 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4561 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4565 static void handleFTPSkipPASVIP(Connection
*conn
, value option
)
4567 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4569 CURLcode result
= CURLE_OK
;
4571 result
= curl_easy_setopt(conn
->connection
,
4572 CURLOPT_FTP_SKIP_PASV_IP
,
4575 if (result
!= CURLE_OK
)
4576 raiseError(conn
, result
);
4580 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4581 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4585 static void handleFTPFileMethod(Connection
*conn
, value option
)
4587 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4589 CURLcode result
= CURLE_OK
;
4591 switch (Long_val(option
))
4593 case 0: /* CURLFTPMETHOD_DEFAULT */
4594 result
= curl_easy_setopt(conn
->connection
,
4595 CURLOPT_FTP_FILEMETHOD
,
4596 CURLFTPMETHOD_DEFAULT
);
4599 case 1: /* CURLFTMETHOD_MULTICWD */
4600 result
= curl_easy_setopt(conn
->connection
,
4601 CURLOPT_FTP_FILEMETHOD
,
4602 CURLFTPMETHOD_MULTICWD
);
4605 case 2: /* CURLFTPMETHOD_NOCWD */
4606 result
= curl_easy_setopt(conn
->connection
,
4607 CURLOPT_FTP_FILEMETHOD
,
4608 CURLFTPMETHOD_NOCWD
);
4611 case 3: /* CURLFTPMETHOD_SINGLECWD */
4612 result
= curl_easy_setopt(conn
->connection
,
4613 CURLOPT_FTP_FILEMETHOD
,
4614 CURLFTPMETHOD_SINGLECWD
);
4617 failwith("Invalid FTP_FILEMETHOD value");
4621 if (result
!= CURLE_OK
)
4622 raiseError(conn
, result
);
4626 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4627 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4631 static void handleLocalPort(Connection
*conn
, value option
)
4633 #if HAVE_DECL_CURLOPT_LOCALPORT
4635 CURLcode result
= CURLE_OK
;
4637 result
= curl_easy_setopt(conn
->connection
,
4641 if (result
!= CURLE_OK
)
4642 raiseError(conn
, result
);
4646 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4647 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4651 static void handleLocalPortRange(Connection
*conn
, value option
)
4653 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4655 CURLcode result
= CURLE_OK
;
4657 result
= curl_easy_setopt(conn
->connection
,
4658 CURLOPT_LOCALPORTRANGE
,
4661 if (result
!= CURLE_OK
)
4662 raiseError(conn
, result
);
4666 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4667 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4671 static void handleConnectOnly(Connection
*conn
, value option
)
4673 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4675 CURLcode result
= CURLE_OK
;
4677 result
= curl_easy_setopt(conn
->connection
,
4678 CURLOPT_CONNECT_ONLY
,
4681 if (result
!= CURLE_OK
)
4682 raiseError(conn
, result
);
4686 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4687 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4691 static void handleMaxSendSpeedLarge(Connection
*conn
, value option
)
4693 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4695 CURLcode result
= CURLE_OK
;
4697 result
= curl_easy_setopt(conn
->connection
,
4698 CURLOPT_MAX_SEND_SPEED_LARGE
,
4701 if (result
!= CURLE_OK
)
4702 raiseError(conn
, result
);
4706 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4707 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4711 static void handleMaxRecvSpeedLarge(Connection
*conn
, value option
)
4713 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4715 CURLcode result
= CURLE_OK
;
4717 result
= curl_easy_setopt(conn
->connection
,
4718 CURLOPT_MAX_RECV_SPEED_LARGE
,
4721 if (result
!= CURLE_OK
)
4722 raiseError(conn
, result
);
4726 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4727 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4731 static void handleFTPAlternativeToUser(Connection
*conn
, value option
)
4733 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4735 CURLcode result
= CURLE_OK
;
4737 Store_field(conn
->ocamlValues
, OcamlFTPAlternativeToUser
, option
);
4739 if (conn
->ftpAlternativeToUser
!= NULL
)
4740 free(conn
->ftpAlternativeToUser
);
4742 conn
->ftpAlternativeToUser
= strdup(String_val(option
));
4744 result
= curl_easy_setopt(conn
->connection
,
4745 CURLOPT_FTP_ALTERNATIVE_TO_USER
,
4746 conn
->ftpAlternativeToUser
);
4748 if (result
!= CURLE_OK
)
4749 raiseError(conn
, result
);
4753 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4754 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4758 static void handleSSLSessionIdCache(Connection
*conn
, value option
)
4760 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4762 CURLcode result
= CURLE_OK
;
4764 result
= curl_easy_setopt(conn
->connection
,
4765 CURLOPT_SSL_SESSIONID_CACHE
,
4768 if (result
!= CURLE_OK
)
4769 raiseError(conn
, result
);
4773 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4774 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4778 static void handleSSHAuthTypes(Connection
*conn
, value option
)
4780 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4782 CAMLlocal1(listIter
);
4783 CURLcode result
= CURLE_OK
;
4784 long authTypes
= CURLSSH_AUTH_NONE
;
4788 while (!Is_long(listIter
))
4790 switch (Long_val(Field(listIter
, 0)))
4792 case 0: /* CURLSSH_AUTH_ANY */
4793 authTypes
|= CURLSSH_AUTH_ANY
;
4796 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4797 authTypes
|= CURLSSH_AUTH_PUBLICKEY
;
4800 case 2: /* CURLSSH_AUTH_PASSWORD */
4801 authTypes
|= CURLSSH_AUTH_PASSWORD
;
4804 case 3: /* CURLSSH_AUTH_HOST */
4805 authTypes
|= CURLSSH_AUTH_HOST
;
4808 case 4: /* CURLSSH_AUTH_KEYBOARD */
4809 authTypes
|= CURLSSH_AUTH_KEYBOARD
;
4813 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4817 listIter
= Field(listIter
, 1);
4820 result
= curl_easy_setopt(conn
->connection
,
4821 CURLOPT_SSH_AUTH_TYPES
,
4824 if (result
!= CURLE_OK
)
4825 raiseError(conn
, result
);
4829 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4830 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4834 static void handleSSHPublicKeyFile(Connection
*conn
, value option
)
4836 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4838 CURLcode result
= CURLE_OK
;
4840 Store_field(conn
->ocamlValues
, OcamlSSHPublicKeyFile
, option
);
4842 if (conn
->sshPublicKeyFile
!= NULL
)
4843 free(conn
->sshPublicKeyFile
);
4845 conn
->sshPublicKeyFile
= strdup(String_val(option
));
4847 result
= curl_easy_setopt(conn
->connection
,
4848 CURLOPT_SSH_PUBLIC_KEYFILE
,
4849 conn
->sshPublicKeyFile
);
4851 if (result
!= CURLE_OK
)
4852 raiseError(conn
, result
);
4856 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4857 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4861 static void handleSSHPrivateKeyFile(Connection
*conn
, value option
)
4863 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4865 CURLcode result
= CURLE_OK
;
4867 Store_field(conn
->ocamlValues
, OcamlSSHPrivateKeyFile
, option
);
4869 if (conn
->sshPrivateKeyFile
!= NULL
)
4870 free(conn
->sshPrivateKeyFile
);
4872 conn
->sshPrivateKeyFile
= strdup(String_val(option
));
4874 result
= curl_easy_setopt(conn
->connection
,
4875 CURLOPT_SSH_PRIVATE_KEYFILE
,
4876 conn
->sshPrivateKeyFile
);
4878 if (result
!= CURLE_OK
)
4879 raiseError(conn
, result
);
4883 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4884 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4888 static void handleFTPSSLCCC(Connection
*conn
, value option
)
4890 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4892 CURLcode result
= CURLE_OK
;
4894 switch (Long_val(option
))
4896 case 0: /* CURLFTPSSL_CCC_NONE */
4897 result
= curl_easy_setopt(conn
->connection
,
4898 CURLOPT_FTP_SSL_CCC
,
4899 CURLFTPSSL_CCC_NONE
);
4902 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4903 result
= curl_easy_setopt(conn
->connection
,
4904 CURLOPT_FTP_SSL_CCC
,
4905 CURLFTPSSL_CCC_PASSIVE
);
4908 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4909 result
= curl_easy_setopt(conn
->connection
,
4910 CURLOPT_FTP_SSL_CCC
,
4911 CURLFTPSSL_CCC_ACTIVE
);
4915 failwith("Invalid FTPSSL_CCC value");
4919 if (result
!= CURLE_OK
)
4920 raiseError(conn
, result
);
4924 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4925 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4929 static void handleTimeoutMS(Connection
*conn
, value option
)
4931 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4933 CURLcode result
= CURLE_OK
;
4935 result
= curl_easy_setopt(conn
->connection
,
4939 if (result
!= CURLE_OK
)
4940 raiseError(conn
, result
);
4944 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4945 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4949 static void handleConnectTimeoutMS(Connection
*conn
, value option
)
4951 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4953 CURLcode result
= CURLE_OK
;
4955 result
= curl_easy_setopt(conn
->connection
,
4956 CURLOPT_CONNECTTIMEOUT_MS
,
4959 if (result
!= CURLE_OK
)
4960 raiseError(conn
, result
);
4964 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4965 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
4969 static void handleHTTPTransferDecoding(Connection
*conn
, value option
)
4971 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
4973 CURLcode result
= CURLE_OK
;
4975 result
= curl_easy_setopt(conn
->connection
,
4976 CURLOPT_HTTP_TRANSFER_DECODING
,
4979 if (result
!= CURLE_OK
)
4980 raiseError(conn
, result
);
4984 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
4985 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
4989 static void handleHTTPContentDecoding(Connection
*conn
, value option
)
4991 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
4993 CURLcode result
= CURLE_OK
;
4995 result
= curl_easy_setopt(conn
->connection
,
4996 CURLOPT_HTTP_CONTENT_DECODING
,
4999 if (result
!= CURLE_OK
)
5000 raiseError(conn
, result
);
5004 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5005 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5009 static void handleNewFilePerms(Connection
*conn
, value option
)
5011 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5013 CURLcode result
= CURLE_OK
;
5015 result
= curl_easy_setopt(conn
->connection
,
5016 CURLOPT_NEW_FILE_PERMS
,
5019 if (result
!= CURLE_OK
)
5020 raiseError(conn
, result
);
5024 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5025 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5029 static void handleNewDirectoryPerms(Connection
*conn
, value option
)
5031 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5033 CURLcode result
= CURLE_OK
;
5035 result
= curl_easy_setopt(conn
->connection
,
5036 CURLOPT_NEW_DIRECTORY_PERMS
,
5039 if (result
!= CURLE_OK
)
5040 raiseError(conn
, result
);
5044 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5045 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5049 static void handlePost301(Connection
*conn
, value option
)
5051 #if HAVE_DECL_CURLOPT_POST301
5053 CURLcode result
= CURLE_OK
;
5055 result
= curl_easy_setopt(conn
->connection
,
5059 if (result
!= CURLE_OK
)
5060 raiseError(conn
, result
);
5064 #warning "libcurl does not implement CURLOPT_POST301"
5065 failwith("libcurl does not implement CURLOPT_POST301");
5069 static void handleSSHHostPublicKeyMD5(Connection
*conn
, value option
)
5071 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5073 CURLcode result
= CURLE_OK
;
5075 Store_field(conn
->ocamlValues
, OcamlSSHHostPublicKeyMD5
, option
);
5077 if (conn
->sshHostPublicKeyMD5
!= NULL
)
5078 free(conn
->sshHostPublicKeyMD5
);
5080 conn
->sshHostPublicKeyMD5
= strdup(String_val(option
));
5082 result
= curl_easy_setopt(conn
->connection
,
5083 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
,
5084 conn
->sshHostPublicKeyMD5
);
5086 if (result
!= CURLE_OK
)
5087 raiseError(conn
, result
);
5091 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5092 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5096 static void handleCopyPostFields(Connection
*conn
, value option
)
5098 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5100 CURLcode result
= CURLE_OK
;
5102 Store_field(conn
->ocamlValues
, OcamlCopyPostFields
, option
);
5104 if (conn
->copyPostFields
!= NULL
)
5105 free(conn
->copyPostFields
);
5107 conn
->copyPostFields
= strdup(String_val(option
));
5109 result
= curl_easy_setopt(conn
->connection
,
5110 CURLOPT_COPYPOSTFIELDS
,
5111 conn
->copyPostFields
);
5113 if (result
!= CURLE_OK
)
5114 raiseError(conn
, result
);
5118 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5119 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5123 static void handleProxyTransferMode(Connection
*conn
, value option
)
5125 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5127 CURLcode result
= CURLE_OK
;
5129 result
= curl_easy_setopt(conn
->connection
,
5130 CURLOPT_PROXY_TRANSFER_MODE
,
5133 if (result
!= CURLE_OK
)
5134 raiseError(conn
, result
);
5138 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5139 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5143 static void handleSeekFunction(Connection
*conn
, value option
)
5145 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5147 CURLcode result
= CURLE_OK
;
5149 if (Tag_val(option
) == Closure_tag
)
5150 Store_field(conn
->ocamlValues
, OcamlSeekFunctionCallback
, option
);
5152 failwith("Not a proper closure");
5154 result
= curl_easy_setopt(conn
->connection
,
5155 CURLOPT_SEEKFUNCTION
,
5158 if (result
!= CURLE_OK
)
5159 raiseError(conn
, result
);
5161 result
= curl_easy_setopt(conn
->connection
,
5165 if (result
!= CURLE_OK
)
5166 raiseError(conn
, result
);
5170 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5171 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5175 static void handleAutoReferer(Connection
*conn
, value option
)
5177 #if HAVE_DECL_CURLOPT_AUTOREFERER
5179 CURLcode result
= curl_easy_setopt(conn
->connection
,
5180 CURLOPT_AUTOREFERER
,
5183 if (result
!= CURLE_OK
)
5184 raiseError(conn
, result
);
5188 #warning "libcurl does not implement CURLOPT_AUTOREFERER"
5189 failwith("libcurl does not implement CURLOPT_AUTOREFERER");
5193 static void handleOpenSocketFunction(Connection
*conn
, value option
)
5195 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
5197 CURLcode result
= CURLE_OK
;
5199 Store_field(conn
->ocamlValues
, OcamlOpenSocketFunctionCallback
, option
);
5201 result
= curl_easy_setopt(conn
->connection
,
5202 CURLOPT_OPENSOCKETDATA
,
5205 if (result
!= CURLE_OK
)
5206 raiseError(conn
, result
);
5208 result
= curl_easy_setopt(conn
->connection
,
5209 CURLOPT_OPENSOCKETFUNCTION
,
5210 openSocketFunction
);
5212 if (result
!= CURLE_OK
)
5213 raiseError(conn
, result
);
5217 #warning "libcurl does not implement CURLOPT_OPENSOCKETFUNCTION"
5218 failwith("libcurl does not implement CURLOPT_OPENSOCKETFUNCTION");
5222 static void handleProxyType(Connection
*conn
, value option
)
5224 #if HAVE_DECL_CURLOPT_PROXYTYPE
5226 CURLcode result
= CURLE_OK
;
5229 switch (Long_val(option
))
5231 case 0: proxy_type
= CURLPROXY_HTTP
; break;
5232 case 1: proxy_type
= CURLPROXY_HTTP_1_0
; break;
5233 case 2: proxy_type
= CURLPROXY_SOCKS4
; break;
5234 case 3: proxy_type
= CURLPROXY_SOCKS5
; break;
5235 case 4: proxy_type
= CURLPROXY_SOCKS4A
; break;
5236 case 5: proxy_type
= CURLPROXY_SOCKS5_HOSTNAME
; break;
5238 failwith("Invalid curl proxy type");
5241 result
= curl_easy_setopt(conn
->connection
,
5245 if (result
!= CURLE_OK
)
5246 raiseError(conn
, result
);
5250 #warning "libcurl does not implement CURLOPT_PROXYTYPE"
5251 failwith("libcurl does not implement CURLOPT_PROXYTYPE");
5258 ** curl_easy_setopt helper function
5261 CAMLprim value
helper_curl_easy_setopt(value conn
, value option
)
5263 CAMLparam2(conn
, option
);
5265 Connection
*connection
= Connection_val(conn
);
5267 checkConnection(connection
);
5269 if (Is_long(option
))
5273 sprintf(error
, "Unimplemented Option: %s",
5274 findOption(unimplementedOptionMap
,
5275 (CURLoption
)(Long_val(option
))));
5280 if (!Is_block(option
))
5281 failwith("Not a block");
5283 if (Wosize_val(option
) < 1)
5284 failwith("Insufficient data in block");
5286 data
= Field(option
, 0);
5288 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5289 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5292 failwith("Invalid CURLOPT Option");
5294 CAMLreturn(Val_unit
);
5298 ** curl_easy_perform helper function
5301 CAMLprim value
helper_curl_easy_perform(value conn
)
5304 CURLcode result
= CURLE_OK
;
5305 Connection
*connection
= Connection_val(conn
);
5307 checkConnection(connection
);
5309 enter_blocking_section();
5310 result
= curl_easy_perform(connection
->connection
);
5311 leave_blocking_section();
5313 if (result
!= CURLE_OK
)
5314 raiseError(connection
, result
);
5316 CAMLreturn(Val_unit
);
5320 ** curl_easy_cleanup helper function
5323 CAMLprim value
helper_curl_easy_cleanup(value conn
)
5326 Connection
*connection
= Connection_val(conn
);
5328 checkConnection(connection
);
5330 removeConnection(connection
);
5332 CAMLreturn(Val_unit
);
5336 ** curl_easy_duphandle helper function
5339 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5343 Connection
*connection
= Connection_val(conn
);
5345 checkConnection(connection
);
5347 result
= caml_alloc(1, Abstract_tag
);
5348 Field(result
, 0) = (value
)duplicateConnection(connection
);
5354 ** curl_easy_getinfo helper function
5357 enum GetInfoResultType
{
5358 StringValue
, LongValue
, DoubleValue
, StringListValue
5361 value
convertStringList(struct curl_slist
*slist
)
5364 CAMLlocal3(result
, current
, next
);
5365 struct curl_slist
*p
= slist
;
5367 result
= Val_int(0);
5368 current
= Val_int(0);
5373 next
= alloc_tuple(2);
5374 Store_field(next
, 0, copy_string(p
->data
));
5375 Store_field(next
, 1, Val_int(0));
5377 if (result
== Val_int(0))
5380 if (current
!= Val_int(0))
5381 Store_field(current
, 1, next
);
5388 curl_slist_free_all(slist
);
5393 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5395 CAMLparam2(conn
, option
);
5397 CURLcode curlResult
;
5398 Connection
*connection
= Connection_val(conn
);
5399 enum GetInfoResultType resultType
;
5400 char *strValue
= NULL
;
5403 struct curl_slist
*stringListValue
= NULL
;
5405 checkConnection(connection
);
5407 switch(Long_val(option
))
5409 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5410 case 0: /* CURLINFO_EFFECTIVE_URL */
5411 resultType
= StringValue
;
5413 curlResult
= curl_easy_getinfo(connection
->connection
,
5414 CURLINFO_EFFECTIVE_URL
,
5418 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5421 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5422 case 1: /* CURLINFO_HTTP_CODE */
5423 case 2: /* CURLINFO_RESPONSE_CODE */
5424 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5425 resultType
= LongValue
;
5427 curlResult
= curl_easy_getinfo(connection
->connection
,
5428 CURLINFO_RESPONSE_CODE
,
5431 resultType
= LongValue
;
5433 curlResult
= curl_easy_getinfo(connection
->connection
,
5440 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5441 case 3: /* CURLINFO_TOTAL_TIME */
5442 resultType
= DoubleValue
;
5444 curlResult
= curl_easy_getinfo(connection
->connection
,
5445 CURLINFO_TOTAL_TIME
,
5450 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5451 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5452 resultType
= DoubleValue
;
5454 curlResult
= curl_easy_getinfo(connection
->connection
,
5455 CURLINFO_NAMELOOKUP_TIME
,
5460 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5461 case 5: /* CURLINFO_CONNECT_TIME */
5462 resultType
= DoubleValue
;
5464 curlResult
= curl_easy_getinfo(connection
->connection
,
5465 CURLINFO_CONNECT_TIME
,
5470 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5471 case 6: /* CURLINFO_PRETRANSFER_TIME */
5472 resultType
= DoubleValue
;
5474 curlResult
= curl_easy_getinfo(connection
->connection
,
5475 CURLINFO_PRETRANSFER_TIME
,
5480 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5481 case 7: /* CURLINFO_SIZE_UPLOAD */
5482 resultType
= DoubleValue
;
5484 curlResult
= curl_easy_getinfo(connection
->connection
,
5485 CURLINFO_SIZE_UPLOAD
,
5490 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5491 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5492 resultType
= DoubleValue
;
5494 curlResult
= curl_easy_getinfo(connection
->connection
,
5495 CURLINFO_SIZE_DOWNLOAD
,
5500 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5501 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5502 resultType
= DoubleValue
;
5504 curlResult
= curl_easy_getinfo(connection
->connection
,
5505 CURLINFO_SPEED_DOWNLOAD
,
5510 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5511 case 10: /* CURLINFO_SPEED_UPLOAD */
5512 resultType
= DoubleValue
;
5514 curlResult
= curl_easy_getinfo(connection
->connection
,
5515 CURLINFO_SPEED_UPLOAD
,
5521 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5522 case 11: /* CURLINFO_HEADER_SIZE */
5523 resultType
= LongValue
;
5525 curlResult
= curl_easy_getinfo(connection
->connection
,
5526 CURLINFO_HEADER_SIZE
,
5531 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5532 case 12: /* CURLINFO_REQUEST_SIZE */
5533 resultType
= LongValue
;
5535 curlResult
= curl_easy_getinfo(connection
->connection
,
5536 CURLINFO_REQUEST_SIZE
,
5541 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5542 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5543 resultType
= LongValue
;
5545 curlResult
= curl_easy_getinfo(connection
->connection
,
5546 CURLINFO_SSL_VERIFYRESULT
,
5551 #if HAVE_DECL_CURLINFO_FILETIME
5552 case 14: /* CURLINFO_FILETIME */
5553 resultType
= DoubleValue
;
5555 curlResult
= curl_easy_getinfo(connection
->connection
,
5559 doubleValue
= longValue
;
5563 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5564 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5565 resultType
= DoubleValue
;
5567 curlResult
= curl_easy_getinfo(connection
->connection
,
5568 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5573 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5574 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5575 resultType
= DoubleValue
;
5577 curlResult
= curl_easy_getinfo(connection
->connection
,
5578 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5583 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5584 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5585 resultType
= DoubleValue
;
5587 curlResult
= curl_easy_getinfo(connection
->connection
,
5588 CURLINFO_STARTTRANSFER_TIME
,
5593 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5594 case 18: /* CURLINFO_CONTENT_TYPE */
5595 resultType
= StringValue
;
5597 curlResult
= curl_easy_getinfo(connection
->connection
,
5598 CURLINFO_CONTENT_TYPE
,
5603 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5604 case 19: /* CURLINFO_REDIRECT_TIME */
5605 resultType
= DoubleValue
;
5607 curlResult
= curl_easy_getinfo(connection
->connection
,
5608 CURLINFO_REDIRECT_TIME
,
5613 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5614 case 20: /* CURLINFO_REDIRECT_COUNT */
5615 resultType
= LongValue
;
5617 curlResult
= curl_easy_getinfo(connection
->connection
,
5618 CURLINFO_REDIRECT_COUNT
,
5623 #if HAVE_DECL_CURLINFO_PRIVATE
5624 case 21: /* CURLINFO_PRIVATE */
5625 resultType
= StringValue
;
5627 curlResult
= curl_easy_getinfo(connection
->connection
,
5633 #if HAVE_DECL_CURLINFO_HTTP_CONNECTCODE
5634 case 22: /* CURLINFO_HTTP_CONNECTCODE */
5635 resultType
= LongValue
;
5637 curlResult
= curl_easy_getinfo(connection
->connection
,
5638 CURLINFO_HTTP_CONNECTCODE
,
5643 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5644 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5645 resultType
= LongValue
;
5647 curlResult
= curl_easy_getinfo(connection
->connection
,
5648 CURLINFO_HTTPAUTH_AVAIL
,
5653 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5654 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5655 resultType
= LongValue
;
5657 curlResult
= curl_easy_getinfo(connection
->connection
,
5658 CURLINFO_PROXYAUTH_AVAIL
,
5663 #if HAVE_DECL_CURLINFO_OS_ERRNO
5664 case 25: /* CURLINFO_OS_ERRNO */
5665 resultType
= LongValue
;
5667 curlResult
= curl_easy_getinfo(connection
->connection
,
5673 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5674 case 26: /* CURLINFO_NUM_CONNECTS */
5675 resultType
= LongValue
;
5677 curlResult
= curl_easy_getinfo(connection
->connection
,
5678 CURLINFO_NUM_CONNECTS
,
5683 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5684 case 27: /* CURLINFO_SSL_ENGINES */
5685 resultType
= StringListValue
;
5687 curlResult
= curl_easy_getinfo(connection
->connection
,
5688 CURLINFO_SSL_ENGINES
,
5693 #if HAVE_DECL_CURLINFO_COOKIELIST
5694 case 28: /* CURLINFO_COOKIELIST */
5695 resultType
= StringListValue
;
5697 curlResult
= curl_easy_getinfo(connection
->connection
,
5698 CURLINFO_COOKIELIST
,
5703 #if HAVE_DECL_CURLINFO_LASTSOCKET
5704 case 29: /* CURLINFO_LASTSOCKET */
5705 resultType
= LongValue
;
5707 curlResult
= curl_easy_getinfo(connection
->connection
,
5708 CURLINFO_LASTSOCKET
,
5713 #if HAVE_DECL_CURLINFO_FTP_ENTRY_PATH
5714 case 30: /* CURLINFO_FTP_ENTRY_PATH */
5715 resultType
= StringValue
;
5717 curlResult
= curl_easy_getinfo(connection
->connection
,
5718 CURLINFO_FTP_ENTRY_PATH
,
5723 #if HAVE_DECL_CURLINFO_REDIRECT_URL
5724 case 31: /* CURLINFO_REDIRECT_URL */
5725 resultType
= StringValue
;
5727 curlResult
= curl_easy_getinfo(connection
->connection
,
5728 CURLINFO_REDIRECT_URL
,
5732 #warning "libcurl does not provide CURLINFO_REDIRECT_URL"
5735 #if HAVE_DECL_CURLINFO_PRIMARY_IP
5736 case 32: /* CURLINFO_PRIMARY_IP */
5737 resultType
= StringValue
;
5739 curlResult
= curl_easy_getinfo(connection
->connection
,
5740 CURLINFO_PRIMARY_IP
,
5744 #warning "libcurl does not provide CURLINFO_PRIMARY_IP"
5748 failwith("Invalid CURLINFO Option");
5752 if (curlResult
!= CURLE_OK
)
5753 raiseError(connection
, curlResult
);
5758 result
= alloc(1, StringValue
);
5759 Store_field(result
, 0, copy_string(strValue
?strValue
:""));
5763 result
= alloc(1, LongValue
);
5764 Store_field(result
, 0, Val_long(longValue
));
5768 result
= alloc(1, DoubleValue
);
5769 Store_field(result
, 0, copy_double(doubleValue
));
5772 case StringListValue
:
5773 result
= alloc(1, StringListValue
);
5774 Store_field(result
, 0, convertStringList(stringListValue
));
5782 ** curl_escape helper function
5785 CAMLprim value
helper_curl_escape(value str
)
5791 curlResult
= curl_escape(String_val(str
), string_length(str
));
5792 result
= copy_string(curlResult
);
5799 ** curl_unescape helper function
5802 CAMLprim value
helper_curl_unescape(value str
)
5808 curlResult
= curl_unescape(String_val(str
), string_length(str
));
5809 result
= copy_string(curlResult
);
5816 ** curl_getdate helper function
5819 CAMLprim value
helper_curl_getdate(value str
, value now
)
5821 CAMLparam2(str
, now
);
5826 curlNow
= (time_t)Double_val(now
);
5827 curlResult
= curl_getdate(String_val(str
), &curlNow
);
5828 result
= copy_double((double)curlResult
);
5834 ** curl_version helper function
5837 CAMLprim value
helper_curl_version(void)
5843 str
= curl_version();
5844 result
= copy_string(str
);
5849 CAMLprim value
caml_curl_version_info(value unit
)
5852 CAMLlocal3(v
, vlist
, vnum
);
5853 const char* const* p
= NULL
;
5855 curl_version_info_data
* data
= curl_version_info(CURLVERSION_NOW
);
5856 if (NULL
== data
) caml_failwith("curl_version_info");
5858 vlist
= Val_emptylist
;
5859 for (p
= data
->protocols
; NULL
!= *p
; p
++)
5861 vlist
= Val_cons(vlist
, caml_copy_string(*p
));
5864 vnum
= caml_alloc_tuple(3);
5865 Store_field(vnum
,0,Val_int(0xFF & (data
->version_num
>> 16)));
5866 Store_field(vnum
,1,Val_int(0xFF & (data
->version_num
>> 8)));
5867 Store_field(vnum
,2,Val_int(0xFF & (data
->version_num
)));
5869 v
= caml_alloc_tuple(7);
5870 Store_field(v
,0,caml_copy_string(data
->version
));
5871 Store_field(v
,1,vnum
);
5872 Store_field(v
,2,caml_copy_string(data
->host
));
5873 Store_field(v
,3,Val_int(data
->features
));
5874 Store_field(v
,4,data
->ssl_version
? Val_some(caml_copy_string(data
->ssl_version
)) : Val_none
);
5875 Store_field(v
,5,data
->libz_version
? Val_some(caml_copy_string(data
->libz_version
)) : Val_none
);
5876 Store_field(v
,6,vlist
);
5882 * Curl multi stack support
5884 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5885 * Other exported functions are prefixed with caml_curlm_, some of them
5886 * can/should be decomposed into smaller parts.
5889 struct ml_multi_handle
5892 value values
; /* callbacks */
5897 curlmopt_socket_function
,
5899 /* last, not used */
5903 typedef struct ml_multi_handle ml_multi_handle
;
5905 #define Multi_val(v) (*(ml_multi_handle**)Data_custom_val(v))
5906 #define CURLM_val(v) (Multi_val(v)->handle)
5908 static struct custom_operations curl_multi_ops
= {
5910 custom_finalize_default
,
5911 custom_compare_default
,
5912 custom_hash_default
,
5913 custom_serialize_default
,
5914 custom_deserialize_default
5917 CAMLprim value
caml_curl_multi_init(value unit
)
5921 ml_multi_handle
* multi
= (ml_multi_handle
*)caml_stat_alloc(sizeof(ml_multi_handle
));
5922 CURLM
* h
= curl_multi_init();
5926 caml_stat_free(multi
);
5927 failwith("caml_curl_multi_init");
5931 multi
->values
= caml_alloc(multi_values_total
, 0);
5932 caml_register_generational_global_root(&multi
->values
);
5934 v
= caml_alloc_custom(&curl_multi_ops
, sizeof(ml_multi_handle
*), 0, 1);
5935 Multi_val(v
) = multi
;
5940 CAMLprim value
caml_curl_multi_cleanup(value handle
)
5943 ml_multi_handle
* h
= Multi_val(handle
);
5946 CAMLreturn(Val_unit
);
5948 caml_remove_generational_global_root(&h
->values
);
5950 if (CURLM_OK
!= curl_multi_cleanup(h
->handle
))
5951 failwith("caml_curl_multi_cleanup");
5953 Multi_val(handle
) = (ml_multi_handle
*)NULL
;
5955 CAMLreturn(Val_unit
);
5958 static CURL
* curlm_remove_finished(CURLM
* multi_handle
, CURLcode
* result
)
5960 int msgs_in_queue
= 0;
5964 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
5965 if (NULL
== msg
) return NULL
;
5966 if (CURLMSG_DONE
== msg
->msg
)
5968 CURL
* easy_handle
= msg
->easy_handle
;
5969 if (result
) *result
= msg
->data
.result
;
5970 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
5972 //failwith("curlm_remove_finished");
5979 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
5981 CAMLparam1(v_multi
);
5982 CAMLlocal2(v_easy
, v_tuple
);
5984 CURLM
* multi_handle
;
5987 multi_handle
= CURLM_val(v_multi
);
5989 caml_enter_blocking_section();
5990 handle
= curlm_remove_finished(multi_handle
,&result
);
5991 caml_leave_blocking_section();
5995 CAMLreturn(Val_none
);
5999 /* not good: same handle, but different block */
6000 v_easy
= caml_alloc(1, Abstract_tag
);
6001 Field(v_easy
, 0) = (value
)findConnection(handle
);
6002 v_tuple
= caml_alloc(2, 0);
6003 Store_field(v_tuple
,0,v_easy
);
6004 Store_field(v_tuple
,1,Val_int(result
)); /* CURLcode */
6005 CAMLreturn(Val_some(v_tuple
));
6009 static int curlm_wait_data(CURLM
* multi_handle
)
6011 struct timeval timeout
;
6023 /* set a suitable timeout */
6025 timeout
.tv_usec
= 0;
6027 /* get file descriptors from the transfers */
6028 ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
6030 if (ret
== CURLM_OK
&& maxfd
>= 0)
6032 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
6033 if (-1 != rc
) return 0;
6034 //printf("select error\n");
6038 //printf("curl_multi_fdset error\n");
6043 CAMLprim value
caml_curlm_wait_data(value v_multi
)
6045 CAMLparam1(v_multi
);
6049 h
= CURLM_val(v_multi
);
6051 caml_enter_blocking_section();
6052 ret
= curlm_wait_data(h
);
6053 caml_leave_blocking_section();
6055 CAMLreturn(Val_bool(0 == ret
));
6058 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
6060 CAMLparam2(v_multi
,v_easy
);
6062 if (CURLM_OK
!= curl_multi_add_handle(CURLM_val(v_multi
), Connection_val(v_easy
)->connection
))
6063 failwith("caml_curl_multi_add_handle");
6065 CAMLreturn(Val_unit
);
6068 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
6070 CAMLparam1(v_multi
);
6072 int still_running
= 0;
6074 h
= CURLM_val(v_multi
);
6076 caml_enter_blocking_section();
6077 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
6078 caml_leave_blocking_section();
6080 CAMLreturn(Val_int(still_running
));
6083 CAMLprim value
helper_curl_easy_strerror(value v_code
)
6086 CAMLreturn(caml_copy_string(curl_easy_strerror(Int_val(v_code
))));