4 *** Copyright (c) 2003-2008, Lars Nilsson, <lars@quantumchamaeleon.com>
11 #include <curl/curl.h>
13 #include <caml/alloc.h>
14 #include <caml/memory.h>
15 #include <caml/mlvalues.h>
16 #include <caml/callback.h>
17 #include <caml/fail.h>
18 #include <caml/custom.h>
23 #warning "No config file given."
26 void leave_blocking_section(void);
27 void enter_blocking_section(void);
29 #define Val_none Val_int(0)
36 some
= caml_alloc(1, 0);
37 Store_field( some
, 0, v
);
41 typedef struct Connection Connection
;
42 typedef struct ConnectionList ConnectionList
;
44 #define Connection_val(v) ((Connection *)Field(v, 0))
57 OcamlProgressCallback
,
61 OcamlSeekFunctionCallback
,
93 OcamlFTPAlternativeToUser
,
94 OcamlSSHPublicKeyFile
,
95 OcamlSSHPrivateKeyFile
,
96 OcamlSSHHostPublicKeyMD5
,
99 /* Not used, last for size */
123 struct curl_slist
*httpHeader
;
124 struct curl_httppost
*httpPostFirst
;
125 struct curl_httppost
*httpPostLast
;
126 struct curl_slist
*httpPostStrings
;
134 struct curl_slist
*quote
;
135 struct curl_slist
*postQuote
;
146 struct curl_slist
*http200Aliases
;
150 char *ftpAlternativeToUser
;
151 char *sshPublicKeyFile
;
152 char *sshPrivateKeyFile
;
153 char *sshHostPublicKeyMD5
;
154 char *copyPostFields
;
157 struct ConnectionList
163 static ConnectionList connectionList
= {NULL
, NULL
};
165 typedef struct CURLErrorMapping CURLErrorMapping
;
167 struct CURLErrorMapping
173 CURLErrorMapping errorMap
[] =
175 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
176 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL
},
178 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
180 #if HAVE_DECL_CURLE_FAILED_INIT
181 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT
},
183 {"CURLE_FAILED_INIT", -1},
185 #if HAVE_DECL_CURLE_URL_MALFORMAT
186 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT
},
188 {"CURLE_URL_MALFORMAT", -1},
190 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
191 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER
},
193 {"CURLE_URL_MALFORMAT_USER", -1},
195 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
196 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY
},
198 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
200 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
201 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST
},
203 {"CURLE_COULDNT_RESOLVE_HOST", -1},
205 #if HAVE_DECL_CURLE_COULDNT_CONNECT
206 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT
},
208 {"CURLE_COULDNT_CONNECT", -1},
210 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
211 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY
},
213 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
215 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
216 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED
},
218 {"CURLE_FTP_ACCESS_DENIED", -1},
220 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
221 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT
},
223 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
225 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
226 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY
},
228 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
230 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
231 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY
},
233 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
235 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
236 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY
},
238 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
240 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
241 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT
},
243 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
245 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
246 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST
},
248 {"CURLE_FTP_CANT_GET_HOST", -1},
250 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
251 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT
},
253 {"CURLE_FTP_CANT_RECONNECT", -1},
255 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
256 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY
},
258 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
260 #if HAVE_DECL_CURLE_PARTIAL_FILE
261 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE
},
263 {"CURLE_PARTIAL_FILE", -1},
265 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
266 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE
},
268 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
270 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
271 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR
},
273 {"CURLE_FTP_WRITE_ERROR", -1},
275 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
276 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR
},
278 {"CURLE_FTP_QUOTE_ERROR", -1},
280 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
281 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND
},
283 {"CURLE_HTTP_NOT_FOUND", -1},
285 #if HAVE_DECL_CURLE_WRITE_ERROR
286 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR
},
288 {"CURLE_WRITE_ERROR", -1},
290 #if HAVE_DECL_CURLE_MALFORMAT_USER
291 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER
},
293 {"CURLE_MALFORMAT_USER", -1},
295 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
296 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE
},
298 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
300 #if HAVE_DECL_CURLE_READ_ERROR
301 {"CURLE_READ_ERROR", CURLE_READ_ERROR
},
303 {"CURLE_READ_ERROR", -1},
305 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
306 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY
},
308 {"CURLE_OUT_OF_MEMORY", -1},
310 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
311 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED
},
313 {"CURLE_OPERATION_TIMEOUTED", -1},
315 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
316 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII
},
318 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
320 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
321 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED
},
323 {"CURLE_FTP_PORT_FAILED", -1},
325 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
326 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST
},
328 {"CURLE_FTP_COULDNT_USE_REST", -1},
330 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
331 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE
},
333 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
335 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
336 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR
},
338 {"CURLE_HTTP_RANGE_ERROR", -1},
340 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
341 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR
},
343 {"CURLE_HTTP_POST_ERROR", -1},
345 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
346 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR
},
348 {"CURLE_SSL_CONNECT_ERROR", -1},
350 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
351 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME
},
353 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
355 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
356 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE
},
358 {"CURLE_FILE_COULDNT_READ_FILE", -1},
360 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
361 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND
},
363 {"CURLE_LDAP_CANNOT_BIND", -1},
365 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
366 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED
},
368 {"CURLE_LDAP_SEARCH_FAILED", -1},
370 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
371 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND
},
373 {"CURLE_LIBRARY_NOT_FOUND", -1},
375 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
376 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND
},
378 {"CURLE_FUNCTION_NOT_FOUND", -1},
380 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
381 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK
},
383 {"CURLE_ABORTED_BY_CALLBACK", -1},
385 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
386 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT
},
388 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
390 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
391 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER
},
393 {"CURLE_BAD_CALLING_ORDER", -1},
395 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
396 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED
},
398 {"CURLE_HTTP_PORT_FAILED", -1},
400 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
401 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED
},
403 {"CURLE_BAD_PASSWORD_ENTERED", -1},
405 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
406 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS
},
408 {"CURLE_TOO_MANY_REDIRECTS", -1},
410 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
411 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION
},
413 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
415 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
416 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX
},
418 {"CURLE_TELNET_OPTION_SYNTAX", -1},
420 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
421 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE
},
423 {"CURLE_SSL_PEER_CERTIFICATE", -1},
425 #if HAVE_DECL_CURLE_GOT_NOTHING
426 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING
},
428 {"CURLE_GOT_NOTHING", -1},
430 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
431 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND
},
433 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
435 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
436 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED
},
438 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
440 #if HAVE_DECL_CURLE_SEND_ERROR
441 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR
},
443 {"CURLE_SEND_ERROR", -1},
445 #if HAVE_DECL_CURLE_RECV_ERROR
446 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR
},
448 {"CURLE_RECV_ERROR", -1},
450 #if HAVE_DECL_CURLE_SHARE_IN_USE
451 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE
},
453 {"CURLE_SHARE_IN_USE", -1},
455 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
456 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM
},
458 {"CURLE_SSL_CERTPROBLEN", -1},
460 #if HAVE_DECL_CURLE_SSL_CIPHER
461 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER
},
463 {"CURLE_SSL_CIPHER", -1},
465 #if HAVE_DECL_CURLE_SSL_CACERT
466 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT
},
468 {"CURLE_SSL_CACERT", -1},
470 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
471 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING
},
473 {"CURLE_BAD_CONTENT_ENCODING", -1},
475 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
476 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL
},
478 {"CURLE_LDAP_INVALID_URL", -1},
480 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
481 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED
},
483 {"CURLE_FILESIZE_EXCEEDED", -1},
485 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
486 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED
},
488 {"CURLE_FTP_SSL_FAILED", -1},
490 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
491 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND
},
493 {"CURLE_SEND_FAIL_REWIND", -1},
495 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
496 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED
},
498 {"CURLE_SSL_ENGINE_INITFAILED", -1},
500 #if HAVE_DECL_CURLE_LOGIN_DENIED
501 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED
},
503 {"CURLE_LOGIN_DENIED", -1},
505 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
506 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND
},
508 {"CURLE_TFTP_NOTFOUND", -1},
510 #if HAVE_DECL_CURLE_TFTP_PERM
511 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM
},
513 {"CURLE_TFTP_PERM", -1},
515 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
516 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL
},
518 {"CURLE_REMOTE_DISK_FULL", -1},
520 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
521 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL
},
523 {"CURLE_TFTP_ILLEGAL", -1},
525 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
526 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID
},
528 {"CURLE_TFTP_UNKNOWNID", -1},
530 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
531 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS
},
533 {"CURLE_REMOTE_FILE_EXISTS", -1},
535 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
536 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER
},
538 {"CURLE_TFTP_NOSUCHUSER", -1},
540 #if HAVE_DECL_CURLE_CONV_FAILED
541 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED
},
543 {"CURLE_CONV_FAILED", -1},
545 #if HAVE_DECL_CURLE_CONV_REQUIRED
546 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED
},
548 {"CURLE_CONV_REQUIRED", -1},
550 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
551 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE
},
553 {"CURLE_SSL_CACERT_BADFILE", -1},
555 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
556 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND
},
558 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
560 #if HAVE_DECL_CURLE_SSH
561 {"CURLE_SSH", CURLE_SSH
},
565 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
566 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED
},
568 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
570 #if HAVE_DECL_CURLE_AGAIN
571 {"CURLE_AGAIN", CURLE_AGAIN
},
575 {"CURLE_OK", CURLE_OK
},
579 typedef struct CURLOptionMapping CURLOptionMapping
;
581 struct CURLOptionMapping
583 void (*optionHandler
)(Connection
*, value
);
588 CURLOptionMapping unimplementedOptionMap
[] =
590 {NULL
, "CURLOPT_STDERR", CURLOPT_STDERR
},
594 static void handleWriteFunction(Connection
*, value
);
595 static void handleReadFunction(Connection
*, value
);
596 static void handleInFileSize(Connection
*, value
);
597 static void handleURL(Connection
*, value
);
598 static void handleProxy(Connection
*, value
);
599 static void handleProxyPort(Connection
*, value
);
600 static void handleHTTPProxyTunnel(Connection
*, value
);
601 static void handleVerbose(Connection
*, value
);
602 static void handleHeader(Connection
*, value
);
603 static void handleNoProgress(Connection
*, value
);
604 static void handleNoSignal(Connection
*, value
);
605 static void handleNoBody(Connection
*, value
);
606 static void handleFailOnError(Connection
*, value
);
607 static void handleUpload(Connection
*, value
);
608 static void handlePost(Connection
*, value
);
609 static void handleFTPListOnly(Connection
*, value
);
610 static void handleFTPAppend(Connection
*, value
);
611 static void handleNETRC(Connection
*, value
);
612 static void handleEncoding(Connection
*, value
);
613 static void handleFollowLocation(Connection
*, value
);
614 static void handleTransferText(Connection
*, value
);
615 static void handlePut(Connection
*, value
);
616 static void handleUserPwd(Connection
*, value
);
617 static void handleProxyUserPwd(Connection
*, value
);
618 static void handleRange(Connection
*, value
);
619 static void handleErrorBuffer(Connection
*, value
);
620 static void handleTimeout(Connection
*, value
);
621 static void handlePostFields(Connection
*, value
);
622 static void handlePostFieldSize(Connection
*, value
);
623 static void handleReferer(Connection
*, value
);
624 static void handleUserAgent(Connection
*, value
);
625 static void handleFTPPort(Connection
*, value
);
626 static void handleLowSpeedLimit(Connection
*, value
);
627 static void handleLowSpeedTime(Connection
*, value
);
628 static void handleResumeFrom(Connection
*, value
);
629 static void handleCookie(Connection
*, value
);
630 static void handleHTTPHeader(Connection
*, value
);
631 static void handleHTTPPost(Connection
*, value
);
632 static void handleSSLCert(Connection
*, value
);
633 static void handleSSLCertType(Connection
*, value
);
634 static void handleSSLCertPasswd(Connection
*, value
);
635 static void handleSSLKey(Connection
*, value
);
636 static void handleSSLKeyType(Connection
*, value
);
637 static void handleSSLKeyPasswd(Connection
*, value
);
638 static void handleSSLEngine(Connection
*, value
);
639 static void handleSSLEngineDefault(Connection
*, value
);
640 static void handleCRLF(Connection
*, value
);
641 static void handleQuote(Connection
*, value
);
642 static void handlePostQuote(Connection
*, value
);
643 static void handleHeaderFunction(Connection
*, value
);
644 static void handleCookieFile(Connection
*, value
);
645 static void handleSSLVersion(Connection
*, value
);
646 static void handleTimeCondition(Connection
*, value
);
647 static void handleTimeValue(Connection
*, value
);
648 static void handleCustomRequest(Connection
*, value
);
649 static void handleInterface(Connection
*, value
);
650 static void handleKRB4Level(Connection
*, value
);
651 static void handleProgressFunction(Connection
*, value
);
652 static void handleSSLVerifyPeer(Connection
*, value
);
653 static void handleCAInfo(Connection
*, value
);
654 static void handleCAPath(Connection
*, value
);
655 static void handleFileTime(Connection
*, value
);
656 static void handleMaxRedirs(Connection
*, value
);
657 static void handleMaxConnects(Connection
*, value
);
658 static void handleClosePolicy(Connection
*, value
);
659 static void handleFreshConnect(Connection
*, value
);
660 static void handleForbidReuse(Connection
*, value
);
661 static void handleRandomFile(Connection
*, value
);
662 static void handleEGDSocket(Connection
*, value
);
663 static void handleConnectTimeout(Connection
*, value
);
664 static void handleHTTPGet(Connection
*, value
);
665 static void handleSSLVerifyHost(Connection
*, value
);
666 static void handleCookieJar(Connection
*, value
);
667 static void handleSSLCipherList(Connection
*, value
);
668 static void handleHTTPVersion(Connection
*, value
);
669 static void handleFTPUseEPSV(Connection
*, value
);
670 static void handleDNSCacheTimeout(Connection
*, value
);
671 static void handleDNSUseGlobalCache(Connection
*, value
);
672 static void handleDebugFunction(Connection
*, value
);
673 static void handlePrivate(Connection
*, value
);
674 static void handleHTTP200Aliases(Connection
*, value
);
675 static void handleUnrestrictedAuth(Connection
*, value
);
676 static void handleFTPUseEPRT(Connection
*, value
);
677 static void handleHTTPAuth(Connection
*, value
);
678 static void handleFTPCreateMissingDirs(Connection
*, value
);
679 static void handleProxyAuth(Connection
*, value
);
680 static void handleFTPResponseTimeout(Connection
*, value
);
681 static void handleIPResolve(Connection
*, value
);
682 static void handleMaxFileSize(Connection
*, value
);
683 static void handleInFileSizeLarge(Connection
*, value
);
684 static void handleResumeFromLarge(Connection
*, value
);
685 static void handleMaxFileSizeLarge(Connection
*, value
);
686 static void handleNETRCFile(Connection
*, value
);
687 static void handleFTPSSL(Connection
*, value
);
688 static void handlePostFieldSizeLarge(Connection
*, value
);
689 static void handleTCPNoDelay(Connection
*, value
);
690 static void handleFTPSSLAuth(Connection
*, value
);
691 static void handleIOCTLFunction(Connection
*, value
);
692 static void handleFTPAccount(Connection
*, value
);
693 static void handleCookieList(Connection
*, value
);
694 static void handleIgnoreContentLength(Connection
*, value
);
695 static void handleFTPSkipPASVIP(Connection
*, value
);
696 static void handleFTPFileMethod(Connection
*, value
);
697 static void handleLocalPort(Connection
*, value
);
698 static void handleLocalPortRange(Connection
*, value
);
699 static void handleConnectOnly(Connection
*, value
);
700 static void handleMaxSendSpeedLarge(Connection
*, value
);
701 static void handleMaxRecvSpeedLarge(Connection
*, value
);
702 static void handleFTPAlternativeToUser(Connection
*, value
);
703 static void handleSSLSessionIdCache(Connection
*, value
);
704 static void handleSSHAuthTypes(Connection
*, value
);
705 static void handleSSHPublicKeyFile(Connection
*, value
);
706 static void handleSSHPrivateKeyFile(Connection
*, value
);
707 static void handleFTPSSLCCC(Connection
*, value
);
708 static void handleTimeoutMS(Connection
*, value
);
709 static void handleConnectTimeoutMS(Connection
*, value
);
710 static void handleHTTPTransferDecoding(Connection
*, value
);
711 static void handleHTTPContentDecoding(Connection
*, value
);
712 static void handleNewFilePerms(Connection
*, value
);
713 static void handleNewDirectoryPerms(Connection
*, value
);
714 static void handlePost301(Connection
*, value
);
715 static void handleSSHHostPublicKeyMD5(Connection
*, value
);
716 static void handleCopyPostFields(Connection
*, value
);
717 static void handleProxyTransferMode(Connection
*, value
);
718 static void handleSeekFunction(Connection
*, value
);
720 CURLOptionMapping implementedOptionMap
[] =
722 {handleWriteFunction
, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION
},
723 {handleReadFunction
, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION
},
724 {handleInFileSize
, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE
},
725 {handleURL
, "CURLOPT_URL", CURLOPT_URL
},
726 {handleProxy
, "CURLOPT_PROXY", CURLOPT_PROXY
},
727 {handleProxyPort
, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT
},
728 {handleHTTPProxyTunnel
, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL
},
729 {handleVerbose
, "CURLOPT_VERBOSE", CURLOPT_VERBOSE
},
730 {handleHeader
, "CURLOPT_HEADER", CURLOPT_HEADER
},
731 {handleNoProgress
, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS
},
732 #if HAVE_DECL_CURLOPT_NOSIGNAL
733 {handleNoSignal
, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL
},
735 {handleNoSignal
, "CURLOPT_NOSIGNAL", 0},
737 {handleNoBody
, "CURLOPT_NOBODY", CURLOPT_NOBODY
},
738 {handleFailOnError
, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR
},
739 {handleUpload
, "CURLOPT_UPLOAD", CURLOPT_UPLOAD
},
740 {handlePost
, "CURLOPT_POST", CURLOPT_POST
},
741 {handleFTPListOnly
, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY
},
742 {handleFTPAppend
, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND
},
743 {handleNETRC
, "CURLOPT_NETRC", CURLOPT_NETRC
},
744 #if HAVE_DECL_CURLOPT_ENCODING
745 {handleEncoding
, "CURLOPT_ENCODING", CURLOPT_ENCODING
},
747 {handleEncoding
, "CURLOPT_ENCODING", 0},
749 {handleFollowLocation
, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION
},
750 {handleTransferText
, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT
},
751 {handlePut
, "CURLOPT_PUT", CURLOPT_PUT
},
752 {handleUserPwd
, "CURLOPT_USERPWD", CURLOPT_USERPWD
},
753 {handleProxyUserPwd
, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD
},
754 {handleRange
, "CURLOPT_RANGE", CURLOPT_RANGE
},
755 {handleErrorBuffer
, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER
},
756 {handleTimeout
, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT
},
757 {handlePostFields
, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS
},
758 {handlePostFieldSize
, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE
},
759 {handleReferer
, "CURLOPT_REFERER", CURLOPT_REFERER
},
760 {handleUserAgent
, "CURLOPT_USERAGENT", CURLOPT_USERAGENT
},
761 {handleFTPPort
, "CURLOPT_FTPPORT", CURLOPT_FTPPORT
},
762 {handleLowSpeedLimit
, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT
},
763 {handleLowSpeedTime
, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME
},
764 {handleResumeFrom
, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM
},
765 {handleCookie
, "CURLOPT_COOKIE", CURLOPT_COOKIE
},
766 {handleHTTPHeader
, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER
},
767 {handleHTTPPost
, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST
},
768 {handleSSLCert
, "CURLOPT_SSLCERT", CURLOPT_SSLCERT
},
769 {handleSSLCertType
, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE
},
770 {handleSSLCertPasswd
, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD
},
771 {handleSSLKey
, "CURLOPT_SSLKEY", CURLOPT_SSLKEY
},
772 {handleSSLKeyType
, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE
},
773 {handleSSLKeyPasswd
, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD
},
774 {handleSSLEngine
, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE
},
775 {handleSSLEngineDefault
, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT
},
776 {handleCRLF
, "CURLOPT_CRLF", CURLOPT_CRLF
},
777 {handleQuote
, "CURLOPT_QUOTE", CURLOPT_QUOTE
},
778 {handlePostQuote
, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE
},
779 {handleHeaderFunction
, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION
},
780 {handleCookieFile
, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE
},
781 {handleSSLVersion
, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION
},
782 {handleTimeCondition
, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION
},
783 {handleTimeValue
, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE
},
784 {handleCustomRequest
, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST
},
785 {handleInterface
, "CURLOPT_INTERFACE", CURLOPT_INTERFACE
},
786 {handleKRB4Level
, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL
},
787 {handleProgressFunction
, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION
},
788 {handleSSLVerifyPeer
, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER
},
789 {handleCAInfo
, "CURLOPT_CAINFO", CURLOPT_CAINFO
},
790 {handleCAPath
, "CURLOPT_CAPATH", CURLOPT_CAPATH
},
791 {handleFileTime
, "CURLOPT_FILETIME", CURLOPT_FILETIME
},
792 {handleMaxRedirs
, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS
},
793 {handleMaxConnects
, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS
},
794 {handleClosePolicy
, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY
},
795 {handleFreshConnect
, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT
},
796 {handleForbidReuse
, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE
},
797 {handleRandomFile
, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE
},
798 {handleEGDSocket
, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET
},
799 {handleConnectTimeout
, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT
},
800 {handleHTTPGet
, "CURLOPT_HTTPGET", CURLOPT_HTTPGET
},
801 {handleSSLVerifyHost
, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST
},
802 {handleCookieJar
, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR
},
803 {handleSSLCipherList
, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST
},
804 {handleHTTPVersion
, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION
},
805 {handleFTPUseEPSV
, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV
},
806 {handleDNSCacheTimeout
, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT
},
807 {handleDNSUseGlobalCache
, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE
},
808 {handleDebugFunction
, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION
},
809 #if HAVE_DECL_CURLOPT_PRIVATE
810 {handlePrivate
, "CURLOPT_PRIVATE", CURLOPT_PRIVATE
},
812 {handlePrivate
, "CURLOPT_PRIVATE", 0},
814 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
815 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES
},
817 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", 0},
819 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
820 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH
},
822 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", 0},
824 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
825 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT
},
827 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", 0},
829 #if HAVE_DECL_CURLOPT_HTTPAUTH
830 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH
},
832 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", 0},
834 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
835 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS
},
837 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
839 #if HAVE_DECL_CURLOPT_PROXYAUTH
840 {handleProxyAuth
, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH
},
842 {handleProxyAuth
, "CURLOPT_PROXYAUTH", 0},
844 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
845 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT
},
847 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
849 #if HAVE_DECL_CURLOPT_IPRESOLVE
850 {handleIPResolve
, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE
},
852 {handleIPResolve
, "CURLOPT_IPRESOLVE", 0},
854 #if HAVE_DECL_CURLOPT_MAXFILESIZE
855 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE
},
857 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", 0},
859 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
860 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE
},
862 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", 0},
864 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
865 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE
},
867 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", 0},
869 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
870 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE
},
872 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", 0},
874 #if HAVE_DECL_CURLOPT_NETRC_FILE
875 {handleNETRCFile
, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE
},
877 {handleNETRCFile
, "CURLOPT_NETRC_FILE", 0},
879 #if HAVE_DECL_CURLOPT_FTP_SSL
880 {handleFTPSSL
, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL
},
882 {handleFTPSSL
, "CURLOPT_FTP_SSL", 0},
884 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
885 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE
},
887 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
889 #if HAVE_DECL_CURLOPT_TCP_NODELAY
890 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY
},
892 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", 0},
894 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
895 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH
},
897 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", 0},
899 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
900 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION
},
902 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", 0},
904 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
905 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT
},
907 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", 0},
909 #if HAVE_DECL_CURLOPT_COOKIELIST
910 {handleCookieList
, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST
},
912 {handleCookieList
, "CURLOPT_COOKIELIST", 0},
914 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
915 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH
},
917 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
919 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
920 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP
},
922 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", 0},
924 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
925 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD
},
927 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", 0},
929 #if HAVE_DECL_CURLOPT_LOCALPORT
930 {handleLocalPort
, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT
},
932 {handleLocalPort
, "CURLOPT_LOCALPORT", 0},
934 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
935 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE
},
937 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", 0},
939 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
940 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY
},
942 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", 0},
944 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
945 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE
},
947 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
949 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
950 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE
},
952 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
954 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
955 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER
},
957 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
959 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
960 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE
},
962 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", 0},
964 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
965 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES
},
967 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", 0},
969 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
970 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE
},
972 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
974 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
975 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE
},
977 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
979 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
980 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC
},
982 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", 0},
984 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
985 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS
},
987 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", 0},
989 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
990 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS
},
992 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", 0},
994 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
995 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING
},
997 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
999 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1000 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING
},
1002 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1004 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1005 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS
},
1007 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", 0},
1009 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1010 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS
},
1012 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1014 #if HAVE_DECL_CURLOPT_POST301
1015 {handlePost301
, "CURLOPT_POST301", CURLOPT_POST301
},
1017 {handlePost301
, "CURLOPT_POST301", 0},
1019 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1020 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
},
1022 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1024 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1025 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS
},
1027 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", 0},
1029 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1030 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE
},
1032 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1034 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1035 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION
},
1037 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", 0},
1041 static char *findOption(CURLOptionMapping optionMap
[],
1044 return optionMap
[option
].name
;
1047 static void free_curl_slist(struct curl_slist
*slist
)
1049 struct curl_slist
*item
;
1056 while (item
!= NULL
)
1063 curl_slist_free_all(slist
);
1066 static void raiseError(Connection
*conn
, CURLcode code
)
1069 CAMLlocal1(exceptionData
);
1071 char *errorString
= "Unknown Error";
1074 for (i
= 0; errorMap
[i
].name
!= NULL
; i
++)
1076 if (errorMap
[i
].error
== code
)
1078 errorString
= errorMap
[i
].name
;
1083 exceptionData
= alloc(3, 0);
1085 Field(exceptionData
, 0) = Val_int(code
);
1086 Field(exceptionData
, 1) = Val_int(code
);
1087 Field(exceptionData
, 2) = copy_string(errorString
);
1089 if (conn
!= NULL
&& conn
->errorBuffer
!= NULL
)
1091 Field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0) =
1092 copy_string(conn
->errorBuffer
);
1095 exception
= caml_named_value("CurlException");
1097 if (exception
== NULL
)
1098 failwith(errorString
);
1100 raise_with_arg(*exception
, exceptionData
);
1105 static void resetOcamlValues(Connection
* connection
)
1109 for (i
= 0; i
< OcamlValuesSize
; i
++)
1110 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1113 static Connection
*newConnection(void)
1115 Connection
*connection
;
1117 connection
= (Connection
*)malloc(sizeof(Connection
));
1119 enter_blocking_section();
1120 connection
->connection
= curl_easy_init();
1121 leave_blocking_section();
1123 connection
->next
= NULL
;
1124 connection
->prev
= NULL
;
1126 if (connectionList
.tail
== NULL
)
1128 connectionList
.tail
= connection
;
1129 connectionList
.head
= connection
;
1133 connection
->prev
= connectionList
.head
;
1134 connectionList
.head
->next
= connection
;
1135 connectionList
.head
= connection
;
1138 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1139 resetOcamlValues(connection
);
1140 register_global_root(&connection
->ocamlValues
);
1142 connection
->url
= NULL
;
1143 connection
->proxy
= NULL
;
1144 connection
->userPwd
= NULL
;
1145 connection
->proxyUserPwd
= NULL
;
1146 connection
->range
= NULL
;
1147 connection
->errorBuffer
= NULL
;
1148 connection
->postFields
= NULL
;
1149 connection
->postFieldSize
= -1;
1150 connection
->referer
= NULL
;
1151 connection
->userAgent
= NULL
;
1152 connection
->ftpPort
= NULL
;
1153 connection
->cookie
= NULL
;
1154 connection
->httpHeader
= NULL
;
1155 connection
->httpPostFirst
= NULL
;
1156 connection
->httpPostLast
= NULL
;
1157 connection
->httpPostStrings
= NULL
;
1158 connection
->sslCert
= NULL
;
1159 connection
->sslCertType
= NULL
;
1160 connection
->sslCertPasswd
= NULL
;
1161 connection
->sslKey
= NULL
;
1162 connection
->sslKeyType
= NULL
;
1163 connection
->sslKeyPasswd
= NULL
;
1164 connection
->sslEngine
= NULL
;
1165 connection
->quote
= NULL
;
1166 connection
->postQuote
= NULL
;
1167 connection
->cookieFile
= NULL
;
1168 connection
->customRequest
= NULL
;
1169 connection
->interface
= NULL
;
1170 connection
->caInfo
= NULL
;
1171 connection
->caPath
= NULL
;
1172 connection
->randomFile
= NULL
;
1173 connection
->egdSocket
= NULL
;
1174 connection
->cookieJar
= NULL
;
1175 connection
->sslCipherList
= NULL
;
1176 connection
->private = NULL
;
1177 connection
->http200Aliases
= NULL
;
1178 connection
->netrcFile
= NULL
;
1179 connection
->ftpaccount
= NULL
;
1180 connection
->cookielist
= NULL
;
1181 connection
->ftpAlternativeToUser
= NULL
;
1182 connection
->sshPublicKeyFile
= NULL
;
1183 connection
->sshPrivateKeyFile
= NULL
;
1184 connection
->copyPostFields
= NULL
;
1189 static Connection
*duplicateConnection(Connection
*original
)
1191 Connection
*connection
;
1193 connection
= (Connection
*)malloc(sizeof(Connection
));
1195 enter_blocking_section();
1196 connection
->connection
= curl_easy_duphandle(original
->connection
);
1197 leave_blocking_section();
1199 connection
->next
= NULL
;
1200 connection
->prev
= NULL
;
1202 if (connectionList
.tail
== NULL
)
1204 connectionList
.tail
= connection
;
1205 connectionList
.head
= connection
;
1209 connection
->prev
= connectionList
.head
;
1210 connectionList
.head
->next
= connection
;
1211 connectionList
.head
= connection
;
1214 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1215 resetOcamlValues(connection
);
1216 register_global_root(&connection
->ocamlValues
);
1218 Store_field(connection
->ocamlValues
, OcamlWriteCallback
,
1219 Field(original
->ocamlValues
, OcamlWriteCallback
));
1220 Store_field(connection
->ocamlValues
, OcamlReadCallback
,
1221 Field(original
->ocamlValues
, OcamlReadCallback
));
1222 Store_field(connection
->ocamlValues
, OcamlErrorBuffer
,
1223 Field(original
->ocamlValues
, OcamlErrorBuffer
));
1224 Store_field(connection
->ocamlValues
, OcamlPostFields
,
1225 Field(original
->ocamlValues
, OcamlPostFields
));
1226 Store_field(connection
->ocamlValues
, OcamlHTTPHeader
,
1227 Field(original
->ocamlValues
, OcamlHTTPHeader
));
1228 Store_field(connection
->ocamlValues
, OcamlQuote
,
1229 Field(original
->ocamlValues
, OcamlQuote
));
1230 Store_field(connection
->ocamlValues
, OcamlPostQuote
,
1231 Field(original
->ocamlValues
, OcamlPostQuote
));
1232 Store_field(connection
->ocamlValues
, OcamlHeaderCallback
,
1233 Field(original
->ocamlValues
, OcamlHeaderCallback
));
1234 Store_field(connection
->ocamlValues
, OcamlProgressCallback
,
1235 Field(original
->ocamlValues
, OcamlProgressCallback
));
1236 Store_field(connection
->ocamlValues
, OcamlDebugCallback
,
1237 Field(original
->ocamlValues
, OcamlDebugCallback
));
1238 Store_field(connection
->ocamlValues
, OcamlHTTP200Aliases
,
1239 Field(original
->ocamlValues
, OcamlHTTP200Aliases
));
1240 Store_field(connection
->ocamlValues
, OcamlIOCTLCallback
,
1241 Field(original
->ocamlValues
, OcamlIOCTLCallback
));
1242 Store_field(connection
->ocamlValues
, OcamlSeekFunctionCallback
,
1243 Field(original
->ocamlValues
, OcamlSeekFunctionCallback
));
1245 connection
->url
= NULL
;
1246 connection
->proxy
= NULL
;
1247 connection
->userPwd
= NULL
;
1248 connection
->proxyUserPwd
= NULL
;
1249 connection
->range
= NULL
;
1250 connection
->errorBuffer
= NULL
;
1251 connection
->postFields
= NULL
;
1252 connection
->postFieldSize
= -1;
1253 connection
->referer
= NULL
;
1254 connection
->userAgent
= NULL
;
1255 connection
->ftpPort
= NULL
;
1256 connection
->cookie
= NULL
;
1257 connection
->httpHeader
= NULL
;
1258 connection
->httpPostFirst
= NULL
;
1259 connection
->httpPostLast
= NULL
;
1260 connection
->httpPostStrings
= NULL
;
1261 connection
->sslCert
= NULL
;
1262 connection
->sslCertType
= NULL
;
1263 connection
->sslCertPasswd
= NULL
;
1264 connection
->sslKey
= NULL
;
1265 connection
->sslKeyType
= NULL
;
1266 connection
->sslKeyPasswd
= NULL
;
1267 connection
->sslEngine
= NULL
;
1268 connection
->quote
= NULL
;
1269 connection
->postQuote
= NULL
;
1270 connection
->cookieFile
= NULL
;
1271 connection
->customRequest
= NULL
;
1272 connection
->interface
= NULL
;
1273 connection
->caInfo
= NULL
;
1274 connection
->caPath
= NULL
;
1275 connection
->randomFile
= NULL
;
1276 connection
->egdSocket
= NULL
;
1277 connection
->cookieJar
= NULL
;
1278 connection
->sslCipherList
= NULL
;
1279 connection
->private = NULL
;
1280 connection
->http200Aliases
= NULL
;
1281 connection
->netrcFile
= NULL
;
1282 connection
->ftpaccount
= NULL
;
1283 connection
->cookielist
= NULL
;
1284 connection
->sshPublicKeyFile
= NULL
;
1285 connection
->sshPrivateKeyFile
= NULL
;
1286 connection
->copyPostFields
= NULL
;
1288 if (Field(original
->ocamlValues
, OcamlURL
) != Val_unit
)
1289 handleURL(connection
, Field(original
->ocamlValues
,
1291 if (Field(original
->ocamlValues
, OcamlProxy
) != Val_unit
)
1292 handleProxy(connection
, Field(original
->ocamlValues
,
1294 if (Field(original
->ocamlValues
, OcamlUserPWD
) != Val_unit
)
1295 handleUserPwd(connection
, Field(original
->ocamlValues
,
1297 if (Field(original
->ocamlValues
, OcamlProxyUserPWD
) != Val_unit
)
1298 handleProxyUserPwd(connection
, Field(original
->ocamlValues
,
1299 OcamlProxyUserPWD
));
1300 if (Field(original
->ocamlValues
, OcamlRange
) != Val_unit
)
1301 handleRange(connection
, Field(original
->ocamlValues
,
1303 if (Field(original
->ocamlValues
, OcamlErrorBuffer
) != Val_unit
)
1304 handleErrorBuffer(connection
, Field(original
->ocamlValues
,
1306 if (Field(original
->ocamlValues
, OcamlPostFields
) != Val_unit
)
1307 handlePostFields(connection
, Field(original
->ocamlValues
,
1309 if (Field(original
->ocamlValues
, OcamlReferer
) != Val_unit
)
1310 handleReferer(connection
, Field(original
->ocamlValues
,
1312 if (Field(original
->ocamlValues
, OcamlUserAgent
) != Val_unit
)
1313 handleUserAgent(connection
, Field(original
->ocamlValues
,
1315 if (Field(original
->ocamlValues
, OcamlFTPPort
) != Val_unit
)
1316 handleFTPPort(connection
, Field(original
->ocamlValues
,
1318 if (Field(original
->ocamlValues
, OcamlCookie
) != Val_unit
)
1319 handleCookie(connection
, Field(original
->ocamlValues
,
1321 if (Field(original
->ocamlValues
, OcamlHTTPHeader
) != Val_unit
)
1322 handleHTTPHeader(connection
, Field(original
->ocamlValues
,
1324 if (Field(original
->ocamlValues
, OcamlHTTPPost
) != Val_unit
)
1325 handleHTTPPost(connection
, Field(original
->ocamlValues
,
1327 if (Field(original
->ocamlValues
, OcamlSSLCert
) != Val_unit
)
1328 handleSSLCert(connection
, Field(original
->ocamlValues
,
1330 if (Field(original
->ocamlValues
, OcamlSSLCertType
) != Val_unit
)
1331 handleSSLCertType(connection
, Field(original
->ocamlValues
,
1333 if (Field(original
->ocamlValues
, OcamlSSLCertPasswd
) != Val_unit
)
1334 handleSSLCertPasswd(connection
, Field(original
->ocamlValues
,
1335 OcamlSSLCertPasswd
));
1336 if (Field(original
->ocamlValues
, OcamlSSLKey
) != Val_unit
)
1337 handleSSLKey(connection
, Field(original
->ocamlValues
,
1339 if (Field(original
->ocamlValues
, OcamlSSLKeyType
) != Val_unit
)
1340 handleSSLKeyType(connection
, Field(original
->ocamlValues
,
1342 if (Field(original
->ocamlValues
, OcamlSSLKeyPasswd
) != Val_unit
)
1343 handleSSLKeyPasswd(connection
, Field(original
->ocamlValues
,
1344 OcamlSSLKeyPasswd
));
1345 if (Field(original
->ocamlValues
, OcamlSSLEngine
) != Val_unit
)
1346 handleSSLEngine(connection
, Field(original
->ocamlValues
,
1348 if (Field(original
->ocamlValues
, OcamlQuote
) != Val_unit
)
1349 handleQuote(connection
, Field(original
->ocamlValues
,
1351 if (Field(original
->ocamlValues
, OcamlPostQuote
) != Val_unit
)
1352 handlePostQuote(connection
, Field(original
->ocamlValues
,
1354 if (Field(original
->ocamlValues
, OcamlCookieFile
) != Val_unit
)
1355 handleCookieFile(connection
, Field(original
->ocamlValues
,
1357 if (Field(original
->ocamlValues
, OcamlCustomRequest
) != Val_unit
)
1358 handleCustomRequest(connection
, Field(original
->ocamlValues
,
1359 OcamlCustomRequest
));
1360 if (Field(original
->ocamlValues
, OcamlInterface
) != Val_unit
)
1361 handleInterface(connection
, Field(original
->ocamlValues
,
1363 if (Field(original
->ocamlValues
, OcamlCAInfo
) != Val_unit
)
1364 handleCAInfo(connection
, Field(original
->ocamlValues
,
1366 if (Field(original
->ocamlValues
, OcamlCAPath
) != Val_unit
)
1367 handleCAPath(connection
, Field(original
->ocamlValues
,
1369 if (Field(original
->ocamlValues
, OcamlRandomFile
) != Val_unit
)
1370 handleRandomFile(connection
, Field(original
->ocamlValues
,
1372 if (Field(original
->ocamlValues
, OcamlEGDSocket
) != Val_unit
)
1373 handleEGDSocket(connection
, Field(original
->ocamlValues
,
1375 if (Field(original
->ocamlValues
, OcamlCookieJar
) != Val_unit
)
1376 handleCookieJar(connection
, Field(original
->ocamlValues
,
1378 if (Field(original
->ocamlValues
, OcamlSSLCipherList
) != Val_unit
)
1379 handleSSLCipherList(connection
, Field(original
->ocamlValues
,
1380 OcamlSSLCipherList
));
1381 if (Field(original
->ocamlValues
, OcamlPrivate
) != Val_unit
)
1382 handlePrivate(connection
, Field(original
->ocamlValues
,
1384 if (Field(original
->ocamlValues
, OcamlHTTP200Aliases
) != Val_unit
)
1385 handleHTTP200Aliases(connection
, Field(original
->ocamlValues
,
1386 OcamlHTTP200Aliases
));
1387 if (Field(original
->ocamlValues
, OcamlNETRCFile
) != Val_unit
)
1388 handleNETRCFile(connection
, Field(original
->ocamlValues
,
1390 if (Field(original
->ocamlValues
, OcamlFTPAccount
) != Val_unit
)
1391 handleFTPAccount(connection
, Field(original
->ocamlValues
,
1393 if (Field(original
->ocamlValues
, OcamlCookieList
) != Val_unit
)
1394 handleCookieList(connection
, Field(original
->ocamlValues
,
1396 if (Field(original
->ocamlValues
, OcamlFTPAlternativeToUser
) != Val_unit
)
1397 handleFTPAlternativeToUser(connection
,
1398 Field(original
->ocamlValues
,
1399 OcamlFTPAlternativeToUser
));
1400 if (Field(original
->ocamlValues
, OcamlSSHPublicKeyFile
) != Val_unit
)
1401 handleSSHPublicKeyFile(connection
,
1402 Field(original
->ocamlValues
,
1403 OcamlSSHPublicKeyFile
));
1404 if (Field(original
->ocamlValues
, OcamlSSHPrivateKeyFile
) != Val_unit
)
1405 handleSSHPrivateKeyFile(connection
,
1406 Field(original
->ocamlValues
,
1407 OcamlSSHPrivateKeyFile
));
1408 if (Field(original
->ocamlValues
, OcamlCopyPostFields
) != Val_unit
)
1409 handleCopyPostFields(connection
,
1410 Field(original
->ocamlValues
,
1411 OcamlCopyPostFields
));
1416 static void removeConnection(Connection
*connection
)
1418 enter_blocking_section();
1419 curl_easy_cleanup(connection
->connection
);
1420 leave_blocking_section();
1422 if (connectionList
.tail
== connection
)
1423 connectionList
.tail
= connectionList
.tail
->next
;
1424 if (connectionList
.head
== connection
)
1425 connectionList
.head
= connectionList
.head
->prev
;
1427 if (connection
->next
!= NULL
)
1428 connection
->next
->prev
= connection
->prev
;
1429 if (connection
->prev
!= NULL
)
1430 connection
->prev
->next
= connection
->next
;
1432 remove_global_root(&connection
->ocamlValues
);
1434 if (connection
->url
!= NULL
)
1435 free(connection
->url
);
1436 if (connection
->proxy
!= NULL
)
1437 free(connection
->proxy
);
1438 if (connection
->userPwd
!= NULL
)
1439 free(connection
->userPwd
);
1440 if (connection
->proxyUserPwd
!= NULL
)
1441 free(connection
->proxyUserPwd
);
1442 if (connection
->range
!= NULL
)
1443 free(connection
->range
);
1444 if (connection
->errorBuffer
!= NULL
)
1445 free(connection
->range
);
1446 if (connection
->postFields
!= NULL
)
1447 free(connection
->postFields
);
1448 if (connection
->referer
!= NULL
)
1449 free(connection
->referer
);
1450 if (connection
->userAgent
!= NULL
)
1451 free(connection
->userAgent
);
1452 if (connection
->ftpPort
!= NULL
)
1453 free(connection
->ftpPort
);
1454 if (connection
->cookie
!= NULL
)
1455 free(connection
->cookie
);
1456 if (connection
->httpHeader
!= NULL
)
1457 free_curl_slist(connection
->httpHeader
);
1458 if (connection
->httpPostFirst
!= NULL
)
1459 curl_formfree(connection
->httpPostFirst
);
1460 if (connection
->httpPostStrings
!= NULL
)
1461 free_curl_slist(connection
->httpPostStrings
);
1462 if (connection
->sslCert
!= NULL
)
1463 free(connection
->sslCert
);
1464 if (connection
->sslCertType
!= NULL
)
1465 free(connection
->sslCertType
);
1466 if (connection
->sslCertPasswd
!= NULL
)
1467 free(connection
->sslCertPasswd
);
1468 if (connection
->sslKey
!= NULL
)
1469 free(connection
->sslKey
);
1470 if (connection
->sslKeyType
!= NULL
)
1471 free(connection
->sslKeyType
);
1472 if (connection
->sslKeyPasswd
!= NULL
)
1473 free(connection
->sslKeyPasswd
);
1474 if (connection
->sslEngine
!= NULL
)
1475 free(connection
->sslEngine
);
1476 if (connection
->quote
!= NULL
)
1477 free_curl_slist(connection
->quote
);
1478 if (connection
->postQuote
!= NULL
)
1479 free_curl_slist(connection
->postQuote
);
1480 if (connection
->cookieFile
!= NULL
)
1481 free(connection
->cookieFile
);
1482 if (connection
->customRequest
!= NULL
)
1483 free(connection
->customRequest
);
1484 if (connection
->interface
!= NULL
)
1485 free(connection
->interface
);
1486 if (connection
->caInfo
!= NULL
)
1487 free(connection
->caInfo
);
1488 if (connection
->caPath
!= NULL
)
1489 free(connection
->caPath
);
1490 if (connection
->randomFile
!= NULL
)
1491 free(connection
->randomFile
);
1492 if (connection
->egdSocket
!= NULL
)
1493 free(connection
->egdSocket
);
1494 if (connection
->cookieJar
!= NULL
)
1495 free(connection
->cookieJar
);
1496 if (connection
->sslCipherList
!= NULL
)
1497 free(connection
->sslCipherList
);
1498 if (connection
->private != NULL
)
1499 free(connection
->private);
1500 if (connection
->http200Aliases
!= NULL
)
1501 free_curl_slist(connection
->http200Aliases
);
1502 if (connection
->netrcFile
!= NULL
)
1503 free(connection
->netrcFile
);
1504 if (connection
->ftpaccount
!= NULL
)
1505 free(connection
->ftpaccount
);
1506 if (connection
->cookielist
!= NULL
)
1507 free(connection
->cookielist
);
1508 if (connection
->ftpAlternativeToUser
!= NULL
)
1509 free(connection
->ftpAlternativeToUser
);
1510 if (connection
->sshPublicKeyFile
!= NULL
)
1511 free(connection
->sshPublicKeyFile
);
1512 if (connection
->sshPrivateKeyFile
!= NULL
)
1513 free(connection
->sshPrivateKeyFile
);
1514 if (connection
->copyPostFields
!= NULL
)
1515 free(connection
->copyPostFields
);
1520 static void checkConnection(Connection
*connection
)
1522 Connection
*listIter
;
1524 listIter
= connectionList
.tail
;
1526 while (listIter
!= NULL
)
1528 if (listIter
== connection
)
1531 listIter
= listIter
->next
;
1534 failwith("Invalid Connection");
1537 static Connection
* findConnection(CURL
* h
)
1539 Connection
*listIter
;
1541 listIter
= connectionList
.tail
;
1543 while (listIter
!= NULL
)
1545 if (listIter
->connection
== h
)
1548 listIter
= listIter
->next
;
1551 failwith("Unknown handle");
1554 #define WRAP_DATA_CALLBACK(f) \
1555 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1558 leave_blocking_section();\
1559 result = f##_nolock(ptr,size,nmemb,data);\
1560 enter_blocking_section();\
1564 static size_t writeFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1567 CAMLlocal2(result
, str
);
1568 Connection
*conn
= (Connection
*)data
;
1571 checkConnection(conn
);
1573 str
= alloc_string(size
*nmemb
);
1575 for (i
= 0; i
< size
*nmemb
; i
++)
1576 Byte(str
, i
) = ptr
[i
];
1578 result
= callback(Field(conn
->ocamlValues
, OcamlWriteCallback
), str
);
1580 CAMLreturnT(size_t, Int_val(result
));
1583 WRAP_DATA_CALLBACK(writeFunction
)
1585 static size_t readFunction_nolock(void *ptr
, size_t size
, size_t nmemb
, void *data
)
1589 Connection
*conn
= (Connection
*)data
;
1592 checkConnection(conn
);
1594 result
= callback(Field(conn
->ocamlValues
, OcamlReadCallback
),
1595 Val_int(size
*nmemb
));
1597 length
= string_length(result
);
1599 if (length
>= size
*nmemb
)
1600 length
= size
*nmemb
;
1602 memcpy(ptr
, String_val(result
), length
);
1604 CAMLreturnT(size_t,length
);
1607 WRAP_DATA_CALLBACK(readFunction
)
1609 static size_t headerFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1612 CAMLlocal2(result
,str
);
1613 Connection
*conn
= (Connection
*)data
;
1616 checkConnection(conn
);
1618 str
= alloc_string(size
*nmemb
);
1620 for (i
= 0; i
< size
*nmemb
; i
++)
1621 Byte(str
, i
) = ptr
[i
];
1623 result
= callback(Field(conn
->ocamlValues
, OcamlHeaderCallback
), str
);
1625 CAMLreturnT(size_t, Int_val(result
));
1628 WRAP_DATA_CALLBACK(headerFunction
)
1630 static int progressFunction_nolock(void *data
,
1638 CAMLlocalN(callbackData
, 4);
1639 Connection
*conn
= (Connection
*)data
;
1641 checkConnection(conn
);
1643 callbackData
[0] = copy_double(dlTotal
);
1644 callbackData
[1] = copy_double(dlNow
);
1645 callbackData
[2] = copy_double(ulTotal
);
1646 callbackData
[3] = copy_double(ulNow
);
1648 result
= callbackN(Field(conn
->ocamlValues
, OcamlProgressCallback
),
1651 CAMLreturnT(int, Bool_val(result
));
1654 static int progressFunction(void *data
,
1661 leave_blocking_section();
1662 r
= progressFunction_nolock(data
,dlTotal
,dlNow
,ulTotal
,ulNow
);
1663 enter_blocking_section();
1667 static int debugFunction_nolock(CURL
*debugConnection
,
1668 curl_infotype infoType
,
1670 size_t bufferLength
,
1674 CAMLlocal3(camlDebugConnection
, camlInfoType
, camlMessage
);
1676 Connection
*conn
= (Connection
*)data
;
1678 checkConnection(conn
);
1680 camlDebugConnection
= (value
)conn
;
1681 camlInfoType
= Val_long(infoType
);
1682 camlMessage
= alloc_string(bufferLength
);
1684 for (i
= 0; i
< bufferLength
; i
++)
1685 Byte(camlMessage
, i
) = buffer
[i
];
1687 callback3(Field(conn
->ocamlValues
, OcamlDebugCallback
),
1688 camlDebugConnection
,
1692 CAMLreturnT(int, 0);
1695 static int debugFunction(CURL
*debugConnection
,
1696 curl_infotype infoType
,
1698 size_t bufferLength
,
1702 leave_blocking_section();
1703 r
= debugFunction_nolock(debugConnection
, infoType
, buffer
, bufferLength
, data
);
1704 enter_blocking_section();
1708 static curlioerr
ioctlFunction_nolock(CURL
*ioctl
,
1713 CAMLlocal3(camlResult
, camlConnection
, camlCmd
);
1714 Connection
*conn
= (Connection
*)data
;
1715 curlioerr result
= CURLIOE_OK
;
1717 checkConnection(conn
);
1719 if (cmd
== CURLIOCMD_NOP
)
1720 camlCmd
= Val_long(0);
1721 else if (cmd
== CURLIOCMD_RESTARTREAD
)
1722 camlCmd
= Val_long(1);
1724 failwith("Invalid IOCTL Cmd!");
1726 camlConnection
= alloc(1, Abstract_tag
);
1727 Store_field(camlConnection
, 0, (value
)conn
);
1729 camlResult
= callback2(Field(conn
->ocamlValues
, OcamlIOCTLCallback
),
1733 switch (Long_val(camlResult
))
1735 case 0: /* CURLIOE_OK */
1736 result
= CURLIOE_OK
;
1739 case 1: /* CURLIOE_UNKNOWNCMD */
1740 result
= CURLIOE_UNKNOWNCMD
;
1743 case 2: /* CURLIOE_FAILRESTART */
1744 result
= CURLIOE_FAILRESTART
;
1747 default: /* Incorrect return value, but let's handle it */
1748 result
= CURLIOE_FAILRESTART
;
1752 CAMLreturnT(curlioerr
, result
);
1755 static curlioerr
ioctlFunction(CURL
*ioctl
,
1760 leave_blocking_section();
1761 r
= ioctlFunction_nolock(ioctl
, cmd
, data
);
1762 enter_blocking_section();
1766 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1767 static int seekFunction_nolock(void *data
,
1772 CAMLlocal3(camlResult
, camlOffset
, camlOrigin
);
1773 Connection
*conn
= (Connection
*)data
;
1776 camlOffset
= copy_int64(offset
);
1778 if (origin
== SEEK_SET
)
1779 camlOrigin
= Val_long(0);
1780 else if (origin
== SEEK_CUR
)
1781 camlOrigin
= Val_long(1);
1782 else if (origin
== SEEK_END
)
1783 camlOrigin
= Val_long(2);
1785 camlOrigin
= Val_long(0);
1787 camlResult
= callback2(Field(conn
->ocamlValues
,
1788 OcamlSeekFunctionCallback
),
1792 result
= Int_val(camlResult
);
1794 CAMLreturnT(int, result
);
1797 static int seekFunction(void *data
,
1802 leave_blocking_section();
1803 r
= seekFunction_nolock(data
,offset
,origin
);
1804 enter_blocking_section();
1811 ** curl_global_init helper function
1814 CAMLprim value
helper_curl_global_init(value initOption
)
1816 CAMLparam1(initOption
);
1818 switch (Long_val(initOption
))
1820 case 0: /* CURLINIT_GLOBALALL */
1821 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL
)));
1824 case 1: /* CURLINIT_GLOBALSSL */
1825 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL
)));
1828 case 2: /* CURLINIT_GLOBALWIN32 */
1829 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32
)));
1832 case 3: /* CURLINIT_GLOBALNOTHING */
1833 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING
)));
1837 failwith("Invalid Initialization Option");
1841 /* Keep compiler happy, we should never get here due to failwith() */
1842 CAMLreturn(Val_unit
);
1846 ** curl_global_cleanup helper function
1849 CAMLprim value
helper_curl_global_cleanup(void)
1853 curl_global_cleanup();
1855 CAMLreturn(Val_unit
);
1859 ** curl_easy_init helper function
1862 CAMLprim value
helper_curl_easy_init(void)
1867 Connection
*conn
= newConnection();
1869 result
= alloc(1, Abstract_tag
);
1870 Store_field(result
, 0, (value
)conn
);
1875 CAMLprim value
helper_curl_easy_reset(value conn
)
1878 Connection
*connection
= Connection_val(conn
);
1880 checkConnection(connection
);
1881 curl_easy_reset(connection
->connection
);
1882 resetOcamlValues(connection
);
1884 CAMLreturn(Val_unit
);
1888 ** curl_easy_setopt helper utility functions
1891 static void handleWriteFunction(Connection
*conn
, value option
)
1894 CURLcode result
= CURLE_OK
;
1896 if (Tag_val(option
) == Closure_tag
)
1897 Store_field(conn
->ocamlValues
, OcamlWriteCallback
, option
);
1899 failwith("Not a proper closure");
1901 result
= curl_easy_setopt(conn
->connection
,
1902 CURLOPT_WRITEFUNCTION
,
1905 if (result
!= CURLE_OK
)
1906 raiseError(conn
, result
);
1908 result
= curl_easy_setopt(conn
->connection
,
1912 if (result
!= CURLE_OK
)
1913 raiseError(conn
, result
);
1918 static void handleReadFunction(Connection
*conn
, value option
)
1921 CURLcode result
= CURLE_OK
;
1923 if (Tag_val(option
) == Closure_tag
)
1924 Store_field(conn
->ocamlValues
, OcamlReadCallback
, option
);
1926 failwith("Not a proper closure");
1928 result
= curl_easy_setopt(conn
->connection
,
1929 CURLOPT_READFUNCTION
,
1932 if (result
!= CURLE_OK
)
1933 raiseError(conn
, result
);
1935 result
= curl_easy_setopt(conn
->connection
,
1939 if (result
!= CURLE_OK
)
1940 raiseError(conn
, result
);
1945 static void handleURL(Connection
*conn
, value option
)
1948 CURLcode result
= CURLE_OK
;
1950 Store_field(conn
->ocamlValues
, OcamlURL
, option
);
1952 if (conn
->url
!= NULL
)
1955 conn
->url
= strdup(String_val(option
));
1957 result
= curl_easy_setopt(conn
->connection
,
1961 if (result
!= CURLE_OK
)
1962 raiseError(conn
, result
);
1967 static void handleInFileSize(Connection
*conn
, value option
)
1970 CURLcode result
= CURLE_OK
;
1972 result
= curl_easy_setopt(conn
->connection
,
1976 if (result
!= CURLE_OK
)
1977 raiseError(conn
, result
);
1982 static void handleProxy(Connection
*conn
, value option
)
1985 CURLcode result
= CURLE_OK
;
1987 Store_field(conn
->ocamlValues
, OcamlProxy
, option
);
1989 if (conn
->proxy
!= NULL
)
1992 conn
->proxy
= strdup(String_val(option
));
1994 result
= curl_easy_setopt(conn
->connection
,
1998 if (result
!= CURLE_OK
)
1999 raiseError(conn
, result
);
2004 static void handleProxyPort(Connection
*conn
, value option
)
2007 CURLcode result
= CURLE_OK
;
2009 result
= curl_easy_setopt(conn
->connection
,
2013 if (result
!= CURLE_OK
)
2014 raiseError(conn
, result
);
2019 static void handleHTTPProxyTunnel(Connection
*conn
, value option
)
2022 CURLcode result
= CURLE_OK
;
2024 result
= curl_easy_setopt(conn
->connection
,
2025 CURLOPT_HTTPPROXYTUNNEL
,
2028 if (result
!= CURLE_OK
)
2029 raiseError(conn
, result
);
2034 static void handleVerbose(Connection
*conn
, value option
)
2037 CURLcode result
= CURLE_OK
;
2039 result
= curl_easy_setopt(conn
->connection
,
2043 if (result
!= CURLE_OK
)
2044 raiseError(conn
, result
);
2049 static void handleHeader(Connection
*conn
, value option
)
2052 CURLcode result
= CURLE_OK
;
2054 result
= curl_easy_setopt(conn
->connection
,
2058 if (result
!= CURLE_OK
)
2059 raiseError(conn
, result
);
2064 static void handleNoProgress(Connection
*conn
, value option
)
2067 CURLcode result
= CURLE_OK
;
2069 result
= curl_easy_setopt(conn
->connection
,
2073 if (result
!= CURLE_OK
)
2074 raiseError(conn
, result
);
2079 static void handleNoSignal(Connection
*conn
, value option
)
2081 #if HAVE_DECL_CURLOPT_NOSIGNAL
2083 CURLcode result
= CURLE_OK
;
2085 result
= curl_easy_setopt(conn
->connection
,
2089 if (result
!= CURLE_OK
)
2090 raiseError(conn
, result
);
2094 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2095 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2099 static void handleNoBody(Connection
*conn
, value option
)
2102 CURLcode result
= CURLE_OK
;
2104 result
= curl_easy_setopt(conn
->connection
,
2108 if (result
!= CURLE_OK
)
2109 raiseError(conn
, result
);
2114 static void handleFailOnError(Connection
*conn
, value option
)
2117 CURLcode result
= CURLE_OK
;
2119 result
= curl_easy_setopt(conn
->connection
,
2120 CURLOPT_FAILONERROR
,
2123 if (result
!= CURLE_OK
)
2124 raiseError(conn
, result
);
2129 static void handleUpload(Connection
*conn
, value option
)
2132 CURLcode result
= CURLE_OK
;
2134 result
= curl_easy_setopt(conn
->connection
,
2138 if (result
!= CURLE_OK
)
2139 raiseError(conn
, result
);
2144 static void handlePost(Connection
*conn
, value option
)
2147 CURLcode result
= CURLE_OK
;
2149 result
= curl_easy_setopt(conn
->connection
,
2153 if (result
!= CURLE_OK
)
2154 raiseError(conn
, result
);
2159 static void handleFTPListOnly(Connection
*conn
, value option
)
2162 CURLcode result
= CURLE_OK
;
2164 result
= curl_easy_setopt(conn
->connection
,
2165 CURLOPT_FTPLISTONLY
,
2168 if (result
!= CURLE_OK
)
2169 raiseError(conn
, result
);
2174 static void handleFTPAppend(Connection
*conn
, value option
)
2177 CURLcode result
= CURLE_OK
;
2179 result
= curl_easy_setopt(conn
->connection
,
2183 if (result
!= CURLE_OK
)
2184 raiseError(conn
, result
);
2189 static void handleNETRC(Connection
*conn
, value option
)
2192 CURLcode result
= CURLE_OK
;
2195 switch (Long_val(option
))
2197 case 0: /* CURL_NETRC_OPTIONAL */
2198 netrc
= CURL_NETRC_OPTIONAL
;
2201 case 1:/* CURL_NETRC_IGNORED */
2202 netrc
= CURL_NETRC_IGNORED
;
2205 case 2: /* CURL_NETRC_REQUIRED */
2206 netrc
= CURL_NETRC_REQUIRED
;
2210 failwith("Invalid NETRC Option");
2214 result
= curl_easy_setopt(conn
->connection
,
2218 if (result
!= CURLE_OK
)
2219 raiseError(conn
, result
);
2224 static void handleEncoding(Connection
*conn
, value option
)
2226 #if HAVE_DECL_CURLOPT_ENCODING
2228 CURLcode result
= CURLE_OK
;
2230 switch (Long_val(option
))
2232 case 0: /* CURL_ENCODING_NONE */
2233 result
= curl_easy_setopt(conn
->connection
,
2238 case 1: /* CURL_ENCODING_DEFLATE */
2239 result
= curl_easy_setopt(conn
->connection
,
2245 failwith("Invalid Encoding Option");
2249 if (result
!= CURLE_OK
)
2250 raiseError(conn
, result
);
2254 #warning "libcurl does not implement CURLOPT_ENCODING"
2255 failwith("libcurl does not implement CURLOPT_ENCODING");
2259 static void handleFollowLocation(Connection
*conn
, value option
)
2262 CURLcode result
= CURLE_OK
;
2264 result
= curl_easy_setopt(conn
->connection
,
2265 CURLOPT_FOLLOWLOCATION
,
2268 if (result
!= CURLE_OK
)
2269 raiseError(conn
, result
);
2274 static void handleTransferText(Connection
*conn
, value option
)
2277 CURLcode result
= CURLE_OK
;
2279 result
= curl_easy_setopt(conn
->connection
,
2280 CURLOPT_TRANSFERTEXT
,
2283 if (result
!= CURLE_OK
)
2284 raiseError(conn
, result
);
2289 static void handlePut(Connection
*conn
, value option
)
2292 CURLcode result
= CURLE_OK
;
2294 result
= curl_easy_setopt(conn
->connection
,
2298 if (result
!= CURLE_OK
)
2299 raiseError(conn
, result
);
2304 static void handleUserPwd(Connection
*conn
, value option
)
2307 CURLcode result
= CURLE_OK
;
2309 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2311 if (conn
->userPwd
!= NULL
)
2312 free(conn
->userPwd
);
2314 conn
->userPwd
= strdup(String_val(option
));
2316 result
= curl_easy_setopt(conn
->connection
,
2320 if (result
!= CURLE_OK
)
2321 raiseError(conn
, result
);
2326 static void handleProxyUserPwd(Connection
*conn
, value option
)
2329 CURLcode result
= CURLE_OK
;
2331 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2333 if (conn
->proxyUserPwd
!= NULL
)
2334 free(conn
->proxyUserPwd
);
2336 conn
->proxyUserPwd
= strdup(String_val(option
));
2338 result
= curl_easy_setopt(conn
->connection
,
2339 CURLOPT_PROXYUSERPWD
,
2340 conn
->proxyUserPwd
);
2342 if (result
!= CURLE_OK
)
2343 raiseError(conn
, result
);
2348 static void handleRange(Connection
*conn
, value option
)
2351 CURLcode result
= CURLE_OK
;
2353 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2355 if (conn
->range
!= NULL
)
2358 conn
->range
= strdup(String_val(option
));
2360 result
= curl_easy_setopt(conn
->connection
,
2364 if (result
!= CURLE_OK
)
2365 raiseError(conn
, result
);
2370 static void handleErrorBuffer(Connection
*conn
, value option
)
2373 CURLcode result
= CURLE_OK
;
2375 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2377 if (conn
->errorBuffer
!= NULL
)
2378 free(conn
->errorBuffer
);
2380 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2382 result
= curl_easy_setopt(conn
->connection
,
2383 CURLOPT_ERRORBUFFER
,
2386 if (result
!= CURLE_OK
)
2387 raiseError(conn
, result
);
2392 static void handleTimeout(Connection
*conn
, value option
)
2395 CURLcode result
= CURLE_OK
;
2397 result
= curl_easy_setopt(conn
->connection
,
2401 if (result
!= CURLE_OK
)
2402 raiseError(conn
, result
);
2407 static void handlePostFields(Connection
*conn
, value option
)
2410 CURLcode result
= CURLE_OK
;
2412 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2414 if (conn
->postFields
!= NULL
)
2415 free(conn
->postFields
);
2417 conn
->postFields
= malloc(string_length(option
)+1);
2418 memcpy(conn
->postFields
, String_val(option
), string_length(option
));
2420 result
= curl_easy_setopt(conn
->connection
,
2424 if (result
!= CURLE_OK
)
2425 raiseError(conn
, result
);
2430 static void handlePostFieldSize(Connection
*conn
, value option
)
2433 CURLcode result
= CURLE_OK
;
2435 result
= curl_easy_setopt(conn
->connection
,
2436 CURLOPT_POSTFIELDSIZE
,
2439 if (result
!= CURLE_OK
)
2440 raiseError(conn
, result
);
2445 static void handleReferer(Connection
*conn
, value option
)
2448 CURLcode result
= CURLE_OK
;
2450 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2452 if (conn
->referer
!= NULL
)
2453 free(conn
->referer
);
2455 conn
->referer
= strdup(String_val(option
));
2457 result
= curl_easy_setopt(conn
->connection
,
2461 if (result
!= CURLE_OK
)
2462 raiseError(conn
, result
);
2467 static void handleUserAgent(Connection
*conn
, value option
)
2470 CURLcode result
= CURLE_OK
;
2472 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2474 if (conn
->userAgent
!= NULL
)
2475 free(conn
->userAgent
);
2477 conn
->userAgent
= strdup(String_val(option
));
2479 result
= curl_easy_setopt(conn
->connection
,
2483 if (result
!= CURLE_OK
)
2484 raiseError(conn
, result
);
2489 static void handleFTPPort(Connection
*conn
, value option
)
2492 CURLcode result
= CURLE_OK
;
2494 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2496 if (conn
->ftpPort
!= NULL
)
2497 free(conn
->ftpPort
);
2499 conn
->ftpPort
= strdup(String_val(option
));
2501 result
= curl_easy_setopt(conn
->connection
,
2505 if (result
!= CURLE_OK
)
2506 raiseError(conn
, result
);
2511 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2514 CURLcode result
= CURLE_OK
;
2516 result
= curl_easy_setopt(conn
->connection
,
2517 CURLOPT_LOW_SPEED_LIMIT
,
2520 if (result
!= CURLE_OK
)
2521 raiseError(conn
, result
);
2526 static void handleLowSpeedTime(Connection
*conn
, value option
)
2529 CURLcode result
= CURLE_OK
;
2531 result
= curl_easy_setopt(conn
->connection
,
2532 CURLOPT_LOW_SPEED_TIME
,
2535 if (result
!= CURLE_OK
)
2536 raiseError(conn
, result
);
2541 static void handleResumeFrom(Connection
*conn
, value option
)
2544 CURLcode result
= CURLE_OK
;
2546 result
= curl_easy_setopt(conn
->connection
,
2547 CURLOPT_RESUME_FROM
,
2550 if (result
!= CURLE_OK
)
2551 raiseError(conn
, result
);
2556 static void handleCookie(Connection
*conn
, value option
)
2559 CURLcode result
= CURLE_OK
;
2561 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2563 if (conn
->cookie
!= NULL
)
2566 conn
->cookie
= strdup(String_val(option
));
2568 result
= curl_easy_setopt(conn
->connection
,
2572 if (result
!= CURLE_OK
)
2573 raiseError(conn
, result
);
2578 static void handleHTTPHeader(Connection
*conn
, value option
)
2581 CAMLlocal1(listIter
);
2582 CURLcode result
= CURLE_OK
;
2585 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2587 if (conn
->httpHeader
!= NULL
)
2588 free_curl_slist(conn
->httpHeader
);
2590 conn
->httpHeader
= NULL
;
2594 while (!Is_long(listIter
))
2596 if (Tag_val(Field(listIter
, 0)) != String_tag
)
2597 failwith("Not a string");
2599 str
= strdup(String_val(Field(listIter
, 0)));
2601 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, str
);
2603 listIter
= Field(listIter
, 1);
2606 result
= curl_easy_setopt(conn
->connection
,
2610 if (result
!= CURLE_OK
)
2611 raiseError(conn
, result
);
2616 static void handleHTTPPost(Connection
*conn
, value option
)
2619 CAMLlocal3(listIter
, formItem
, contentType
);
2620 CURLcode result
= CURLE_OK
;
2621 char *str1
, *str2
, *str3
, *str4
;
2625 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2627 if (conn
->httpPostFirst
!= NULL
)
2628 curl_formfree(conn
->httpPostFirst
);
2630 conn
->httpPostFirst
= NULL
;
2631 conn
->httpPostLast
= NULL
;
2633 if (conn
->httpPostStrings
!= NULL
)
2634 free_curl_slist(conn
->httpPostStrings
);
2636 while (!Is_long(listIter
))
2638 formItem
= Field(listIter
, 0);
2640 switch (Tag_val(formItem
))
2642 case 0: /* CURLFORM_CONTENT */
2643 if (Wosize_val(formItem
) < 3)
2645 failwith("Incorrect CURLFORM_CONTENT parameters");
2648 if (Is_long(Field(formItem
, 2)) &&
2649 Long_val(Field(formItem
, 2)) == 0)
2651 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2653 String_val(Field(formItem
, 0)),
2654 string_length(Field(formItem
, 0)));
2655 str1
[string_length(Field(formItem
, 0))] = 0;
2656 conn
->httpPostStrings
=
2657 curl_slist_append(conn
->httpPostStrings
, str1
);
2659 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2661 String_val(Field(formItem
, 1)),
2662 string_length(Field(formItem
, 1)));
2663 str2
[string_length(Field(formItem
, 1))] = 0;
2664 conn
->httpPostStrings
=
2665 curl_slist_append(conn
->httpPostStrings
, str2
);
2667 curl_formadd(&conn
->httpPostFirst
,
2668 &conn
->httpPostLast
,
2671 CURLFORM_NAMELENGTH
,
2672 string_length(Field(formItem
, 0)),
2673 CURLFORM_PTRCONTENTS
,
2675 CURLFORM_CONTENTSLENGTH
,
2676 string_length(Field(formItem
, 1)),
2679 else if (Is_block(Field(formItem
, 2)))
2681 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2683 String_val(Field(formItem
, 0)),
2684 string_length(Field(formItem
, 0)));
2685 str1
[string_length(Field(formItem
, 0))] = 0;
2686 conn
->httpPostStrings
=
2687 curl_slist_append(conn
->httpPostStrings
, str1
);
2689 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2691 String_val(Field(formItem
, 1)),
2692 string_length(Field(formItem
, 1)));
2693 str2
[string_length(Field(formItem
, 1))] = 0;
2694 conn
->httpPostStrings
=
2695 curl_slist_append(conn
->httpPostStrings
, str2
);
2697 contentType
= Field(formItem
, 2);
2699 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2701 String_val(Field(contentType
, 0)),
2702 string_length(Field(contentType
, 0)));
2703 str3
[string_length(Field(contentType
, 0))] = 0;
2704 conn
->httpPostStrings
=
2705 curl_slist_append(conn
->httpPostStrings
, str3
);
2707 curl_formadd(&conn
->httpPostFirst
,
2708 &conn
->httpPostLast
,
2711 CURLFORM_NAMELENGTH
,
2712 string_length(Field(formItem
, 0)),
2713 CURLFORM_PTRCONTENTS
,
2715 CURLFORM_CONTENTSLENGTH
,
2716 string_length(Field(formItem
, 1)),
2717 CURLFORM_CONTENTTYPE
,
2723 failwith("Incorrect CURLFORM_CONTENT parameters");
2727 case 1: /* CURLFORM_FILECONTENT */
2728 if (Wosize_val(formItem
) < 3)
2730 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2733 if (Is_long(Field(formItem
, 2)) &&
2734 Long_val(Field(formItem
, 2)) == 0)
2736 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2738 String_val(Field(formItem
, 0)),
2739 string_length(Field(formItem
, 0)));
2740 str1
[string_length(Field(formItem
, 0))] = 0;
2741 conn
->httpPostStrings
=
2742 curl_slist_append(conn
->httpPostStrings
, str1
);
2744 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2746 String_val(Field(formItem
, 1)),
2747 string_length(Field(formItem
, 1)));
2748 str2
[string_length(Field(formItem
, 1))] = 0;
2749 conn
->httpPostStrings
=
2750 curl_slist_append(conn
->httpPostStrings
, str2
);
2752 curl_formadd(&conn
->httpPostFirst
,
2753 &conn
->httpPostLast
,
2756 CURLFORM_NAMELENGTH
,
2757 string_length(Field(formItem
, 0)),
2758 CURLFORM_FILECONTENT
,
2762 else if (Is_block(Field(formItem
, 2)))
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 contentType
= Field(formItem
, 2);
2782 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2784 String_val(Field(contentType
, 0)),
2785 string_length(Field(contentType
, 0)));
2786 str3
[string_length(Field(contentType
, 0))] = 0;
2787 conn
->httpPostStrings
=
2788 curl_slist_append(conn
->httpPostStrings
, str3
);
2790 curl_formadd(&conn
->httpPostFirst
,
2791 &conn
->httpPostLast
,
2794 CURLFORM_NAMELENGTH
,
2795 string_length(Field(formItem
, 0)),
2796 CURLFORM_FILECONTENT
,
2798 CURLFORM_CONTENTTYPE
,
2804 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2808 case 2: /* CURLFORM_FILE */
2809 if (Wosize_val(formItem
) < 3)
2811 failwith("Incorrect CURLFORM_FILE parameters");
2814 if (Is_long(Field(formItem
, 2)) &&
2815 Long_val(Field(formItem
, 2)) == 0)
2817 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2819 String_val(Field(formItem
, 0)),
2820 string_length(Field(formItem
, 0)));
2821 str1
[string_length(Field(formItem
, 0))] = 0;
2822 conn
->httpPostStrings
=
2823 curl_slist_append(conn
->httpPostStrings
, str1
);
2825 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2827 String_val(Field(formItem
, 1)),
2828 string_length(Field(formItem
, 1)));
2829 str2
[string_length(Field(formItem
, 1))] = 0;
2830 conn
->httpPostStrings
=
2831 curl_slist_append(conn
->httpPostStrings
, str2
);
2833 curl_formadd(&conn
->httpPostFirst
,
2834 &conn
->httpPostLast
,
2837 CURLFORM_NAMELENGTH
,
2838 string_length(Field(formItem
, 0)),
2843 else if (Is_block(Field(formItem
, 2)))
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 contentType
= Field(formItem
, 2);
2863 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2865 String_val(Field(contentType
, 0)),
2866 string_length(Field(contentType
, 0)));
2867 str3
[string_length(Field(contentType
, 0))] = 0;
2868 conn
->httpPostStrings
=
2869 curl_slist_append(conn
->httpPostStrings
, str3
);
2871 curl_formadd(&conn
->httpPostFirst
,
2872 &conn
->httpPostLast
,
2875 CURLFORM_NAMELENGTH
,
2876 string_length(Field(formItem
, 0)),
2879 CURLFORM_CONTENTTYPE
,
2885 failwith("Incorrect CURLFORM_FILE parameters");
2889 case 3: /* CURLFORM_BUFFER */
2890 if (Wosize_val(formItem
) < 4)
2892 failwith("Incorrect CURLFORM_BUFFER parameters");
2895 if (Is_long(Field(formItem
, 3)) &&
2896 Long_val(Field(formItem
, 3)) == 0)
2898 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2900 String_val(Field(formItem
, 0)),
2901 string_length(Field(formItem
, 0)));
2902 str1
[string_length(Field(formItem
, 0))] = 0;
2903 conn
->httpPostStrings
=
2904 curl_slist_append(conn
->httpPostStrings
, str1
);
2906 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2908 String_val(Field(formItem
, 1)),
2909 string_length(Field(formItem
, 1)));
2910 str2
[string_length(Field(formItem
, 1))] = 0;
2911 conn
->httpPostStrings
=
2912 curl_slist_append(conn
->httpPostStrings
, str2
);
2914 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2916 String_val(Field(formItem
, 2)),
2917 string_length(Field(formItem
, 2)));
2918 str3
[string_length(Field(formItem
, 2))] = 0;
2919 conn
->httpPostStrings
=
2920 curl_slist_append(conn
->httpPostStrings
, str3
);
2922 curl_formadd(&conn
->httpPostFirst
,
2923 &conn
->httpPostLast
,
2926 CURLFORM_NAMELENGTH
,
2927 string_length(Field(formItem
, 0)),
2932 CURLFORM_BUFFERLENGTH
,
2933 string_length(Field(formItem
, 2)),
2936 else if (Is_block(Field(formItem
, 3)))
2938 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2940 String_val(Field(formItem
, 0)),
2941 string_length(Field(formItem
, 0)));
2942 str1
[string_length(Field(formItem
, 0))] = 0;
2943 conn
->httpPostStrings
=
2944 curl_slist_append(conn
->httpPostStrings
, str1
);
2946 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2948 String_val(Field(formItem
, 1)),
2949 string_length(Field(formItem
, 1)));
2950 str2
[string_length(Field(formItem
, 1))] = 0;
2951 conn
->httpPostStrings
=
2952 curl_slist_append(conn
->httpPostStrings
, str2
);
2954 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2956 String_val(Field(formItem
, 2)),
2957 string_length(Field(formItem
, 2)));
2958 str3
[string_length(Field(formItem
, 2))] = 0;
2959 conn
->httpPostStrings
=
2960 curl_slist_append(conn
->httpPostStrings
, str3
);
2962 contentType
= Field(formItem
, 3);
2964 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2966 String_val(Field(contentType
, 0)),
2967 string_length(Field(contentType
, 0)));
2968 str4
[string_length(Field(contentType
, 0))] = 0;
2969 conn
->httpPostStrings
=
2970 curl_slist_append(conn
->httpPostStrings
, str4
);
2972 curl_formadd(&conn
->httpPostFirst
,
2973 &conn
->httpPostLast
,
2976 CURLFORM_NAMELENGTH
,
2977 string_length(Field(formItem
, 0)),
2982 CURLFORM_BUFFERLENGTH
,
2983 string_length(Field(formItem
, 2)),
2984 CURLFORM_CONTENTTYPE
,
2990 failwith("Incorrect CURLFORM_BUFFER parameters");
2995 listIter
= Field(listIter
, 1);
2998 result
= curl_easy_setopt(conn
->connection
,
3000 conn
->httpPostFirst
);
3002 if (result
!= CURLE_OK
)
3003 raiseError(conn
, result
);
3008 static void handleSSLCert(Connection
*conn
, value option
)
3011 CURLcode result
= CURLE_OK
;
3013 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3015 if (conn
->sslCert
!= NULL
)
3016 free(conn
->sslCert
);
3018 conn
->sslCert
= strdup(String_val(option
));
3020 result
= curl_easy_setopt(conn
->connection
,
3024 if (result
!= CURLE_OK
)
3025 raiseError(conn
, result
);
3030 static void handleSSLCertType(Connection
*conn
, value option
)
3033 CURLcode result
= CURLE_OK
;
3035 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3037 if (conn
->sslCertType
!= NULL
)
3038 free(conn
->sslCertType
);
3040 conn
->sslCertType
= strdup(String_val(option
));
3042 result
= curl_easy_setopt(conn
->connection
,
3043 CURLOPT_SSLCERTTYPE
,
3046 if (result
!= CURLE_OK
)
3047 raiseError(conn
, result
);
3052 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3055 CURLcode result
= CURLE_OK
;
3057 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3059 if (conn
->sslCertPasswd
!= NULL
)
3060 free(conn
->sslCertPasswd
);
3062 conn
->sslCertPasswd
= strdup(String_val(option
));
3064 result
= curl_easy_setopt(conn
->connection
,
3065 CURLOPT_SSLCERTPASSWD
,
3066 conn
->sslCertPasswd
);
3068 if (result
!= CURLE_OK
)
3069 raiseError(conn
, result
);
3074 static void handleSSLKey(Connection
*conn
, value option
)
3077 CURLcode result
= CURLE_OK
;
3079 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3081 if (conn
->sslKey
!= NULL
)
3084 conn
->sslKey
= strdup(String_val(option
));
3086 result
= curl_easy_setopt(conn
->connection
,
3090 if (result
!= CURLE_OK
)
3091 raiseError(conn
, result
);
3096 static void handleSSLKeyType(Connection
*conn
, value option
)
3099 CURLcode result
= CURLE_OK
;
3101 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3103 if (conn
->sslKeyType
!= NULL
)
3104 free(conn
->sslKeyType
);
3106 conn
->sslKeyType
= strdup(String_val(option
));
3108 result
= curl_easy_setopt(conn
->connection
,
3112 if (result
!= CURLE_OK
)
3113 raiseError(conn
, result
);
3118 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3121 CURLcode result
= CURLE_OK
;
3123 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3125 if (conn
->sslKeyPasswd
!= NULL
)
3126 free(conn
->sslKeyPasswd
);
3128 conn
->sslKeyPasswd
= strdup(String_val(option
));
3130 result
= curl_easy_setopt(conn
->connection
,
3131 CURLOPT_SSLKEYPASSWD
,
3132 conn
->sslKeyPasswd
);
3134 if (result
!= CURLE_OK
)
3135 raiseError(conn
, result
);
3140 static void handleSSLEngine(Connection
*conn
, value option
)
3143 CURLcode result
= CURLE_OK
;
3145 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3147 if (conn
->sslEngine
!= NULL
)
3148 free(conn
->sslEngine
);
3150 conn
->sslEngine
= strdup(String_val(option
));
3152 result
= curl_easy_setopt(conn
->connection
,
3156 if (result
!= CURLE_OK
)
3157 raiseError(conn
, result
);
3162 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3165 CURLcode result
= CURLE_OK
;
3167 result
= curl_easy_setopt(conn
->connection
,
3168 CURLOPT_SSLENGINE_DEFAULT
,
3171 if (result
!= CURLE_OK
)
3172 raiseError(conn
, result
);
3177 static void handleCRLF(Connection
*conn
, value option
)
3180 CURLcode result
= CURLE_OK
;
3182 result
= curl_easy_setopt(conn
->connection
,
3186 if (result
!= CURLE_OK
)
3187 raiseError(conn
, result
);
3192 static void handleQuote(Connection
*conn
, value option
)
3195 CAMLlocal1(listIter
);
3196 CURLcode result
= CURLE_OK
;
3199 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3201 if (conn
->quote
!= NULL
)
3202 free_curl_slist(conn
->quote
);
3208 while (!Is_long(listIter
))
3210 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3211 failwith("Not a string");
3213 str
= strdup(String_val(Field(listIter
, 0)));
3215 conn
->quote
= curl_slist_append(conn
->quote
, str
);
3217 listIter
= Field(listIter
, 1);
3220 result
= curl_easy_setopt(conn
->connection
,
3224 if (result
!= CURLE_OK
)
3225 raiseError(conn
, result
);
3230 static void handlePostQuote(Connection
*conn
, value option
)
3233 CAMLlocal1(listIter
);
3234 CURLcode result
= CURLE_OK
;
3237 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3239 if (conn
->postQuote
!= NULL
)
3240 free_curl_slist(conn
->postQuote
);
3242 conn
->postQuote
= NULL
;
3246 while (!Is_long(listIter
))
3248 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3249 failwith("Not a string");
3251 str
= strdup(String_val(Field(listIter
, 0)));
3253 conn
->postQuote
= curl_slist_append(conn
->postQuote
, str
);
3255 listIter
= Field(listIter
, 1);
3258 result
= curl_easy_setopt(conn
->connection
,
3262 if (result
!= CURLE_OK
)
3263 raiseError(conn
, result
);
3268 static void handleHeaderFunction(Connection
*conn
, value option
)
3271 CURLcode result
= CURLE_OK
;
3273 if (Tag_val(option
) == Closure_tag
)
3274 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3276 failwith("Not a proper closure");
3278 result
= curl_easy_setopt(conn
->connection
,
3279 CURLOPT_HEADERFUNCTION
,
3282 if (result
!= CURLE_OK
)
3283 raiseError(conn
, result
);
3285 result
= curl_easy_setopt(conn
->connection
,
3286 CURLOPT_WRITEHEADER
,
3289 if (result
!= CURLE_OK
)
3290 raiseError(conn
, result
);
3295 static void handleCookieFile(Connection
*conn
, value option
)
3298 CURLcode result
= CURLE_OK
;
3300 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3302 if (conn
->cookieFile
!= NULL
)
3303 free(conn
->cookieFile
);
3305 conn
->cookieFile
= strdup(String_val(option
));
3307 result
= curl_easy_setopt(conn
->connection
,
3311 if (result
!= CURLE_OK
)
3312 raiseError(conn
, result
);
3317 static void handleSSLVersion(Connection
*conn
, value option
)
3320 CURLcode result
= CURLE_OK
;
3322 result
= curl_easy_setopt(conn
->connection
,
3326 if (result
!= CURLE_OK
)
3327 raiseError(conn
, result
);
3332 static void handleTimeCondition(Connection
*conn
, value option
)
3335 CURLcode result
= CURLE_OK
;
3337 switch (Long_val(option
))
3339 case 0: /* TIMECOND_IFMODSINCE */
3340 result
= curl_easy_setopt(conn
->connection
,
3341 CURLOPT_TIMECONDITION
,
3342 CURL_TIMECOND_IFMODSINCE
);
3345 case 1: /* TIMECOND_IFUNMODSINCE */
3346 result
= curl_easy_setopt(conn
->connection
,
3347 CURLOPT_TIMECONDITION
,
3348 CURL_TIMECOND_IFUNMODSINCE
);
3352 failwith("Invalid TIMECOND Option");
3356 if (result
!= CURLE_OK
)
3357 raiseError(conn
, result
);
3362 static void handleTimeValue(Connection
*conn
, value option
)
3365 CURLcode result
= CURLE_OK
;
3367 result
= curl_easy_setopt(conn
->connection
,
3371 if (result
!= CURLE_OK
)
3372 raiseError(conn
, result
);
3377 static void handleCustomRequest(Connection
*conn
, value option
)
3380 CURLcode result
= CURLE_OK
;
3382 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3384 if (conn
->customRequest
!= NULL
)
3385 free(conn
->customRequest
);
3387 conn
->customRequest
= strdup(String_val(option
));
3389 result
= curl_easy_setopt(conn
->connection
,
3390 CURLOPT_CUSTOMREQUEST
,
3391 conn
->customRequest
);
3393 if (result
!= CURLE_OK
)
3394 raiseError(conn
, result
);
3399 static void handleInterface(Connection
*conn
, value option
)
3402 CURLcode result
= CURLE_OK
;
3404 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3406 if (conn
->interface
!= NULL
)
3407 free(conn
->interface
);
3409 conn
->interface
= strdup(String_val(option
));
3411 result
= curl_easy_setopt(conn
->connection
,
3415 if (result
!= CURLE_OK
)
3416 raiseError(conn
, result
);
3421 static void handleKRB4Level(Connection
*conn
, value option
)
3424 CURLcode result
= CURLE_OK
;
3426 switch (Long_val(option
))
3428 case 0: /* KRB4_NONE */
3429 result
= curl_easy_setopt(conn
->connection
,
3434 case 1: /* KRB4_CLEAR */
3435 result
= curl_easy_setopt(conn
->connection
,
3440 case 2: /* KRB4_SAFE */
3441 result
= curl_easy_setopt(conn
->connection
,
3446 case 3: /* KRB4_CONFIDENTIAL */
3447 result
= curl_easy_setopt(conn
->connection
,
3452 case 4: /* KRB4_PRIVATE */
3453 result
= curl_easy_setopt(conn
->connection
,
3459 failwith("Invalid KRB4 Option");
3463 if (result
!= CURLE_OK
)
3464 raiseError(conn
, result
);
3469 static void handleProgressFunction(Connection
*conn
, value option
)
3472 CURLcode result
= CURLE_OK
;
3474 if (Tag_val(option
) == Closure_tag
)
3475 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3477 failwith("Not a proper closure");
3479 result
= curl_easy_setopt(conn
->connection
,
3480 CURLOPT_PROGRESSFUNCTION
,
3482 if (result
!= CURLE_OK
)
3483 raiseError(conn
, result
);
3485 result
= curl_easy_setopt(conn
->connection
,
3486 CURLOPT_PROGRESSDATA
,
3489 if (result
!= CURLE_OK
)
3490 raiseError(conn
, result
);
3495 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3498 CURLcode result
= CURLE_OK
;
3500 result
= curl_easy_setopt(conn
->connection
,
3501 CURLOPT_SSL_VERIFYPEER
,
3504 if (result
!= CURLE_OK
)
3505 raiseError(conn
, result
);
3510 static void handleCAInfo(Connection
*conn
, value option
)
3513 CURLcode result
= CURLE_OK
;
3515 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3517 if (conn
->caInfo
!= NULL
)
3520 conn
->caInfo
= strdup(String_val(option
));
3522 result
= curl_easy_setopt(conn
->connection
,
3526 if (result
!= CURLE_OK
)
3527 raiseError(conn
, result
);
3532 static void handleCAPath(Connection
*conn
, value option
)
3535 CURLcode result
= CURLE_OK
;
3537 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3539 if (conn
->caPath
!= NULL
)
3542 conn
->caPath
= strdup(String_val(option
));
3544 result
= curl_easy_setopt(conn
->connection
,
3548 if (result
!= CURLE_OK
)
3549 raiseError(conn
, result
);
3554 static void handleFileTime(Connection
*conn
, value option
)
3557 CURLcode result
= CURLE_OK
;
3559 result
= curl_easy_setopt(conn
->connection
,
3563 if (result
!= CURLE_OK
)
3564 raiseError(conn
, result
);
3569 static void handleMaxRedirs(Connection
*conn
, value option
)
3572 CURLcode result
= CURLE_OK
;
3574 result
= curl_easy_setopt(conn
->connection
,
3578 if (result
!= CURLE_OK
)
3579 raiseError(conn
, result
);
3584 static void handleMaxConnects(Connection
*conn
, value option
)
3587 CURLcode result
= CURLE_OK
;
3589 result
= curl_easy_setopt(conn
->connection
,
3590 CURLOPT_MAXCONNECTS
,
3593 if (result
!= CURLE_OK
)
3594 raiseError(conn
, result
);
3599 static void handleClosePolicy(Connection
*conn
, value option
)
3602 CURLcode result
= CURLE_OK
;
3604 switch (Long_val(option
))
3606 case 0: /* CLOSEPOLICY_OLDEST */
3607 result
= curl_easy_setopt(conn
->connection
,
3608 CURLOPT_CLOSEPOLICY
,
3609 CURLCLOSEPOLICY_OLDEST
);
3612 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3613 result
= curl_easy_setopt(conn
->connection
,
3614 CURLOPT_CLOSEPOLICY
,
3615 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3619 failwith("Invalid CLOSEPOLICY Option");
3623 if (result
!= CURLE_OK
)
3624 raiseError(conn
, result
);
3629 static void handleFreshConnect(Connection
*conn
, value option
)
3632 CURLcode result
= CURLE_OK
;
3634 result
= curl_easy_setopt(conn
->connection
,
3635 CURLOPT_FRESH_CONNECT
,
3638 if (result
!= CURLE_OK
)
3639 raiseError(conn
, result
);
3644 static void handleForbidReuse(Connection
*conn
, value option
)
3647 CURLcode result
= CURLE_OK
;
3649 result
= curl_easy_setopt(conn
->connection
,
3650 CURLOPT_FORBID_REUSE
,
3653 if (result
!= CURLE_OK
)
3654 raiseError(conn
, result
);
3659 static void handleRandomFile(Connection
*conn
, value option
)
3662 CURLcode result
= CURLE_OK
;
3664 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3666 if (conn
->randomFile
!= NULL
)
3667 free(conn
->randomFile
);
3669 conn
->randomFile
= strdup(String_val(option
));
3671 result
= curl_easy_setopt(conn
->connection
,
3672 CURLOPT_RANDOM_FILE
,
3675 if (result
!= CURLE_OK
)
3676 raiseError(conn
, result
);
3681 static void handleEGDSocket(Connection
*conn
, value option
)
3684 CURLcode result
= CURLE_OK
;
3686 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3688 if (conn
->egdSocket
!= NULL
)
3689 free(conn
->egdSocket
);
3691 conn
->egdSocket
= strdup(String_val(option
));
3693 result
= curl_easy_setopt(conn
->connection
,
3697 if (result
!= CURLE_OK
)
3698 raiseError(conn
, result
);
3703 static void handleConnectTimeout(Connection
*conn
, value option
)
3706 CURLcode result
= CURLE_OK
;
3708 result
= curl_easy_setopt(conn
->connection
,
3709 CURLOPT_CONNECTTIMEOUT
,
3712 if (result
!= CURLE_OK
)
3713 raiseError(conn
, result
);
3718 static void handleHTTPGet(Connection
*conn
, value option
)
3721 CURLcode result
= CURLE_OK
;
3723 result
= curl_easy_setopt(conn
->connection
,
3727 if (result
!= CURLE_OK
)
3728 raiseError(conn
, result
);
3733 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3736 CURLcode result
= CURLE_OK
;
3738 switch (Long_val(option
))
3740 case 0: /* SSLVERIFYHOST_EXISTENCE */
3741 result
= curl_easy_setopt(conn
->connection
,
3742 CURLOPT_SSL_VERIFYHOST
,
3746 case 1: /* SSLVERIFYHOST_HOSTNAME */
3747 result
= curl_easy_setopt(conn
->connection
,
3748 CURLOPT_SSL_VERIFYHOST
,
3753 failwith("Invalid SSLVERIFYHOST Option");
3757 if (result
!= CURLE_OK
)
3758 raiseError(conn
, result
);
3763 static void handleCookieJar(Connection
*conn
, value option
)
3766 CURLcode result
= CURLE_OK
;
3768 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3770 if (conn
->cookieJar
!= NULL
)
3771 free(conn
->cookieJar
);
3773 conn
->cookieJar
= strdup(String_val(option
));
3775 result
= curl_easy_setopt(conn
->connection
,
3779 if (result
!= CURLE_OK
)
3780 raiseError(conn
, result
);
3785 static void handleSSLCipherList(Connection
*conn
, value option
)
3788 CURLcode result
= CURLE_OK
;
3790 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3792 if (conn
->sslCipherList
!= NULL
)
3793 free(conn
->sslCipherList
);
3795 conn
->sslCipherList
= strdup(String_val(option
));
3797 result
= curl_easy_setopt(conn
->connection
,
3798 CURLOPT_SSL_CIPHER_LIST
,
3799 conn
->sslCipherList
);
3801 if (result
!= CURLE_OK
)
3802 raiseError(conn
, result
);
3807 static void handleHTTPVersion(Connection
*conn
, value option
)
3810 CURLcode result
= CURLE_OK
;
3812 switch (Long_val(option
))
3814 case 0: /* HTTP_VERSION_NONE */
3815 result
= curl_easy_setopt(conn
->connection
,
3816 CURLOPT_HTTP_VERSION
,
3817 CURL_HTTP_VERSION_NONE
);
3820 case 1: /* HTTP_VERSION_1_0 */
3821 result
= curl_easy_setopt(conn
->connection
,
3822 CURLOPT_HTTP_VERSION
,
3823 CURL_HTTP_VERSION_1_0
);
3826 case 2: /* HTTP_VERSION_1_1 */
3827 result
= curl_easy_setopt(conn
->connection
,
3828 CURLOPT_HTTP_VERSION
,
3829 CURL_HTTP_VERSION_1_1
);
3833 failwith("Invalid HTTP_VERSION Option");
3837 if (result
!= CURLE_OK
)
3838 raiseError(conn
, result
);
3843 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3846 CURLcode result
= CURLE_OK
;
3848 result
= curl_easy_setopt(conn
->connection
,
3849 CURLOPT_FTP_USE_EPSV
,
3852 if (result
!= CURLE_OK
)
3853 raiseError(conn
, result
);
3858 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3861 CURLcode result
= CURLE_OK
;
3863 result
= curl_easy_setopt(conn
->connection
,
3864 CURLOPT_DNS_CACHE_TIMEOUT
,
3867 if (result
!= CURLE_OK
)
3868 raiseError(conn
, result
);
3873 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3876 CURLcode result
= CURLE_OK
;
3878 result
= curl_easy_setopt(conn
->connection
,
3879 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3882 if (result
!= CURLE_OK
)
3883 raiseError(conn
, result
);
3888 static void handleDebugFunction(Connection
*conn
, value option
)
3891 CURLcode result
= CURLE_OK
;
3893 if (Tag_val(option
) == Closure_tag
)
3894 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3896 failwith("Not a proper closure");
3898 result
= curl_easy_setopt(conn
->connection
,
3899 CURLOPT_DEBUGFUNCTION
,
3901 if (result
!= CURLE_OK
)
3902 raiseError(conn
, result
);
3904 result
= curl_easy_setopt(conn
->connection
,
3908 if (result
!= CURLE_OK
)
3909 raiseError(conn
, result
);
3914 static void handlePrivate(Connection
*conn
, value option
)
3916 #if HAVE_DECL_CURLOPT_PRIVATE
3918 CURLcode result
= CURLE_OK
;
3920 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
3922 if (conn
->private != NULL
)
3923 free(conn
->private);
3925 conn
->private = strdup(String_val(option
));
3927 result
= curl_easy_setopt(conn
->connection
,
3931 if (result
!= CURLE_OK
)
3932 raiseError(conn
, result
);
3936 #warning "libcurl does not implement CURLOPT_PRIVATE"
3937 failwith("libcurl does not implement CURLOPT_PRIVATE");
3941 static void handleHTTP200Aliases(Connection
*conn
, value option
)
3943 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3945 CAMLlocal1(listIter
);
3946 CURLcode result
= CURLE_OK
;
3949 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
3951 if (conn
->http200Aliases
!= NULL
)
3952 free_curl_slist(conn
->http200Aliases
);
3954 conn
->http200Aliases
= NULL
;
3958 while (!Is_long(listIter
))
3960 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3961 failwith("Not a string");
3963 str
= strdup(String_val(Field(listIter
, 0)));
3965 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, str
);
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");
5176 ** curl_easy_setopt helper function
5179 CAMLprim value
helper_curl_easy_setopt(value conn
, value option
)
5181 CAMLparam2(conn
, option
);
5183 Connection
*connection
= Connection_val(conn
);
5185 checkConnection(connection
);
5187 if (Is_long(option
))
5191 sprintf(error
, "Unimplemented Option: %s",
5192 findOption(unimplementedOptionMap
,
5193 (CURLoption
)(Long_val(option
))));
5198 if (!Is_block(option
))
5199 failwith("Not a block");
5201 if (Wosize_val(option
) < 1)
5202 failwith("Insufficient data in block");
5204 data
= Field(option
, 0);
5206 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5207 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5210 failwith("Invalid CURLOPT Option");
5212 CAMLreturn(Val_unit
);
5216 ** curl_easy_perform helper function
5219 CAMLprim value
helper_curl_easy_perform(value conn
)
5222 CURLcode result
= CURLE_OK
;
5223 Connection
*connection
= Connection_val(conn
);
5225 checkConnection(connection
);
5227 enter_blocking_section();
5228 result
= curl_easy_perform(connection
->connection
);
5229 leave_blocking_section();
5231 if (result
!= CURLE_OK
)
5232 raiseError(connection
, result
);
5234 CAMLreturn(Val_unit
);
5238 ** curl_easy_cleanup helper function
5241 CAMLprim value
helper_curl_easy_cleanup(value conn
)
5244 Connection
*connection
= Connection_val(conn
);
5246 checkConnection(connection
);
5248 removeConnection(connection
);
5250 CAMLreturn(Val_unit
);
5254 ** curl_easy_duphandle helper function
5257 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5261 Connection
*connection
= Connection_val(conn
);
5263 checkConnection(connection
);
5265 result
= alloc(1, Abstract_tag
);
5266 Store_field(result
, 0, (value
)duplicateConnection(connection
));
5272 ** curl_easy_getinfo helper function
5275 enum GetInfoResultType
{
5276 StringValue
, LongValue
, DoubleValue
, StringListValue
5279 value
convertStringList(struct curl_slist
*slist
)
5282 CAMLlocal3(result
, current
, next
);
5283 struct curl_slist
*p
= slist
;
5285 result
= Val_int(0);
5286 current
= Val_int(0);
5291 next
= alloc_tuple(2);
5292 Store_field(next
, 0, copy_string(p
->data
));
5293 Store_field(next
, 1, Val_int(0));
5295 if (result
== Val_int(0))
5298 if (current
!= Val_int(0))
5299 Store_field(current
, 1, next
);
5306 curl_slist_free_all(slist
);
5311 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5313 CAMLparam2(conn
, option
);
5315 CURLcode curlResult
;
5316 Connection
*connection
= Connection_val(conn
);
5317 enum GetInfoResultType resultType
;
5318 char *strValue
= NULL
;
5321 struct curl_slist
*stringListValue
= NULL
;
5323 checkConnection(connection
);
5325 switch(Long_val(option
))
5327 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5328 case 0: /* CURLINFO_EFFECTIVE_URL */
5329 resultType
= StringValue
;
5331 curlResult
= curl_easy_getinfo(connection
->connection
,
5332 CURLINFO_EFFECTIVE_URL
,
5336 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5339 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5340 case 1: /* CURLINFO_HTTP_CODE */
5341 case 2: /* CURLINFO_RESPONSE_CODE */
5342 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5343 resultType
= LongValue
;
5345 curlResult
= curl_easy_getinfo(connection
->connection
,
5346 CURLINFO_RESPONSE_CODE
,
5349 resultType
= LongValue
;
5351 curlResult
= curl_easy_getinfo(connection
->connection
,
5358 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5359 case 3: /* CURLINFO_TOTAL_TIME */
5360 resultType
= DoubleValue
;
5362 curlResult
= curl_easy_getinfo(connection
->connection
,
5363 CURLINFO_TOTAL_TIME
,
5368 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5369 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5370 resultType
= DoubleValue
;
5372 curlResult
= curl_easy_getinfo(connection
->connection
,
5373 CURLINFO_NAMELOOKUP_TIME
,
5378 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5379 case 5: /* CURLINFO_CONNECT_TIME */
5380 resultType
= DoubleValue
;
5382 curlResult
= curl_easy_getinfo(connection
->connection
,
5383 CURLINFO_CONNECT_TIME
,
5388 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5389 case 6: /* CURLINFO_PRETRANSFER_TIME */
5390 resultType
= DoubleValue
;
5392 curlResult
= curl_easy_getinfo(connection
->connection
,
5393 CURLINFO_PRETRANSFER_TIME
,
5398 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5399 case 7: /* CURLINFO_SIZE_UPLOAD */
5400 resultType
= DoubleValue
;
5402 curlResult
= curl_easy_getinfo(connection
->connection
,
5403 CURLINFO_SIZE_UPLOAD
,
5408 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5409 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5410 resultType
= DoubleValue
;
5412 curlResult
= curl_easy_getinfo(connection
->connection
,
5413 CURLINFO_SIZE_DOWNLOAD
,
5418 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5419 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5420 resultType
= DoubleValue
;
5422 curlResult
= curl_easy_getinfo(connection
->connection
,
5423 CURLINFO_SPEED_DOWNLOAD
,
5428 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5429 case 10: /* CURLINFO_SPEED_UPLOAD */
5430 resultType
= DoubleValue
;
5432 curlResult
= curl_easy_getinfo(connection
->connection
,
5433 CURLINFO_SPEED_UPLOAD
,
5439 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5440 case 11: /* CURLINFO_HEADER_SIZE */
5441 resultType
= LongValue
;
5443 curlResult
= curl_easy_getinfo(connection
->connection
,
5444 CURLINFO_HEADER_SIZE
,
5449 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5450 case 12: /* CURLINFO_REQUEST_SIZE */
5451 resultType
= LongValue
;
5453 curlResult
= curl_easy_getinfo(connection
->connection
,
5454 CURLINFO_REQUEST_SIZE
,
5459 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5460 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5461 resultType
= LongValue
;
5463 curlResult
= curl_easy_getinfo(connection
->connection
,
5464 CURLINFO_SSL_VERIFYRESULT
,
5469 #if HAVE_DECL_CURLINFO_FILETIME
5470 case 14: /* CURLINFO_FILETIME */
5471 resultType
= DoubleValue
;
5473 curlResult
= curl_easy_getinfo(connection
->connection
,
5479 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5480 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5481 resultType
= DoubleValue
;
5483 curlResult
= curl_easy_getinfo(connection
->connection
,
5484 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5489 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5490 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5491 resultType
= DoubleValue
;
5493 curlResult
= curl_easy_getinfo(connection
->connection
,
5494 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5499 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5500 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5501 resultType
= DoubleValue
;
5503 curlResult
= curl_easy_getinfo(connection
->connection
,
5504 CURLINFO_STARTTRANSFER_TIME
,
5509 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5510 case 18: /* CURLINFO_CONTENT_TYPE */
5511 resultType
= StringValue
;
5513 curlResult
= curl_easy_getinfo(connection
->connection
,
5514 CURLINFO_CONTENT_TYPE
,
5519 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5520 case 19: /* CURLINFO_REDIRECT_TIME */
5521 resultType
= DoubleValue
;
5523 curlResult
= curl_easy_getinfo(connection
->connection
,
5524 CURLINFO_REDIRECT_TIME
,
5529 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5530 case 20: /* CURLINFO_REDIRECT_COUNT */
5531 resultType
= LongValue
;
5533 curlResult
= curl_easy_getinfo(connection
->connection
,
5534 CURLINFO_REDIRECT_COUNT
,
5539 #if HAVE_DECL_CURLINFO_PRIVATE
5540 case 21: /* CURLINFO_PRIVATE */
5541 resultType
= StringValue
;
5543 curlResult
= curl_easy_getinfo(connection
->connection
,
5549 #if HAVE_DECL_CURLINFO_HTTP_CONNECT_CODE
5550 case 22: /* CURLINFO_HTTP_CONNECT_CODE */
5551 resultType
= LongValue
;
5553 curlResult
= curl_easy_getinfo(connection
->connection
,
5554 CURLINFO_HTTP_CONNECT_CODE
,
5559 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5560 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5561 resultType
= LongValue
;
5563 curlResult
= curl_easy_getinfo(connection
->connection
,
5564 CURLINFO_HTTPAUTH_AVAIL
,
5569 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5570 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5571 resultType
= LongValue
;
5573 curlResult
= curl_easy_getinfo(connection
->connection
,
5574 CURLINFO_PROXYAUTH_AVAIL
,
5579 #if HAVE_DECL_CURLINFO_OS_ERRNO
5580 case 25: /* CURLINFO_OS_ERRNO */
5581 resultType
= LongValue
;
5583 curlResult
= curl_easy_getinfo(connection
->connection
,
5589 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5590 case 26: /* CURLINFO_NUM_CONNECTS */
5591 resultType
= LongValue
;
5593 curlResult
= curl_easy_getinfo(connection
->connection
,
5594 CURLINFO_NUM_CONNECTS
,
5599 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5600 case 27: /* CURLINFO_SSL_ENGINES */
5601 resultType
= StringListValue
;
5603 curlResult
= curl_easy_getinfo(connection
->connection
,
5604 CURLINFO_SSL_ENGINES
,
5609 #if HAVE_DECL_CURLINFO_COOKIELIST
5610 case 28: /* CURLINFO_COOKIELIST */
5611 resultType
= StringListValue
;
5613 curlResult
= curl_easy_getinfo(connection
->connection
,
5614 CURLINFO_COOKIELIST
,
5619 #if HAVE_DECL_CURLINFO_LASTSOCKET
5620 case 29: /* CURLINFO_LASTSOCKET */
5621 resultType
= LongValue
;
5623 curlResult
= curl_easy_getinfo(connection
->connection
,
5624 CURLINFO_LASTSOCKET
,
5630 failwith("Invalid CURLINFO Option");
5634 if (curlResult
!= CURLE_OK
)
5635 raiseError(connection
, curlResult
);
5640 result
= alloc(1, StringValue
);
5642 libcurl can return NULL, e.g. for CONTENT_TYPE or PRIVATE
5643 alternative: add StringOptionValue and break API..
5645 Store_field(result
, 0, copy_string(strValue
?strValue
:""));
5649 result
= alloc(1, LongValue
);
5650 Store_field(result
, 0, Val_long(longValue
));
5654 result
= alloc(1, DoubleValue
);
5655 Store_field(result
, 0, copy_double(doubleValue
));
5658 case StringListValue
:
5659 result
= alloc(1, StringListValue
);
5660 Store_field(result
, 0, convertStringList(stringListValue
));
5668 ** curl_escape helper function
5671 CAMLprim value
helper_curl_escape(value str
)
5677 curlResult
= curl_escape(String_val(str
), string_length(str
));
5678 result
= copy_string(curlResult
);
5685 ** curl_unescape helper function
5688 CAMLprim value
helper_curl_unescape(value str
)
5694 curlResult
= curl_unescape(String_val(str
), string_length(str
));
5695 result
= copy_string(curlResult
);
5702 ** curl_getdate helper function
5705 CAMLprim value
helper_curl_getdate(value str
, value now
)
5707 CAMLparam2(str
, now
);
5712 curlNow
= (time_t)Double_val(now
);
5713 curlResult
= curl_getdate(String_val(str
), &curlNow
);
5714 result
= copy_double((double)curlResult
);
5720 ** curl_version helper function
5723 CAMLprim value
helper_curl_version(void)
5729 str
= curl_version();
5730 result
= copy_string(str
);
5736 * Curl multi stack support
5738 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5739 * Other exported functions are prefixed with caml_curlm_, some of them
5740 * can/should be decomposed into smaller parts.
5743 struct ml_multi_handle
5746 value values
; /* callbacks */
5751 curlmopt_socket_function
,
5753 /* last, not used */
5757 typedef struct ml_multi_handle ml_multi_handle
;
5759 #define Multi_val(v) (*(ml_multi_handle**)Data_custom_val(v))
5760 #define CURLM_val(v) (Multi_val(v)->handle)
5762 static struct custom_operations curl_multi_ops
= {
5764 custom_finalize_default
,
5765 custom_compare_default
,
5766 custom_hash_default
,
5767 custom_serialize_default
,
5768 custom_deserialize_default
5771 CAMLprim value
caml_curl_multi_init(value unit
)
5775 ml_multi_handle
* multi
= (ml_multi_handle
*)caml_stat_alloc(sizeof(ml_multi_handle
));
5776 CURLM
* h
= curl_multi_init();
5780 caml_stat_free(multi
);
5781 failwith("caml_curl_multi_init");
5785 multi
->values
= caml_alloc(multi_values_total
, 0);
5786 caml_register_generational_global_root(&multi
->values
);
5788 v
= caml_alloc_custom(&curl_multi_ops
, sizeof(ml_multi_handle
*), 0, 1);
5789 Multi_val(v
) = multi
;
5794 CAMLprim value
caml_curl_multi_cleanup(value handle
)
5797 ml_multi_handle
* h
= Multi_val(handle
);
5800 CAMLreturn(Val_unit
);
5802 caml_remove_generational_global_root(&h
->values
);
5804 if (CURLM_OK
!= curl_multi_cleanup(h
->handle
))
5805 failwith("caml_curl_multi_cleanup");
5807 Multi_val(handle
) = (ml_multi_handle
*)NULL
;
5809 CAMLreturn(Val_unit
);
5812 static CURL
* curlm_remove_finished(CURLM
* multi_handle
)
5814 int msgs_in_queue
= 0;
5818 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
5819 if (NULL
== msg
) return NULL
;
5820 if (CURLMSG_DONE
== msg
->msg
)
5822 CURL
* easy_handle
= msg
->easy_handle
;
5823 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
5825 //failwith("curlm_remove_finished");
5832 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
5834 CAMLparam1(v_multi
);
5837 CURLM
* multi_handle
;
5839 multi_handle
= CURLM_val(v_multi
);
5841 caml_enter_blocking_section();
5842 handle
= curlm_remove_finished(multi_handle
);
5843 caml_leave_blocking_section();
5847 CAMLreturn(Val_none
);
5852 v_easy
= alloc(1, Abstract_tag
);
5853 Store_field(v_easy
, 0, (value
)findConnection(handle
));
5854 CAMLreturn(Val_some(v_easy
));
5858 static int curlm_wait_data(CURLM
* multi_handle
)
5860 struct timeval timeout
;
5871 /* set a suitable timeout */
5873 timeout
.tv_usec
= 0;
5875 /* get file descriptors from the transfers */
5876 CURLMcode ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
5878 if (ret
== CURLM_OK
&& maxfd
>= 0)
5880 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
5881 if (-1 != rc
) return 0;
5882 //printf("select error\n");
5886 //printf("curl_multi_fdset error\n");
5891 CAMLprim value
caml_curlm_wait_data(value v_multi
)
5893 CAMLparam1(v_multi
);
5897 h
= CURLM_val(v_multi
);
5899 caml_enter_blocking_section();
5900 ret
= curlm_wait_data(h
);
5901 caml_leave_blocking_section();
5903 CAMLreturn(Val_bool(0 == ret
));
5906 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
5908 CAMLparam2(v_multi
,v_easy
);
5910 if (CURLM_OK
!= curl_multi_add_handle(CURLM_val(v_multi
), Connection_val(v_easy
)->connection
))
5911 failwith("caml_curl_multi_add_handle");
5913 CAMLreturn(Val_unit
);
5916 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
5918 CAMLparam1(v_multi
);
5920 int still_running
= 0;
5922 h
= CURLM_val(v_multi
);
5924 caml_enter_blocking_section();
5925 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
5926 caml_leave_blocking_section();
5928 CAMLreturn(Val_int(still_running
));
5932 * Wrappers for the curl_multi_socket_action infrastructure
5933 * Based on curl hiperfifo.c example
5936 /* FIXME win32unix */
5937 #define Socket_val(v) Int_val(v)
5938 #define Val_socket(v) Val_int(v)
5940 CAMLprim value
caml_curl_multi_socket_action(value v_multi
, value v_fd
, value v_kind
)
5942 CAMLparam3(v_multi
, v_fd
, v_kind
);
5943 CURLM
* h
= CURLM_val(v_multi
);
5944 int still_running
= 0;
5946 int kind
= 0; /* FIXME */
5947 (void)v_kind
; /* unused */
5950 rc
= curl_multi_socket_action(h
, Socket_val(v_fd
), kind
, &still_running
);
5951 } while (rc
== CURLM_CALL_MULTI_PERFORM
);
5952 /* mcode_or_die("event_cb: curl_multi_socket", rc);*/
5955 if ( g->still_running <= 0 ) {
5956 fprintf(MSG_OUT, "last transfer done, kill timeout\n");
5957 if (evtimer_pending(&g->timer_event, NULL)) {
5958 evtimer_del(&g->timer_event);
5962 CAMLreturn(Val_int(still_running
));
5965 CAMLprim value
caml_curl_multi_socket_all(value v_multi
)
5967 CAMLparam1(v_multi
);
5968 int still_running
= 0;
5969 CURLM
* h
= CURLM_val(v_multi
);
5971 caml_enter_blocking_section();
5972 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_socket_all(h
, &still_running
));
5973 caml_leave_blocking_section();
5975 CAMLreturn(Val_int(still_running
));
5978 static int curlm_sock_cb(CURL
*e
, curl_socket_t sock
, int what
, void *cbp
, void *sockp
)
5981 CAMLlocal2(v
,v_what
);
5982 ml_multi_handle
*multi
= (ml_multi_handle
*) cbp
;
5984 v
= caml_alloc_custom(&curl_multi_ops
, sizeof(ml_multi_handle
*), 0, 1);
5985 Multi_val(v
) = multi
;
5987 if (what
>=0 && what
<= 4)
5989 v_what
= Val_int(what
);
5997 callback3(Field(multi
->values
,curlmopt_socket_function
),
5998 v
, Val_socket(sock
), v_what
);
6003 CAMLprim value
caml_curl_multi_socketfunction(value v_multi
, value v_cb
)
6005 CAMLparam2(v_multi
, v_cb
);
6006 ml_multi_handle
* multi
= Multi_val(v_multi
);
6008 Store_field(multi
->values
, curlmopt_socket_function
, v_cb
);
6010 curl_multi_setopt(multi
->handle
, CURLMOPT_SOCKETFUNCTION
, curlm_sock_cb
);
6011 curl_multi_setopt(multi
->handle
, CURLMOPT_SOCKETDATA
, multi
);
6013 CAMLreturn(Val_unit
);