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>
22 #warning "No config file given."
31 void leave_blocking_section(void);
32 void enter_blocking_section(void);
34 #define Val_none Val_int(0)
41 some
= caml_alloc(1, 0);
42 Store_field( some
, 0, v
);
46 typedef struct Connection Connection
;
47 typedef struct ConnectionList ConnectionList
;
49 #define Connection_val(v) ((Connection *)Field(v, 0))
62 OcamlProgressCallback
,
66 OcamlSeekFunctionCallback
,
98 OcamlFTPAlternativeToUser
,
99 OcamlSSHPublicKeyFile
,
100 OcamlSSHPrivateKeyFile
,
101 OcamlSSHHostPublicKeyMD5
,
104 /* Not used, last for size */
128 struct curl_slist
*httpHeader
;
129 struct curl_httppost
*httpPostFirst
;
130 struct curl_httppost
*httpPostLast
;
131 struct curl_slist
*httpPostStrings
;
139 struct curl_slist
*quote
;
140 struct curl_slist
*postQuote
;
151 struct curl_slist
*http200Aliases
;
155 char *ftpAlternativeToUser
;
156 char *sshPublicKeyFile
;
157 char *sshPrivateKeyFile
;
158 char *sshHostPublicKeyMD5
;
159 char *copyPostFields
;
162 struct ConnectionList
168 static ConnectionList connectionList
= {NULL
, NULL
};
170 typedef struct CURLErrorMapping CURLErrorMapping
;
172 struct CURLErrorMapping
178 CURLErrorMapping errorMap
[] =
180 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
181 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL
},
183 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
185 #if HAVE_DECL_CURLE_FAILED_INIT
186 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT
},
188 {"CURLE_FAILED_INIT", -1},
190 #if HAVE_DECL_CURLE_URL_MALFORMAT
191 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT
},
193 {"CURLE_URL_MALFORMAT", -1},
195 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
196 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER
},
198 {"CURLE_URL_MALFORMAT_USER", -1},
200 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
201 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY
},
203 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
205 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
206 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST
},
208 {"CURLE_COULDNT_RESOLVE_HOST", -1},
210 #if HAVE_DECL_CURLE_COULDNT_CONNECT
211 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT
},
213 {"CURLE_COULDNT_CONNECT", -1},
215 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
216 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY
},
218 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
220 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
221 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED
},
223 {"CURLE_FTP_ACCESS_DENIED", -1},
225 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
226 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT
},
228 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
230 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
231 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY
},
233 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
235 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
236 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY
},
238 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
240 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
241 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY
},
243 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
245 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
246 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT
},
248 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
250 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
251 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST
},
253 {"CURLE_FTP_CANT_GET_HOST", -1},
255 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
256 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT
},
258 {"CURLE_FTP_CANT_RECONNECT", -1},
260 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
261 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY
},
263 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
265 #if HAVE_DECL_CURLE_PARTIAL_FILE
266 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE
},
268 {"CURLE_PARTIAL_FILE", -1},
270 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
271 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE
},
273 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
275 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
276 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR
},
278 {"CURLE_FTP_WRITE_ERROR", -1},
280 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
281 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR
},
283 {"CURLE_FTP_QUOTE_ERROR", -1},
285 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
286 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND
},
288 {"CURLE_HTTP_NOT_FOUND", -1},
290 #if HAVE_DECL_CURLE_WRITE_ERROR
291 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR
},
293 {"CURLE_WRITE_ERROR", -1},
295 #if HAVE_DECL_CURLE_MALFORMAT_USER
296 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER
},
298 {"CURLE_MALFORMAT_USER", -1},
300 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
301 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE
},
303 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
305 #if HAVE_DECL_CURLE_READ_ERROR
306 {"CURLE_READ_ERROR", CURLE_READ_ERROR
},
308 {"CURLE_READ_ERROR", -1},
310 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
311 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY
},
313 {"CURLE_OUT_OF_MEMORY", -1},
315 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
316 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED
},
318 {"CURLE_OPERATION_TIMEOUTED", -1},
320 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
321 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII
},
323 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
325 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
326 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED
},
328 {"CURLE_FTP_PORT_FAILED", -1},
330 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
331 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST
},
333 {"CURLE_FTP_COULDNT_USE_REST", -1},
335 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
336 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE
},
338 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
340 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
341 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR
},
343 {"CURLE_HTTP_RANGE_ERROR", -1},
345 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
346 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR
},
348 {"CURLE_HTTP_POST_ERROR", -1},
350 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
351 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR
},
353 {"CURLE_SSL_CONNECT_ERROR", -1},
355 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
356 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME
},
358 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
360 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
361 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE
},
363 {"CURLE_FILE_COULDNT_READ_FILE", -1},
365 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
366 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND
},
368 {"CURLE_LDAP_CANNOT_BIND", -1},
370 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
371 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED
},
373 {"CURLE_LDAP_SEARCH_FAILED", -1},
375 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
376 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND
},
378 {"CURLE_LIBRARY_NOT_FOUND", -1},
380 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
381 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND
},
383 {"CURLE_FUNCTION_NOT_FOUND", -1},
385 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
386 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK
},
388 {"CURLE_ABORTED_BY_CALLBACK", -1},
390 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
391 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT
},
393 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
395 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
396 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER
},
398 {"CURLE_BAD_CALLING_ORDER", -1},
400 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
401 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED
},
403 {"CURLE_HTTP_PORT_FAILED", -1},
405 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
406 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED
},
408 {"CURLE_BAD_PASSWORD_ENTERED", -1},
410 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
411 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS
},
413 {"CURLE_TOO_MANY_REDIRECTS", -1},
415 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
416 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION
},
418 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
420 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
421 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX
},
423 {"CURLE_TELNET_OPTION_SYNTAX", -1},
425 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
426 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE
},
428 {"CURLE_SSL_PEER_CERTIFICATE", -1},
430 #if HAVE_DECL_CURLE_GOT_NOTHING
431 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING
},
433 {"CURLE_GOT_NOTHING", -1},
435 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
436 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND
},
438 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
440 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
441 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED
},
443 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
445 #if HAVE_DECL_CURLE_SEND_ERROR
446 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR
},
448 {"CURLE_SEND_ERROR", -1},
450 #if HAVE_DECL_CURLE_RECV_ERROR
451 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR
},
453 {"CURLE_RECV_ERROR", -1},
455 #if HAVE_DECL_CURLE_SHARE_IN_USE
456 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE
},
458 {"CURLE_SHARE_IN_USE", -1},
460 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
461 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM
},
463 {"CURLE_SSL_CERTPROBLEN", -1},
465 #if HAVE_DECL_CURLE_SSL_CIPHER
466 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER
},
468 {"CURLE_SSL_CIPHER", -1},
470 #if HAVE_DECL_CURLE_SSL_CACERT
471 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT
},
473 {"CURLE_SSL_CACERT", -1},
475 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
476 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING
},
478 {"CURLE_BAD_CONTENT_ENCODING", -1},
480 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
481 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL
},
483 {"CURLE_LDAP_INVALID_URL", -1},
485 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
486 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED
},
488 {"CURLE_FILESIZE_EXCEEDED", -1},
490 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
491 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED
},
493 {"CURLE_FTP_SSL_FAILED", -1},
495 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
496 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND
},
498 {"CURLE_SEND_FAIL_REWIND", -1},
500 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
501 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED
},
503 {"CURLE_SSL_ENGINE_INITFAILED", -1},
505 #if HAVE_DECL_CURLE_LOGIN_DENIED
506 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED
},
508 {"CURLE_LOGIN_DENIED", -1},
510 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
511 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND
},
513 {"CURLE_TFTP_NOTFOUND", -1},
515 #if HAVE_DECL_CURLE_TFTP_PERM
516 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM
},
518 {"CURLE_TFTP_PERM", -1},
520 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
521 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL
},
523 {"CURLE_REMOTE_DISK_FULL", -1},
525 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
526 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL
},
528 {"CURLE_TFTP_ILLEGAL", -1},
530 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
531 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID
},
533 {"CURLE_TFTP_UNKNOWNID", -1},
535 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
536 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS
},
538 {"CURLE_REMOTE_FILE_EXISTS", -1},
540 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
541 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER
},
543 {"CURLE_TFTP_NOSUCHUSER", -1},
545 #if HAVE_DECL_CURLE_CONV_FAILED
546 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED
},
548 {"CURLE_CONV_FAILED", -1},
550 #if HAVE_DECL_CURLE_CONV_REQUIRED
551 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED
},
553 {"CURLE_CONV_REQUIRED", -1},
555 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
556 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE
},
558 {"CURLE_SSL_CACERT_BADFILE", -1},
560 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
561 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND
},
563 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
565 #if HAVE_DECL_CURLE_SSH
566 {"CURLE_SSH", CURLE_SSH
},
570 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
571 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED
},
573 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
575 #if HAVE_DECL_CURLE_AGAIN
576 {"CURLE_AGAIN", CURLE_AGAIN
},
580 {"CURLE_OK", CURLE_OK
},
584 typedef struct CURLOptionMapping CURLOptionMapping
;
586 struct CURLOptionMapping
588 void (*optionHandler
)(Connection
*, value
);
593 CURLOptionMapping unimplementedOptionMap
[] =
595 {NULL
, "CURLOPT_STDERR", CURLOPT_STDERR
},
599 static void handleWriteFunction(Connection
*, value
);
600 static void handleReadFunction(Connection
*, value
);
601 static void handleInFileSize(Connection
*, value
);
602 static void handleURL(Connection
*, value
);
603 static void handleProxy(Connection
*, value
);
604 static void handleProxyPort(Connection
*, value
);
605 static void handleHTTPProxyTunnel(Connection
*, value
);
606 static void handleVerbose(Connection
*, value
);
607 static void handleHeader(Connection
*, value
);
608 static void handleNoProgress(Connection
*, value
);
609 static void handleNoSignal(Connection
*, value
);
610 static void handleNoBody(Connection
*, value
);
611 static void handleFailOnError(Connection
*, value
);
612 static void handleUpload(Connection
*, value
);
613 static void handlePost(Connection
*, value
);
614 static void handleFTPListOnly(Connection
*, value
);
615 static void handleFTPAppend(Connection
*, value
);
616 static void handleNETRC(Connection
*, value
);
617 static void handleEncoding(Connection
*, value
);
618 static void handleFollowLocation(Connection
*, value
);
619 static void handleTransferText(Connection
*, value
);
620 static void handlePut(Connection
*, value
);
621 static void handleUserPwd(Connection
*, value
);
622 static void handleProxyUserPwd(Connection
*, value
);
623 static void handleRange(Connection
*, value
);
624 static void handleErrorBuffer(Connection
*, value
);
625 static void handleTimeout(Connection
*, value
);
626 static void handlePostFields(Connection
*, value
);
627 static void handlePostFieldSize(Connection
*, value
);
628 static void handleReferer(Connection
*, value
);
629 static void handleUserAgent(Connection
*, value
);
630 static void handleFTPPort(Connection
*, value
);
631 static void handleLowSpeedLimit(Connection
*, value
);
632 static void handleLowSpeedTime(Connection
*, value
);
633 static void handleResumeFrom(Connection
*, value
);
634 static void handleCookie(Connection
*, value
);
635 static void handleHTTPHeader(Connection
*, value
);
636 static void handleHTTPPost(Connection
*, value
);
637 static void handleSSLCert(Connection
*, value
);
638 static void handleSSLCertType(Connection
*, value
);
639 static void handleSSLCertPasswd(Connection
*, value
);
640 static void handleSSLKey(Connection
*, value
);
641 static void handleSSLKeyType(Connection
*, value
);
642 static void handleSSLKeyPasswd(Connection
*, value
);
643 static void handleSSLEngine(Connection
*, value
);
644 static void handleSSLEngineDefault(Connection
*, value
);
645 static void handleCRLF(Connection
*, value
);
646 static void handleQuote(Connection
*, value
);
647 static void handlePostQuote(Connection
*, value
);
648 static void handleHeaderFunction(Connection
*, value
);
649 static void handleCookieFile(Connection
*, value
);
650 static void handleSSLVersion(Connection
*, value
);
651 static void handleTimeCondition(Connection
*, value
);
652 static void handleTimeValue(Connection
*, value
);
653 static void handleCustomRequest(Connection
*, value
);
654 static void handleInterface(Connection
*, value
);
655 static void handleKRB4Level(Connection
*, value
);
656 static void handleProgressFunction(Connection
*, value
);
657 static void handleSSLVerifyPeer(Connection
*, value
);
658 static void handleCAInfo(Connection
*, value
);
659 static void handleCAPath(Connection
*, value
);
660 static void handleFileTime(Connection
*, value
);
661 static void handleMaxRedirs(Connection
*, value
);
662 static void handleMaxConnects(Connection
*, value
);
663 static void handleClosePolicy(Connection
*, value
);
664 static void handleFreshConnect(Connection
*, value
);
665 static void handleForbidReuse(Connection
*, value
);
666 static void handleRandomFile(Connection
*, value
);
667 static void handleEGDSocket(Connection
*, value
);
668 static void handleConnectTimeout(Connection
*, value
);
669 static void handleHTTPGet(Connection
*, value
);
670 static void handleSSLVerifyHost(Connection
*, value
);
671 static void handleCookieJar(Connection
*, value
);
672 static void handleSSLCipherList(Connection
*, value
);
673 static void handleHTTPVersion(Connection
*, value
);
674 static void handleFTPUseEPSV(Connection
*, value
);
675 static void handleDNSCacheTimeout(Connection
*, value
);
676 static void handleDNSUseGlobalCache(Connection
*, value
);
677 static void handleDebugFunction(Connection
*, value
);
678 static void handlePrivate(Connection
*, value
);
679 static void handleHTTP200Aliases(Connection
*, value
);
680 static void handleUnrestrictedAuth(Connection
*, value
);
681 static void handleFTPUseEPRT(Connection
*, value
);
682 static void handleHTTPAuth(Connection
*, value
);
683 static void handleFTPCreateMissingDirs(Connection
*, value
);
684 static void handleProxyAuth(Connection
*, value
);
685 static void handleFTPResponseTimeout(Connection
*, value
);
686 static void handleIPResolve(Connection
*, value
);
687 static void handleMaxFileSize(Connection
*, value
);
688 static void handleInFileSizeLarge(Connection
*, value
);
689 static void handleResumeFromLarge(Connection
*, value
);
690 static void handleMaxFileSizeLarge(Connection
*, value
);
691 static void handleNETRCFile(Connection
*, value
);
692 static void handleFTPSSL(Connection
*, value
);
693 static void handlePostFieldSizeLarge(Connection
*, value
);
694 static void handleTCPNoDelay(Connection
*, value
);
695 static void handleFTPSSLAuth(Connection
*, value
);
696 static void handleIOCTLFunction(Connection
*, value
);
697 static void handleFTPAccount(Connection
*, value
);
698 static void handleCookieList(Connection
*, value
);
699 static void handleIgnoreContentLength(Connection
*, value
);
700 static void handleFTPSkipPASVIP(Connection
*, value
);
701 static void handleFTPFileMethod(Connection
*, value
);
702 static void handleLocalPort(Connection
*, value
);
703 static void handleLocalPortRange(Connection
*, value
);
704 static void handleConnectOnly(Connection
*, value
);
705 static void handleMaxSendSpeedLarge(Connection
*, value
);
706 static void handleMaxRecvSpeedLarge(Connection
*, value
);
707 static void handleFTPAlternativeToUser(Connection
*, value
);
708 static void handleSSLSessionIdCache(Connection
*, value
);
709 static void handleSSHAuthTypes(Connection
*, value
);
710 static void handleSSHPublicKeyFile(Connection
*, value
);
711 static void handleSSHPrivateKeyFile(Connection
*, value
);
712 static void handleFTPSSLCCC(Connection
*, value
);
713 static void handleTimeoutMS(Connection
*, value
);
714 static void handleConnectTimeoutMS(Connection
*, value
);
715 static void handleHTTPTransferDecoding(Connection
*, value
);
716 static void handleHTTPContentDecoding(Connection
*, value
);
717 static void handleNewFilePerms(Connection
*, value
);
718 static void handleNewDirectoryPerms(Connection
*, value
);
719 static void handlePost301(Connection
*, value
);
720 static void handleSSHHostPublicKeyMD5(Connection
*, value
);
721 static void handleCopyPostFields(Connection
*, value
);
722 static void handleProxyTransferMode(Connection
*, value
);
723 static void handleSeekFunction(Connection
*, value
);
725 CURLOptionMapping implementedOptionMap
[] =
727 {handleWriteFunction
, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION
},
728 {handleReadFunction
, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION
},
729 {handleInFileSize
, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE
},
730 {handleURL
, "CURLOPT_URL", CURLOPT_URL
},
731 {handleProxy
, "CURLOPT_PROXY", CURLOPT_PROXY
},
732 {handleProxyPort
, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT
},
733 {handleHTTPProxyTunnel
, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL
},
734 {handleVerbose
, "CURLOPT_VERBOSE", CURLOPT_VERBOSE
},
735 {handleHeader
, "CURLOPT_HEADER", CURLOPT_HEADER
},
736 {handleNoProgress
, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS
},
737 #if HAVE_DECL_CURLOPT_NOSIGNAL
738 {handleNoSignal
, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL
},
740 {handleNoSignal
, "CURLOPT_NOSIGNAL", 0},
742 {handleNoBody
, "CURLOPT_NOBODY", CURLOPT_NOBODY
},
743 {handleFailOnError
, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR
},
744 {handleUpload
, "CURLOPT_UPLOAD", CURLOPT_UPLOAD
},
745 {handlePost
, "CURLOPT_POST", CURLOPT_POST
},
746 {handleFTPListOnly
, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY
},
747 {handleFTPAppend
, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND
},
748 {handleNETRC
, "CURLOPT_NETRC", CURLOPT_NETRC
},
749 #if HAVE_DECL_CURLOPT_ENCODING
750 {handleEncoding
, "CURLOPT_ENCODING", CURLOPT_ENCODING
},
752 {handleEncoding
, "CURLOPT_ENCODING", 0},
754 {handleFollowLocation
, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION
},
755 {handleTransferText
, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT
},
756 {handlePut
, "CURLOPT_PUT", CURLOPT_PUT
},
757 {handleUserPwd
, "CURLOPT_USERPWD", CURLOPT_USERPWD
},
758 {handleProxyUserPwd
, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD
},
759 {handleRange
, "CURLOPT_RANGE", CURLOPT_RANGE
},
760 {handleErrorBuffer
, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER
},
761 {handleTimeout
, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT
},
762 {handlePostFields
, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS
},
763 {handlePostFieldSize
, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE
},
764 {handleReferer
, "CURLOPT_REFERER", CURLOPT_REFERER
},
765 {handleUserAgent
, "CURLOPT_USERAGENT", CURLOPT_USERAGENT
},
766 {handleFTPPort
, "CURLOPT_FTPPORT", CURLOPT_FTPPORT
},
767 {handleLowSpeedLimit
, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT
},
768 {handleLowSpeedTime
, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME
},
769 {handleResumeFrom
, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM
},
770 {handleCookie
, "CURLOPT_COOKIE", CURLOPT_COOKIE
},
771 {handleHTTPHeader
, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER
},
772 {handleHTTPPost
, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST
},
773 {handleSSLCert
, "CURLOPT_SSLCERT", CURLOPT_SSLCERT
},
774 {handleSSLCertType
, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE
},
775 {handleSSLCertPasswd
, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD
},
776 {handleSSLKey
, "CURLOPT_SSLKEY", CURLOPT_SSLKEY
},
777 {handleSSLKeyType
, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE
},
778 {handleSSLKeyPasswd
, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD
},
779 {handleSSLEngine
, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE
},
780 {handleSSLEngineDefault
, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT
},
781 {handleCRLF
, "CURLOPT_CRLF", CURLOPT_CRLF
},
782 {handleQuote
, "CURLOPT_QUOTE", CURLOPT_QUOTE
},
783 {handlePostQuote
, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE
},
784 {handleHeaderFunction
, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION
},
785 {handleCookieFile
, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE
},
786 {handleSSLVersion
, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION
},
787 {handleTimeCondition
, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION
},
788 {handleTimeValue
, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE
},
789 {handleCustomRequest
, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST
},
790 {handleInterface
, "CURLOPT_INTERFACE", CURLOPT_INTERFACE
},
791 {handleKRB4Level
, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL
},
792 {handleProgressFunction
, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION
},
793 {handleSSLVerifyPeer
, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER
},
794 {handleCAInfo
, "CURLOPT_CAINFO", CURLOPT_CAINFO
},
795 {handleCAPath
, "CURLOPT_CAPATH", CURLOPT_CAPATH
},
796 {handleFileTime
, "CURLOPT_FILETIME", CURLOPT_FILETIME
},
797 {handleMaxRedirs
, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS
},
798 {handleMaxConnects
, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS
},
799 {handleClosePolicy
, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY
},
800 {handleFreshConnect
, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT
},
801 {handleForbidReuse
, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE
},
802 {handleRandomFile
, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE
},
803 {handleEGDSocket
, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET
},
804 {handleConnectTimeout
, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT
},
805 {handleHTTPGet
, "CURLOPT_HTTPGET", CURLOPT_HTTPGET
},
806 {handleSSLVerifyHost
, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST
},
807 {handleCookieJar
, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR
},
808 {handleSSLCipherList
, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST
},
809 {handleHTTPVersion
, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION
},
810 {handleFTPUseEPSV
, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV
},
811 {handleDNSCacheTimeout
, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT
},
812 {handleDNSUseGlobalCache
, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE
},
813 {handleDebugFunction
, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION
},
814 #if HAVE_DECL_CURLOPT_PRIVATE
815 {handlePrivate
, "CURLOPT_PRIVATE", CURLOPT_PRIVATE
},
817 {handlePrivate
, "CURLOPT_PRIVATE", 0},
819 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
820 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES
},
822 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", 0},
824 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
825 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH
},
827 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", 0},
829 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
830 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT
},
832 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", 0},
834 #if HAVE_DECL_CURLOPT_HTTPAUTH
835 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH
},
837 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", 0},
839 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
840 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS
},
842 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
844 #if HAVE_DECL_CURLOPT_PROXYAUTH
845 {handleProxyAuth
, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH
},
847 {handleProxyAuth
, "CURLOPT_PROXYAUTH", 0},
849 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
850 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT
},
852 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
854 #if HAVE_DECL_CURLOPT_IPRESOLVE
855 {handleIPResolve
, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE
},
857 {handleIPResolve
, "CURLOPT_IPRESOLVE", 0},
859 #if HAVE_DECL_CURLOPT_MAXFILESIZE
860 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE
},
862 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", 0},
864 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
865 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE
},
867 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", 0},
869 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
870 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE
},
872 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", 0},
874 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
875 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE
},
877 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", 0},
879 #if HAVE_DECL_CURLOPT_NETRC_FILE
880 {handleNETRCFile
, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE
},
882 {handleNETRCFile
, "CURLOPT_NETRC_FILE", 0},
884 #if HAVE_DECL_CURLOPT_FTP_SSL
885 {handleFTPSSL
, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL
},
887 {handleFTPSSL
, "CURLOPT_FTP_SSL", 0},
889 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
890 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE
},
892 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
894 #if HAVE_DECL_CURLOPT_TCP_NODELAY
895 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY
},
897 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", 0},
899 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
900 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH
},
902 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", 0},
904 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
905 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION
},
907 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", 0},
909 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
910 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT
},
912 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", 0},
914 #if HAVE_DECL_CURLOPT_COOKIELIST
915 {handleCookieList
, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST
},
917 {handleCookieList
, "CURLOPT_COOKIELIST", 0},
919 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
920 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH
},
922 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
924 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
925 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP
},
927 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", 0},
929 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
930 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD
},
932 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", 0},
934 #if HAVE_DECL_CURLOPT_LOCALPORT
935 {handleLocalPort
, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT
},
937 {handleLocalPort
, "CURLOPT_LOCALPORT", 0},
939 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
940 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE
},
942 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", 0},
944 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
945 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY
},
947 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", 0},
949 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
950 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE
},
952 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
954 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
955 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE
},
957 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
959 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
960 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER
},
962 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
964 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
965 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE
},
967 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", 0},
969 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
970 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES
},
972 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", 0},
974 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
975 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE
},
977 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
979 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
980 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE
},
982 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
984 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
985 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC
},
987 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", 0},
989 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
990 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS
},
992 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", 0},
994 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
995 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS
},
997 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", 0},
999 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
1000 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING
},
1002 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
1004 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1005 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING
},
1007 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1009 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1010 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS
},
1012 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", 0},
1014 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1015 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS
},
1017 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1019 #if HAVE_DECL_CURLOPT_POST301
1020 {handlePost301
, "CURLOPT_POST301", CURLOPT_POST301
},
1022 {handlePost301
, "CURLOPT_POST301", 0},
1024 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1025 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
},
1027 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1029 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1030 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS
},
1032 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", 0},
1034 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1035 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE
},
1037 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1039 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1040 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION
},
1042 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", 0},
1046 static char *findOption(CURLOptionMapping optionMap
[],
1049 return optionMap
[option
].name
;
1052 static void free_curl_slist(struct curl_slist
*slist
)
1054 struct curl_slist
*item
;
1061 while (item
!= NULL
)
1068 curl_slist_free_all(slist
);
1071 static void raiseError(Connection
*conn
, CURLcode code
)
1074 CAMLlocal1(exceptionData
);
1076 char *errorString
= "Unknown Error";
1079 for (i
= 0; errorMap
[i
].name
!= NULL
; i
++)
1081 if (errorMap
[i
].error
== code
)
1083 errorString
= errorMap
[i
].name
;
1088 exceptionData
= alloc(3, 0);
1090 Field(exceptionData
, 0) = Val_int(code
);
1091 Field(exceptionData
, 1) = Val_int(code
);
1092 Field(exceptionData
, 2) = copy_string(errorString
);
1094 if (conn
!= NULL
&& conn
->errorBuffer
!= NULL
)
1096 Field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0) =
1097 copy_string(conn
->errorBuffer
);
1100 exception
= caml_named_value("CurlException");
1102 if (exception
== NULL
)
1103 failwith(errorString
);
1105 raise_with_arg(*exception
, exceptionData
);
1110 static void resetOcamlValues(Connection
* connection
)
1114 for (i
= 0; i
< OcamlValuesSize
; i
++)
1115 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1118 static Connection
*newConnection(void)
1120 Connection
*connection
;
1122 connection
= (Connection
*)malloc(sizeof(Connection
));
1124 enter_blocking_section();
1125 connection
->connection
= curl_easy_init();
1126 leave_blocking_section();
1128 connection
->next
= NULL
;
1129 connection
->prev
= NULL
;
1131 if (connectionList
.tail
== NULL
)
1133 connectionList
.tail
= connection
;
1134 connectionList
.head
= connection
;
1138 connection
->prev
= connectionList
.head
;
1139 connectionList
.head
->next
= connection
;
1140 connectionList
.head
= connection
;
1143 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1144 resetOcamlValues(connection
);
1145 register_global_root(&connection
->ocamlValues
);
1147 connection
->url
= NULL
;
1148 connection
->proxy
= NULL
;
1149 connection
->userPwd
= NULL
;
1150 connection
->proxyUserPwd
= NULL
;
1151 connection
->range
= NULL
;
1152 connection
->errorBuffer
= NULL
;
1153 connection
->postFields
= NULL
;
1154 connection
->postFieldSize
= -1;
1155 connection
->referer
= NULL
;
1156 connection
->userAgent
= NULL
;
1157 connection
->ftpPort
= NULL
;
1158 connection
->cookie
= NULL
;
1159 connection
->httpHeader
= NULL
;
1160 connection
->httpPostFirst
= NULL
;
1161 connection
->httpPostLast
= NULL
;
1162 connection
->httpPostStrings
= NULL
;
1163 connection
->sslCert
= NULL
;
1164 connection
->sslCertType
= NULL
;
1165 connection
->sslCertPasswd
= NULL
;
1166 connection
->sslKey
= NULL
;
1167 connection
->sslKeyType
= NULL
;
1168 connection
->sslKeyPasswd
= NULL
;
1169 connection
->sslEngine
= NULL
;
1170 connection
->quote
= NULL
;
1171 connection
->postQuote
= NULL
;
1172 connection
->cookieFile
= NULL
;
1173 connection
->customRequest
= NULL
;
1174 connection
->interface
= NULL
;
1175 connection
->caInfo
= NULL
;
1176 connection
->caPath
= NULL
;
1177 connection
->randomFile
= NULL
;
1178 connection
->egdSocket
= NULL
;
1179 connection
->cookieJar
= NULL
;
1180 connection
->sslCipherList
= NULL
;
1181 connection
->private = NULL
;
1182 connection
->http200Aliases
= NULL
;
1183 connection
->netrcFile
= NULL
;
1184 connection
->ftpaccount
= NULL
;
1185 connection
->cookielist
= NULL
;
1186 connection
->ftpAlternativeToUser
= NULL
;
1187 connection
->sshPublicKeyFile
= NULL
;
1188 connection
->sshPrivateKeyFile
= NULL
;
1189 connection
->copyPostFields
= NULL
;
1194 static Connection
*duplicateConnection(Connection
*original
)
1196 Connection
*connection
;
1198 connection
= (Connection
*)malloc(sizeof(Connection
));
1200 enter_blocking_section();
1201 connection
->connection
= curl_easy_duphandle(original
->connection
);
1202 leave_blocking_section();
1204 connection
->next
= NULL
;
1205 connection
->prev
= NULL
;
1207 if (connectionList
.tail
== NULL
)
1209 connectionList
.tail
= connection
;
1210 connectionList
.head
= connection
;
1214 connection
->prev
= connectionList
.head
;
1215 connectionList
.head
->next
= connection
;
1216 connectionList
.head
= connection
;
1219 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1220 resetOcamlValues(connection
);
1221 register_global_root(&connection
->ocamlValues
);
1223 Store_field(connection
->ocamlValues
, OcamlWriteCallback
,
1224 Field(original
->ocamlValues
, OcamlWriteCallback
));
1225 Store_field(connection
->ocamlValues
, OcamlReadCallback
,
1226 Field(original
->ocamlValues
, OcamlReadCallback
));
1227 Store_field(connection
->ocamlValues
, OcamlErrorBuffer
,
1228 Field(original
->ocamlValues
, OcamlErrorBuffer
));
1229 Store_field(connection
->ocamlValues
, OcamlPostFields
,
1230 Field(original
->ocamlValues
, OcamlPostFields
));
1231 Store_field(connection
->ocamlValues
, OcamlHTTPHeader
,
1232 Field(original
->ocamlValues
, OcamlHTTPHeader
));
1233 Store_field(connection
->ocamlValues
, OcamlQuote
,
1234 Field(original
->ocamlValues
, OcamlQuote
));
1235 Store_field(connection
->ocamlValues
, OcamlPostQuote
,
1236 Field(original
->ocamlValues
, OcamlPostQuote
));
1237 Store_field(connection
->ocamlValues
, OcamlHeaderCallback
,
1238 Field(original
->ocamlValues
, OcamlHeaderCallback
));
1239 Store_field(connection
->ocamlValues
, OcamlProgressCallback
,
1240 Field(original
->ocamlValues
, OcamlProgressCallback
));
1241 Store_field(connection
->ocamlValues
, OcamlDebugCallback
,
1242 Field(original
->ocamlValues
, OcamlDebugCallback
));
1243 Store_field(connection
->ocamlValues
, OcamlHTTP200Aliases
,
1244 Field(original
->ocamlValues
, OcamlHTTP200Aliases
));
1245 Store_field(connection
->ocamlValues
, OcamlIOCTLCallback
,
1246 Field(original
->ocamlValues
, OcamlIOCTLCallback
));
1247 Store_field(connection
->ocamlValues
, OcamlSeekFunctionCallback
,
1248 Field(original
->ocamlValues
, OcamlSeekFunctionCallback
));
1250 connection
->url
= NULL
;
1251 connection
->proxy
= NULL
;
1252 connection
->userPwd
= NULL
;
1253 connection
->proxyUserPwd
= NULL
;
1254 connection
->range
= NULL
;
1255 connection
->errorBuffer
= NULL
;
1256 connection
->postFields
= NULL
;
1257 connection
->postFieldSize
= -1;
1258 connection
->referer
= NULL
;
1259 connection
->userAgent
= NULL
;
1260 connection
->ftpPort
= NULL
;
1261 connection
->cookie
= NULL
;
1262 connection
->httpHeader
= NULL
;
1263 connection
->httpPostFirst
= NULL
;
1264 connection
->httpPostLast
= NULL
;
1265 connection
->httpPostStrings
= NULL
;
1266 connection
->sslCert
= NULL
;
1267 connection
->sslCertType
= NULL
;
1268 connection
->sslCertPasswd
= NULL
;
1269 connection
->sslKey
= NULL
;
1270 connection
->sslKeyType
= NULL
;
1271 connection
->sslKeyPasswd
= NULL
;
1272 connection
->sslEngine
= NULL
;
1273 connection
->quote
= NULL
;
1274 connection
->postQuote
= NULL
;
1275 connection
->cookieFile
= NULL
;
1276 connection
->customRequest
= NULL
;
1277 connection
->interface
= NULL
;
1278 connection
->caInfo
= NULL
;
1279 connection
->caPath
= NULL
;
1280 connection
->randomFile
= NULL
;
1281 connection
->egdSocket
= NULL
;
1282 connection
->cookieJar
= NULL
;
1283 connection
->sslCipherList
= NULL
;
1284 connection
->private = NULL
;
1285 connection
->http200Aliases
= NULL
;
1286 connection
->netrcFile
= NULL
;
1287 connection
->ftpaccount
= NULL
;
1288 connection
->cookielist
= NULL
;
1289 connection
->sshPublicKeyFile
= NULL
;
1290 connection
->sshPrivateKeyFile
= NULL
;
1291 connection
->copyPostFields
= NULL
;
1293 if (Field(original
->ocamlValues
, OcamlURL
) != Val_unit
)
1294 handleURL(connection
, Field(original
->ocamlValues
,
1296 if (Field(original
->ocamlValues
, OcamlProxy
) != Val_unit
)
1297 handleProxy(connection
, Field(original
->ocamlValues
,
1299 if (Field(original
->ocamlValues
, OcamlUserPWD
) != Val_unit
)
1300 handleUserPwd(connection
, Field(original
->ocamlValues
,
1302 if (Field(original
->ocamlValues
, OcamlProxyUserPWD
) != Val_unit
)
1303 handleProxyUserPwd(connection
, Field(original
->ocamlValues
,
1304 OcamlProxyUserPWD
));
1305 if (Field(original
->ocamlValues
, OcamlRange
) != Val_unit
)
1306 handleRange(connection
, Field(original
->ocamlValues
,
1308 if (Field(original
->ocamlValues
, OcamlErrorBuffer
) != Val_unit
)
1309 handleErrorBuffer(connection
, Field(original
->ocamlValues
,
1311 if (Field(original
->ocamlValues
, OcamlPostFields
) != Val_unit
)
1312 handlePostFields(connection
, Field(original
->ocamlValues
,
1314 if (Field(original
->ocamlValues
, OcamlReferer
) != Val_unit
)
1315 handleReferer(connection
, Field(original
->ocamlValues
,
1317 if (Field(original
->ocamlValues
, OcamlUserAgent
) != Val_unit
)
1318 handleUserAgent(connection
, Field(original
->ocamlValues
,
1320 if (Field(original
->ocamlValues
, OcamlFTPPort
) != Val_unit
)
1321 handleFTPPort(connection
, Field(original
->ocamlValues
,
1323 if (Field(original
->ocamlValues
, OcamlCookie
) != Val_unit
)
1324 handleCookie(connection
, Field(original
->ocamlValues
,
1326 if (Field(original
->ocamlValues
, OcamlHTTPHeader
) != Val_unit
)
1327 handleHTTPHeader(connection
, Field(original
->ocamlValues
,
1329 if (Field(original
->ocamlValues
, OcamlHTTPPost
) != Val_unit
)
1330 handleHTTPPost(connection
, Field(original
->ocamlValues
,
1332 if (Field(original
->ocamlValues
, OcamlSSLCert
) != Val_unit
)
1333 handleSSLCert(connection
, Field(original
->ocamlValues
,
1335 if (Field(original
->ocamlValues
, OcamlSSLCertType
) != Val_unit
)
1336 handleSSLCertType(connection
, Field(original
->ocamlValues
,
1338 if (Field(original
->ocamlValues
, OcamlSSLCertPasswd
) != Val_unit
)
1339 handleSSLCertPasswd(connection
, Field(original
->ocamlValues
,
1340 OcamlSSLCertPasswd
));
1341 if (Field(original
->ocamlValues
, OcamlSSLKey
) != Val_unit
)
1342 handleSSLKey(connection
, Field(original
->ocamlValues
,
1344 if (Field(original
->ocamlValues
, OcamlSSLKeyType
) != Val_unit
)
1345 handleSSLKeyType(connection
, Field(original
->ocamlValues
,
1347 if (Field(original
->ocamlValues
, OcamlSSLKeyPasswd
) != Val_unit
)
1348 handleSSLKeyPasswd(connection
, Field(original
->ocamlValues
,
1349 OcamlSSLKeyPasswd
));
1350 if (Field(original
->ocamlValues
, OcamlSSLEngine
) != Val_unit
)
1351 handleSSLEngine(connection
, Field(original
->ocamlValues
,
1353 if (Field(original
->ocamlValues
, OcamlQuote
) != Val_unit
)
1354 handleQuote(connection
, Field(original
->ocamlValues
,
1356 if (Field(original
->ocamlValues
, OcamlPostQuote
) != Val_unit
)
1357 handlePostQuote(connection
, Field(original
->ocamlValues
,
1359 if (Field(original
->ocamlValues
, OcamlCookieFile
) != Val_unit
)
1360 handleCookieFile(connection
, Field(original
->ocamlValues
,
1362 if (Field(original
->ocamlValues
, OcamlCustomRequest
) != Val_unit
)
1363 handleCustomRequest(connection
, Field(original
->ocamlValues
,
1364 OcamlCustomRequest
));
1365 if (Field(original
->ocamlValues
, OcamlInterface
) != Val_unit
)
1366 handleInterface(connection
, Field(original
->ocamlValues
,
1368 if (Field(original
->ocamlValues
, OcamlCAInfo
) != Val_unit
)
1369 handleCAInfo(connection
, Field(original
->ocamlValues
,
1371 if (Field(original
->ocamlValues
, OcamlCAPath
) != Val_unit
)
1372 handleCAPath(connection
, Field(original
->ocamlValues
,
1374 if (Field(original
->ocamlValues
, OcamlRandomFile
) != Val_unit
)
1375 handleRandomFile(connection
, Field(original
->ocamlValues
,
1377 if (Field(original
->ocamlValues
, OcamlEGDSocket
) != Val_unit
)
1378 handleEGDSocket(connection
, Field(original
->ocamlValues
,
1380 if (Field(original
->ocamlValues
, OcamlCookieJar
) != Val_unit
)
1381 handleCookieJar(connection
, Field(original
->ocamlValues
,
1383 if (Field(original
->ocamlValues
, OcamlSSLCipherList
) != Val_unit
)
1384 handleSSLCipherList(connection
, Field(original
->ocamlValues
,
1385 OcamlSSLCipherList
));
1386 if (Field(original
->ocamlValues
, OcamlPrivate
) != Val_unit
)
1387 handlePrivate(connection
, Field(original
->ocamlValues
,
1389 if (Field(original
->ocamlValues
, OcamlHTTP200Aliases
) != Val_unit
)
1390 handleHTTP200Aliases(connection
, Field(original
->ocamlValues
,
1391 OcamlHTTP200Aliases
));
1392 if (Field(original
->ocamlValues
, OcamlNETRCFile
) != Val_unit
)
1393 handleNETRCFile(connection
, Field(original
->ocamlValues
,
1395 if (Field(original
->ocamlValues
, OcamlFTPAccount
) != Val_unit
)
1396 handleFTPAccount(connection
, Field(original
->ocamlValues
,
1398 if (Field(original
->ocamlValues
, OcamlCookieList
) != Val_unit
)
1399 handleCookieList(connection
, Field(original
->ocamlValues
,
1401 if (Field(original
->ocamlValues
, OcamlFTPAlternativeToUser
) != Val_unit
)
1402 handleFTPAlternativeToUser(connection
,
1403 Field(original
->ocamlValues
,
1404 OcamlFTPAlternativeToUser
));
1405 if (Field(original
->ocamlValues
, OcamlSSHPublicKeyFile
) != Val_unit
)
1406 handleSSHPublicKeyFile(connection
,
1407 Field(original
->ocamlValues
,
1408 OcamlSSHPublicKeyFile
));
1409 if (Field(original
->ocamlValues
, OcamlSSHPrivateKeyFile
) != Val_unit
)
1410 handleSSHPrivateKeyFile(connection
,
1411 Field(original
->ocamlValues
,
1412 OcamlSSHPrivateKeyFile
));
1413 if (Field(original
->ocamlValues
, OcamlCopyPostFields
) != Val_unit
)
1414 handleCopyPostFields(connection
,
1415 Field(original
->ocamlValues
,
1416 OcamlCopyPostFields
));
1421 static void removeConnection(Connection
*connection
)
1423 enter_blocking_section();
1424 curl_easy_cleanup(connection
->connection
);
1425 leave_blocking_section();
1427 if (connectionList
.tail
== connection
)
1428 connectionList
.tail
= connectionList
.tail
->next
;
1429 if (connectionList
.head
== connection
)
1430 connectionList
.head
= connectionList
.head
->prev
;
1432 if (connection
->next
!= NULL
)
1433 connection
->next
->prev
= connection
->prev
;
1434 if (connection
->prev
!= NULL
)
1435 connection
->prev
->next
= connection
->next
;
1437 remove_global_root(&connection
->ocamlValues
);
1439 if (connection
->url
!= NULL
)
1440 free(connection
->url
);
1441 if (connection
->proxy
!= NULL
)
1442 free(connection
->proxy
);
1443 if (connection
->userPwd
!= NULL
)
1444 free(connection
->userPwd
);
1445 if (connection
->proxyUserPwd
!= NULL
)
1446 free(connection
->proxyUserPwd
);
1447 if (connection
->range
!= NULL
)
1448 free(connection
->range
);
1449 if (connection
->errorBuffer
!= NULL
)
1450 free(connection
->range
);
1451 if (connection
->postFields
!= NULL
)
1452 free(connection
->postFields
);
1453 if (connection
->referer
!= NULL
)
1454 free(connection
->referer
);
1455 if (connection
->userAgent
!= NULL
)
1456 free(connection
->userAgent
);
1457 if (connection
->ftpPort
!= NULL
)
1458 free(connection
->ftpPort
);
1459 if (connection
->cookie
!= NULL
)
1460 free(connection
->cookie
);
1461 if (connection
->httpHeader
!= NULL
)
1462 free_curl_slist(connection
->httpHeader
);
1463 if (connection
->httpPostFirst
!= NULL
)
1464 curl_formfree(connection
->httpPostFirst
);
1465 if (connection
->httpPostStrings
!= NULL
)
1466 free_curl_slist(connection
->httpPostStrings
);
1467 if (connection
->sslCert
!= NULL
)
1468 free(connection
->sslCert
);
1469 if (connection
->sslCertType
!= NULL
)
1470 free(connection
->sslCertType
);
1471 if (connection
->sslCertPasswd
!= NULL
)
1472 free(connection
->sslCertPasswd
);
1473 if (connection
->sslKey
!= NULL
)
1474 free(connection
->sslKey
);
1475 if (connection
->sslKeyType
!= NULL
)
1476 free(connection
->sslKeyType
);
1477 if (connection
->sslKeyPasswd
!= NULL
)
1478 free(connection
->sslKeyPasswd
);
1479 if (connection
->sslEngine
!= NULL
)
1480 free(connection
->sslEngine
);
1481 if (connection
->quote
!= NULL
)
1482 free_curl_slist(connection
->quote
);
1483 if (connection
->postQuote
!= NULL
)
1484 free_curl_slist(connection
->postQuote
);
1485 if (connection
->cookieFile
!= NULL
)
1486 free(connection
->cookieFile
);
1487 if (connection
->customRequest
!= NULL
)
1488 free(connection
->customRequest
);
1489 if (connection
->interface
!= NULL
)
1490 free(connection
->interface
);
1491 if (connection
->caInfo
!= NULL
)
1492 free(connection
->caInfo
);
1493 if (connection
->caPath
!= NULL
)
1494 free(connection
->caPath
);
1495 if (connection
->randomFile
!= NULL
)
1496 free(connection
->randomFile
);
1497 if (connection
->egdSocket
!= NULL
)
1498 free(connection
->egdSocket
);
1499 if (connection
->cookieJar
!= NULL
)
1500 free(connection
->cookieJar
);
1501 if (connection
->sslCipherList
!= NULL
)
1502 free(connection
->sslCipherList
);
1503 if (connection
->private != NULL
)
1504 free(connection
->private);
1505 if (connection
->http200Aliases
!= NULL
)
1506 free_curl_slist(connection
->http200Aliases
);
1507 if (connection
->netrcFile
!= NULL
)
1508 free(connection
->netrcFile
);
1509 if (connection
->ftpaccount
!= NULL
)
1510 free(connection
->ftpaccount
);
1511 if (connection
->cookielist
!= NULL
)
1512 free(connection
->cookielist
);
1513 if (connection
->ftpAlternativeToUser
!= NULL
)
1514 free(connection
->ftpAlternativeToUser
);
1515 if (connection
->sshPublicKeyFile
!= NULL
)
1516 free(connection
->sshPublicKeyFile
);
1517 if (connection
->sshPrivateKeyFile
!= NULL
)
1518 free(connection
->sshPrivateKeyFile
);
1519 if (connection
->copyPostFields
!= NULL
)
1520 free(connection
->copyPostFields
);
1525 static void checkConnection(Connection
*connection
)
1527 Connection
*listIter
;
1529 listIter
= connectionList
.tail
;
1531 while (listIter
!= NULL
)
1533 if (listIter
== connection
)
1536 listIter
= listIter
->next
;
1539 failwith("Invalid Connection");
1542 static Connection
* findConnection(CURL
* h
)
1544 Connection
*listIter
;
1546 listIter
= connectionList
.tail
;
1548 while (listIter
!= NULL
)
1550 if (listIter
->connection
== h
)
1553 listIter
= listIter
->next
;
1556 failwith("Unknown handle");
1559 #define WRAP_DATA_CALLBACK(f) \
1560 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1563 leave_blocking_section();\
1564 result = f##_nolock(ptr,size,nmemb,data);\
1565 enter_blocking_section();\
1569 static size_t writeFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1572 CAMLlocal2(result
, str
);
1573 Connection
*conn
= (Connection
*)data
;
1576 checkConnection(conn
);
1578 str
= alloc_string(size
*nmemb
);
1580 for (i
= 0; i
< size
*nmemb
; i
++)
1581 Byte(str
, i
) = ptr
[i
];
1583 result
= callback(Field(conn
->ocamlValues
, OcamlWriteCallback
), str
);
1585 CAMLreturnT(size_t, Int_val(result
));
1588 WRAP_DATA_CALLBACK(writeFunction
)
1590 static size_t readFunction_nolock(void *ptr
, size_t size
, size_t nmemb
, void *data
)
1594 Connection
*conn
= (Connection
*)data
;
1597 checkConnection(conn
);
1599 result
= callback(Field(conn
->ocamlValues
, OcamlReadCallback
),
1600 Val_int(size
*nmemb
));
1602 length
= string_length(result
);
1604 if (length
>= size
*nmemb
)
1605 length
= size
*nmemb
;
1607 memcpy(ptr
, String_val(result
), length
);
1609 CAMLreturnT(size_t,length
);
1612 WRAP_DATA_CALLBACK(readFunction
)
1614 static size_t headerFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1617 CAMLlocal2(result
,str
);
1618 Connection
*conn
= (Connection
*)data
;
1621 checkConnection(conn
);
1623 str
= alloc_string(size
*nmemb
);
1625 for (i
= 0; i
< size
*nmemb
; i
++)
1626 Byte(str
, i
) = ptr
[i
];
1628 result
= callback(Field(conn
->ocamlValues
, OcamlHeaderCallback
), str
);
1630 CAMLreturnT(size_t, Int_val(result
));
1633 WRAP_DATA_CALLBACK(headerFunction
)
1635 static int progressFunction_nolock(void *data
,
1643 CAMLlocalN(callbackData
, 4);
1644 Connection
*conn
= (Connection
*)data
;
1646 checkConnection(conn
);
1648 callbackData
[0] = copy_double(dlTotal
);
1649 callbackData
[1] = copy_double(dlNow
);
1650 callbackData
[2] = copy_double(ulTotal
);
1651 callbackData
[3] = copy_double(ulNow
);
1653 result
= callbackN(Field(conn
->ocamlValues
, OcamlProgressCallback
),
1656 CAMLreturnT(int, Bool_val(result
));
1659 static int progressFunction(void *data
,
1666 leave_blocking_section();
1667 r
= progressFunction_nolock(data
,dlTotal
,dlNow
,ulTotal
,ulNow
);
1668 enter_blocking_section();
1672 static int debugFunction_nolock(CURL
*debugConnection
,
1673 curl_infotype infoType
,
1675 size_t bufferLength
,
1679 CAMLlocal3(camlDebugConnection
, camlInfoType
, camlMessage
);
1681 Connection
*conn
= (Connection
*)data
;
1683 checkConnection(conn
);
1685 camlDebugConnection
= (value
)conn
;
1686 camlInfoType
= Val_long(infoType
);
1687 camlMessage
= alloc_string(bufferLength
);
1689 for (i
= 0; i
< bufferLength
; i
++)
1690 Byte(camlMessage
, i
) = buffer
[i
];
1692 callback3(Field(conn
->ocamlValues
, OcamlDebugCallback
),
1693 camlDebugConnection
,
1697 CAMLreturnT(int, 0);
1700 static int debugFunction(CURL
*debugConnection
,
1701 curl_infotype infoType
,
1703 size_t bufferLength
,
1707 leave_blocking_section();
1708 r
= debugFunction_nolock(debugConnection
, infoType
, buffer
, bufferLength
, data
);
1709 enter_blocking_section();
1713 static curlioerr
ioctlFunction_nolock(CURL
*ioctl
,
1718 CAMLlocal3(camlResult
, camlConnection
, camlCmd
);
1719 Connection
*conn
= (Connection
*)data
;
1720 curlioerr result
= CURLIOE_OK
;
1722 checkConnection(conn
);
1724 if (cmd
== CURLIOCMD_NOP
)
1725 camlCmd
= Val_long(0);
1726 else if (cmd
== CURLIOCMD_RESTARTREAD
)
1727 camlCmd
= Val_long(1);
1729 failwith("Invalid IOCTL Cmd!");
1731 camlConnection
= alloc(1, Abstract_tag
);
1732 Store_field(camlConnection
, 0, (value
)conn
);
1734 camlResult
= callback2(Field(conn
->ocamlValues
, OcamlIOCTLCallback
),
1738 switch (Long_val(camlResult
))
1740 case 0: /* CURLIOE_OK */
1741 result
= CURLIOE_OK
;
1744 case 1: /* CURLIOE_UNKNOWNCMD */
1745 result
= CURLIOE_UNKNOWNCMD
;
1748 case 2: /* CURLIOE_FAILRESTART */
1749 result
= CURLIOE_FAILRESTART
;
1752 default: /* Incorrect return value, but let's handle it */
1753 result
= CURLIOE_FAILRESTART
;
1757 CAMLreturnT(curlioerr
, result
);
1760 static curlioerr
ioctlFunction(CURL
*ioctl
,
1765 leave_blocking_section();
1766 r
= ioctlFunction_nolock(ioctl
, cmd
, data
);
1767 enter_blocking_section();
1771 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1772 static int seekFunction_nolock(void *data
,
1777 CAMLlocal3(camlResult
, camlOffset
, camlOrigin
);
1778 Connection
*conn
= (Connection
*)data
;
1781 camlOffset
= copy_int64(offset
);
1783 if (origin
== SEEK_SET
)
1784 camlOrigin
= Val_long(0);
1785 else if (origin
== SEEK_CUR
)
1786 camlOrigin
= Val_long(1);
1787 else if (origin
== SEEK_END
)
1788 camlOrigin
= Val_long(2);
1790 camlOrigin
= Val_long(0);
1792 camlResult
= callback2(Field(conn
->ocamlValues
,
1793 OcamlSeekFunctionCallback
),
1797 result
= Int_val(camlResult
);
1799 CAMLreturnT(int, result
);
1802 static int seekFunction(void *data
,
1807 leave_blocking_section();
1808 r
= seekFunction_nolock(data
,offset
,origin
);
1809 enter_blocking_section();
1816 ** curl_global_init helper function
1819 CAMLprim value
helper_curl_global_init(value initOption
)
1821 CAMLparam1(initOption
);
1823 switch (Long_val(initOption
))
1825 case 0: /* CURLINIT_GLOBALALL */
1826 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL
)));
1829 case 1: /* CURLINIT_GLOBALSSL */
1830 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL
)));
1833 case 2: /* CURLINIT_GLOBALWIN32 */
1834 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32
)));
1837 case 3: /* CURLINIT_GLOBALNOTHING */
1838 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING
)));
1842 failwith("Invalid Initialization Option");
1846 /* Keep compiler happy, we should never get here due to failwith() */
1847 CAMLreturn(Val_unit
);
1851 ** curl_global_cleanup helper function
1854 CAMLprim value
helper_curl_global_cleanup(void)
1858 curl_global_cleanup();
1860 CAMLreturn(Val_unit
);
1864 ** curl_easy_init helper function
1867 CAMLprim value
helper_curl_easy_init(void)
1872 Connection
*conn
= newConnection();
1874 result
= alloc(1, Abstract_tag
);
1875 Store_field(result
, 0, (value
)conn
);
1880 CAMLprim value
helper_curl_easy_reset(value conn
)
1883 Connection
*connection
= Connection_val(conn
);
1885 checkConnection(connection
);
1886 curl_easy_reset(connection
->connection
);
1887 resetOcamlValues(connection
);
1889 CAMLreturn(Val_unit
);
1893 ** curl_easy_setopt helper utility functions
1896 static void handleWriteFunction(Connection
*conn
, value option
)
1899 CURLcode result
= CURLE_OK
;
1901 if (Tag_val(option
) == Closure_tag
)
1902 Store_field(conn
->ocamlValues
, OcamlWriteCallback
, option
);
1904 failwith("Not a proper closure");
1906 result
= curl_easy_setopt(conn
->connection
,
1907 CURLOPT_WRITEFUNCTION
,
1910 if (result
!= CURLE_OK
)
1911 raiseError(conn
, result
);
1913 result
= curl_easy_setopt(conn
->connection
,
1917 if (result
!= CURLE_OK
)
1918 raiseError(conn
, result
);
1923 static void handleReadFunction(Connection
*conn
, value option
)
1926 CURLcode result
= CURLE_OK
;
1928 if (Tag_val(option
) == Closure_tag
)
1929 Store_field(conn
->ocamlValues
, OcamlReadCallback
, option
);
1931 failwith("Not a proper closure");
1933 result
= curl_easy_setopt(conn
->connection
,
1934 CURLOPT_READFUNCTION
,
1937 if (result
!= CURLE_OK
)
1938 raiseError(conn
, result
);
1940 result
= curl_easy_setopt(conn
->connection
,
1944 if (result
!= CURLE_OK
)
1945 raiseError(conn
, result
);
1950 static void handleURL(Connection
*conn
, value option
)
1953 CURLcode result
= CURLE_OK
;
1955 Store_field(conn
->ocamlValues
, OcamlURL
, option
);
1957 if (conn
->url
!= NULL
)
1960 conn
->url
= strdup(String_val(option
));
1962 result
= curl_easy_setopt(conn
->connection
,
1966 if (result
!= CURLE_OK
)
1967 raiseError(conn
, result
);
1972 static void handleInFileSize(Connection
*conn
, value option
)
1975 CURLcode result
= CURLE_OK
;
1977 result
= curl_easy_setopt(conn
->connection
,
1981 if (result
!= CURLE_OK
)
1982 raiseError(conn
, result
);
1987 static void handleProxy(Connection
*conn
, value option
)
1990 CURLcode result
= CURLE_OK
;
1992 Store_field(conn
->ocamlValues
, OcamlProxy
, option
);
1994 if (conn
->proxy
!= NULL
)
1997 conn
->proxy
= strdup(String_val(option
));
1999 result
= curl_easy_setopt(conn
->connection
,
2003 if (result
!= CURLE_OK
)
2004 raiseError(conn
, result
);
2009 static void handleProxyPort(Connection
*conn
, value option
)
2012 CURLcode result
= CURLE_OK
;
2014 result
= curl_easy_setopt(conn
->connection
,
2018 if (result
!= CURLE_OK
)
2019 raiseError(conn
, result
);
2024 static void handleHTTPProxyTunnel(Connection
*conn
, value option
)
2027 CURLcode result
= CURLE_OK
;
2029 result
= curl_easy_setopt(conn
->connection
,
2030 CURLOPT_HTTPPROXYTUNNEL
,
2033 if (result
!= CURLE_OK
)
2034 raiseError(conn
, result
);
2039 static void handleVerbose(Connection
*conn
, value option
)
2042 CURLcode result
= CURLE_OK
;
2044 result
= curl_easy_setopt(conn
->connection
,
2048 if (result
!= CURLE_OK
)
2049 raiseError(conn
, result
);
2054 static void handleHeader(Connection
*conn
, value option
)
2057 CURLcode result
= CURLE_OK
;
2059 result
= curl_easy_setopt(conn
->connection
,
2063 if (result
!= CURLE_OK
)
2064 raiseError(conn
, result
);
2069 static void handleNoProgress(Connection
*conn
, value option
)
2072 CURLcode result
= CURLE_OK
;
2074 result
= curl_easy_setopt(conn
->connection
,
2078 if (result
!= CURLE_OK
)
2079 raiseError(conn
, result
);
2084 static void handleNoSignal(Connection
*conn
, value option
)
2086 #if HAVE_DECL_CURLOPT_NOSIGNAL
2088 CURLcode result
= CURLE_OK
;
2090 result
= curl_easy_setopt(conn
->connection
,
2094 if (result
!= CURLE_OK
)
2095 raiseError(conn
, result
);
2099 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2100 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2104 static void handleNoBody(Connection
*conn
, value option
)
2107 CURLcode result
= CURLE_OK
;
2109 result
= curl_easy_setopt(conn
->connection
,
2113 if (result
!= CURLE_OK
)
2114 raiseError(conn
, result
);
2119 static void handleFailOnError(Connection
*conn
, value option
)
2122 CURLcode result
= CURLE_OK
;
2124 result
= curl_easy_setopt(conn
->connection
,
2125 CURLOPT_FAILONERROR
,
2128 if (result
!= CURLE_OK
)
2129 raiseError(conn
, result
);
2134 static void handleUpload(Connection
*conn
, value option
)
2137 CURLcode result
= CURLE_OK
;
2139 result
= curl_easy_setopt(conn
->connection
,
2143 if (result
!= CURLE_OK
)
2144 raiseError(conn
, result
);
2149 static void handlePost(Connection
*conn
, value option
)
2152 CURLcode result
= CURLE_OK
;
2154 result
= curl_easy_setopt(conn
->connection
,
2158 if (result
!= CURLE_OK
)
2159 raiseError(conn
, result
);
2164 static void handleFTPListOnly(Connection
*conn
, value option
)
2167 CURLcode result
= CURLE_OK
;
2169 result
= curl_easy_setopt(conn
->connection
,
2170 CURLOPT_FTPLISTONLY
,
2173 if (result
!= CURLE_OK
)
2174 raiseError(conn
, result
);
2179 static void handleFTPAppend(Connection
*conn
, value option
)
2182 CURLcode result
= CURLE_OK
;
2184 result
= curl_easy_setopt(conn
->connection
,
2188 if (result
!= CURLE_OK
)
2189 raiseError(conn
, result
);
2194 static void handleNETRC(Connection
*conn
, value option
)
2197 CURLcode result
= CURLE_OK
;
2200 switch (Long_val(option
))
2202 case 0: /* CURL_NETRC_OPTIONAL */
2203 netrc
= CURL_NETRC_OPTIONAL
;
2206 case 1:/* CURL_NETRC_IGNORED */
2207 netrc
= CURL_NETRC_IGNORED
;
2210 case 2: /* CURL_NETRC_REQUIRED */
2211 netrc
= CURL_NETRC_REQUIRED
;
2215 failwith("Invalid NETRC Option");
2219 result
= curl_easy_setopt(conn
->connection
,
2223 if (result
!= CURLE_OK
)
2224 raiseError(conn
, result
);
2229 static void handleEncoding(Connection
*conn
, value option
)
2231 #if HAVE_DECL_CURLOPT_ENCODING
2233 CURLcode result
= CURLE_OK
;
2235 switch (Long_val(option
))
2237 case 0: /* CURL_ENCODING_NONE */
2238 result
= curl_easy_setopt(conn
->connection
,
2243 case 1: /* CURL_ENCODING_DEFLATE */
2244 result
= curl_easy_setopt(conn
->connection
,
2250 failwith("Invalid Encoding Option");
2254 if (result
!= CURLE_OK
)
2255 raiseError(conn
, result
);
2259 #warning "libcurl does not implement CURLOPT_ENCODING"
2260 failwith("libcurl does not implement CURLOPT_ENCODING");
2264 static void handleFollowLocation(Connection
*conn
, value option
)
2267 CURLcode result
= CURLE_OK
;
2269 result
= curl_easy_setopt(conn
->connection
,
2270 CURLOPT_FOLLOWLOCATION
,
2273 if (result
!= CURLE_OK
)
2274 raiseError(conn
, result
);
2279 static void handleTransferText(Connection
*conn
, value option
)
2282 CURLcode result
= CURLE_OK
;
2284 result
= curl_easy_setopt(conn
->connection
,
2285 CURLOPT_TRANSFERTEXT
,
2288 if (result
!= CURLE_OK
)
2289 raiseError(conn
, result
);
2294 static void handlePut(Connection
*conn
, value option
)
2297 CURLcode result
= CURLE_OK
;
2299 result
= curl_easy_setopt(conn
->connection
,
2303 if (result
!= CURLE_OK
)
2304 raiseError(conn
, result
);
2309 static void handleUserPwd(Connection
*conn
, value option
)
2312 CURLcode result
= CURLE_OK
;
2314 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2316 if (conn
->userPwd
!= NULL
)
2317 free(conn
->userPwd
);
2319 conn
->userPwd
= strdup(String_val(option
));
2321 result
= curl_easy_setopt(conn
->connection
,
2325 if (result
!= CURLE_OK
)
2326 raiseError(conn
, result
);
2331 static void handleProxyUserPwd(Connection
*conn
, value option
)
2334 CURLcode result
= CURLE_OK
;
2336 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2338 if (conn
->proxyUserPwd
!= NULL
)
2339 free(conn
->proxyUserPwd
);
2341 conn
->proxyUserPwd
= strdup(String_val(option
));
2343 result
= curl_easy_setopt(conn
->connection
,
2344 CURLOPT_PROXYUSERPWD
,
2345 conn
->proxyUserPwd
);
2347 if (result
!= CURLE_OK
)
2348 raiseError(conn
, result
);
2353 static void handleRange(Connection
*conn
, value option
)
2356 CURLcode result
= CURLE_OK
;
2358 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2360 if (conn
->range
!= NULL
)
2363 conn
->range
= strdup(String_val(option
));
2365 result
= curl_easy_setopt(conn
->connection
,
2369 if (result
!= CURLE_OK
)
2370 raiseError(conn
, result
);
2375 static void handleErrorBuffer(Connection
*conn
, value option
)
2378 CURLcode result
= CURLE_OK
;
2380 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2382 if (conn
->errorBuffer
!= NULL
)
2383 free(conn
->errorBuffer
);
2385 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2387 result
= curl_easy_setopt(conn
->connection
,
2388 CURLOPT_ERRORBUFFER
,
2391 if (result
!= CURLE_OK
)
2392 raiseError(conn
, result
);
2397 static void handleTimeout(Connection
*conn
, value option
)
2400 CURLcode result
= CURLE_OK
;
2402 result
= curl_easy_setopt(conn
->connection
,
2406 if (result
!= CURLE_OK
)
2407 raiseError(conn
, result
);
2412 static void handlePostFields(Connection
*conn
, value option
)
2415 CURLcode result
= CURLE_OK
;
2417 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2419 if (conn
->postFields
!= NULL
)
2420 free(conn
->postFields
);
2422 conn
->postFields
= malloc(string_length(option
)+1);
2423 memcpy(conn
->postFields
, String_val(option
), string_length(option
));
2425 result
= curl_easy_setopt(conn
->connection
,
2429 if (result
!= CURLE_OK
)
2430 raiseError(conn
, result
);
2435 static void handlePostFieldSize(Connection
*conn
, value option
)
2438 CURLcode result
= CURLE_OK
;
2440 result
= curl_easy_setopt(conn
->connection
,
2441 CURLOPT_POSTFIELDSIZE
,
2444 if (result
!= CURLE_OK
)
2445 raiseError(conn
, result
);
2450 static void handleReferer(Connection
*conn
, value option
)
2453 CURLcode result
= CURLE_OK
;
2455 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2457 if (conn
->referer
!= NULL
)
2458 free(conn
->referer
);
2460 conn
->referer
= strdup(String_val(option
));
2462 result
= curl_easy_setopt(conn
->connection
,
2466 if (result
!= CURLE_OK
)
2467 raiseError(conn
, result
);
2472 static void handleUserAgent(Connection
*conn
, value option
)
2475 CURLcode result
= CURLE_OK
;
2477 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2479 if (conn
->userAgent
!= NULL
)
2480 free(conn
->userAgent
);
2482 conn
->userAgent
= strdup(String_val(option
));
2484 result
= curl_easy_setopt(conn
->connection
,
2488 if (result
!= CURLE_OK
)
2489 raiseError(conn
, result
);
2494 static void handleFTPPort(Connection
*conn
, value option
)
2497 CURLcode result
= CURLE_OK
;
2499 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2501 if (conn
->ftpPort
!= NULL
)
2502 free(conn
->ftpPort
);
2504 conn
->ftpPort
= strdup(String_val(option
));
2506 result
= curl_easy_setopt(conn
->connection
,
2510 if (result
!= CURLE_OK
)
2511 raiseError(conn
, result
);
2516 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2519 CURLcode result
= CURLE_OK
;
2521 result
= curl_easy_setopt(conn
->connection
,
2522 CURLOPT_LOW_SPEED_LIMIT
,
2525 if (result
!= CURLE_OK
)
2526 raiseError(conn
, result
);
2531 static void handleLowSpeedTime(Connection
*conn
, value option
)
2534 CURLcode result
= CURLE_OK
;
2536 result
= curl_easy_setopt(conn
->connection
,
2537 CURLOPT_LOW_SPEED_TIME
,
2540 if (result
!= CURLE_OK
)
2541 raiseError(conn
, result
);
2546 static void handleResumeFrom(Connection
*conn
, value option
)
2549 CURLcode result
= CURLE_OK
;
2551 result
= curl_easy_setopt(conn
->connection
,
2552 CURLOPT_RESUME_FROM
,
2555 if (result
!= CURLE_OK
)
2556 raiseError(conn
, result
);
2561 static void handleCookie(Connection
*conn
, value option
)
2564 CURLcode result
= CURLE_OK
;
2566 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2568 if (conn
->cookie
!= NULL
)
2571 conn
->cookie
= strdup(String_val(option
));
2573 result
= curl_easy_setopt(conn
->connection
,
2577 if (result
!= CURLE_OK
)
2578 raiseError(conn
, result
);
2583 static void handleHTTPHeader(Connection
*conn
, value option
)
2586 CAMLlocal1(listIter
);
2587 CURLcode result
= CURLE_OK
;
2590 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2592 if (conn
->httpHeader
!= NULL
)
2593 free_curl_slist(conn
->httpHeader
);
2595 conn
->httpHeader
= NULL
;
2599 while (!Is_long(listIter
))
2601 if (Tag_val(Field(listIter
, 0)) != String_tag
)
2602 failwith("Not a string");
2604 str
= strdup(String_val(Field(listIter
, 0)));
2606 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, str
);
2608 listIter
= Field(listIter
, 1);
2611 result
= curl_easy_setopt(conn
->connection
,
2615 if (result
!= CURLE_OK
)
2616 raiseError(conn
, result
);
2621 static void handleHTTPPost(Connection
*conn
, value option
)
2624 CAMLlocal3(listIter
, formItem
, contentType
);
2625 CURLcode result
= CURLE_OK
;
2626 char *str1
, *str2
, *str3
, *str4
;
2630 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2632 if (conn
->httpPostFirst
!= NULL
)
2633 curl_formfree(conn
->httpPostFirst
);
2635 conn
->httpPostFirst
= NULL
;
2636 conn
->httpPostLast
= NULL
;
2638 if (conn
->httpPostStrings
!= NULL
)
2639 free_curl_slist(conn
->httpPostStrings
);
2641 while (!Is_long(listIter
))
2643 formItem
= Field(listIter
, 0);
2645 switch (Tag_val(formItem
))
2647 case 0: /* CURLFORM_CONTENT */
2648 if (Wosize_val(formItem
) < 3)
2650 failwith("Incorrect CURLFORM_CONTENT parameters");
2653 if (Is_long(Field(formItem
, 2)) &&
2654 Long_val(Field(formItem
, 2)) == 0)
2656 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2658 String_val(Field(formItem
, 0)),
2659 string_length(Field(formItem
, 0)));
2660 str1
[string_length(Field(formItem
, 0))] = 0;
2661 conn
->httpPostStrings
=
2662 curl_slist_append(conn
->httpPostStrings
, str1
);
2664 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2666 String_val(Field(formItem
, 1)),
2667 string_length(Field(formItem
, 1)));
2668 str2
[string_length(Field(formItem
, 1))] = 0;
2669 conn
->httpPostStrings
=
2670 curl_slist_append(conn
->httpPostStrings
, str2
);
2672 curl_formadd(&conn
->httpPostFirst
,
2673 &conn
->httpPostLast
,
2676 CURLFORM_NAMELENGTH
,
2677 string_length(Field(formItem
, 0)),
2678 CURLFORM_PTRCONTENTS
,
2680 CURLFORM_CONTENTSLENGTH
,
2681 string_length(Field(formItem
, 1)),
2684 else if (Is_block(Field(formItem
, 2)))
2686 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2688 String_val(Field(formItem
, 0)),
2689 string_length(Field(formItem
, 0)));
2690 str1
[string_length(Field(formItem
, 0))] = 0;
2691 conn
->httpPostStrings
=
2692 curl_slist_append(conn
->httpPostStrings
, str1
);
2694 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2696 String_val(Field(formItem
, 1)),
2697 string_length(Field(formItem
, 1)));
2698 str2
[string_length(Field(formItem
, 1))] = 0;
2699 conn
->httpPostStrings
=
2700 curl_slist_append(conn
->httpPostStrings
, str2
);
2702 contentType
= Field(formItem
, 2);
2704 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2706 String_val(Field(contentType
, 0)),
2707 string_length(Field(contentType
, 0)));
2708 str3
[string_length(Field(contentType
, 0))] = 0;
2709 conn
->httpPostStrings
=
2710 curl_slist_append(conn
->httpPostStrings
, str3
);
2712 curl_formadd(&conn
->httpPostFirst
,
2713 &conn
->httpPostLast
,
2716 CURLFORM_NAMELENGTH
,
2717 string_length(Field(formItem
, 0)),
2718 CURLFORM_PTRCONTENTS
,
2720 CURLFORM_CONTENTSLENGTH
,
2721 string_length(Field(formItem
, 1)),
2722 CURLFORM_CONTENTTYPE
,
2728 failwith("Incorrect CURLFORM_CONTENT parameters");
2732 case 1: /* CURLFORM_FILECONTENT */
2733 if (Wosize_val(formItem
) < 3)
2735 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2738 if (Is_long(Field(formItem
, 2)) &&
2739 Long_val(Field(formItem
, 2)) == 0)
2741 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2743 String_val(Field(formItem
, 0)),
2744 string_length(Field(formItem
, 0)));
2745 str1
[string_length(Field(formItem
, 0))] = 0;
2746 conn
->httpPostStrings
=
2747 curl_slist_append(conn
->httpPostStrings
, str1
);
2749 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2751 String_val(Field(formItem
, 1)),
2752 string_length(Field(formItem
, 1)));
2753 str2
[string_length(Field(formItem
, 1))] = 0;
2754 conn
->httpPostStrings
=
2755 curl_slist_append(conn
->httpPostStrings
, str2
);
2757 curl_formadd(&conn
->httpPostFirst
,
2758 &conn
->httpPostLast
,
2761 CURLFORM_NAMELENGTH
,
2762 string_length(Field(formItem
, 0)),
2763 CURLFORM_FILECONTENT
,
2767 else if (Is_block(Field(formItem
, 2)))
2769 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2771 String_val(Field(formItem
, 0)),
2772 string_length(Field(formItem
, 0)));
2773 str1
[string_length(Field(formItem
, 0))] = 0;
2774 conn
->httpPostStrings
=
2775 curl_slist_append(conn
->httpPostStrings
, str1
);
2777 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2779 String_val(Field(formItem
, 1)),
2780 string_length(Field(formItem
, 1)));
2781 str2
[string_length(Field(formItem
, 1))] = 0;
2782 conn
->httpPostStrings
=
2783 curl_slist_append(conn
->httpPostStrings
, str2
);
2785 contentType
= Field(formItem
, 2);
2787 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2789 String_val(Field(contentType
, 0)),
2790 string_length(Field(contentType
, 0)));
2791 str3
[string_length(Field(contentType
, 0))] = 0;
2792 conn
->httpPostStrings
=
2793 curl_slist_append(conn
->httpPostStrings
, str3
);
2795 curl_formadd(&conn
->httpPostFirst
,
2796 &conn
->httpPostLast
,
2799 CURLFORM_NAMELENGTH
,
2800 string_length(Field(formItem
, 0)),
2801 CURLFORM_FILECONTENT
,
2803 CURLFORM_CONTENTTYPE
,
2809 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2813 case 2: /* CURLFORM_FILE */
2814 if (Wosize_val(formItem
) < 3)
2816 failwith("Incorrect CURLFORM_FILE parameters");
2819 if (Is_long(Field(formItem
, 2)) &&
2820 Long_val(Field(formItem
, 2)) == 0)
2822 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2824 String_val(Field(formItem
, 0)),
2825 string_length(Field(formItem
, 0)));
2826 str1
[string_length(Field(formItem
, 0))] = 0;
2827 conn
->httpPostStrings
=
2828 curl_slist_append(conn
->httpPostStrings
, str1
);
2830 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2832 String_val(Field(formItem
, 1)),
2833 string_length(Field(formItem
, 1)));
2834 str2
[string_length(Field(formItem
, 1))] = 0;
2835 conn
->httpPostStrings
=
2836 curl_slist_append(conn
->httpPostStrings
, str2
);
2838 curl_formadd(&conn
->httpPostFirst
,
2839 &conn
->httpPostLast
,
2842 CURLFORM_NAMELENGTH
,
2843 string_length(Field(formItem
, 0)),
2848 else if (Is_block(Field(formItem
, 2)))
2850 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2852 String_val(Field(formItem
, 0)),
2853 string_length(Field(formItem
, 0)));
2854 str1
[string_length(Field(formItem
, 0))] = 0;
2855 conn
->httpPostStrings
=
2856 curl_slist_append(conn
->httpPostStrings
, str1
);
2858 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2860 String_val(Field(formItem
, 1)),
2861 string_length(Field(formItem
, 1)));
2862 str2
[string_length(Field(formItem
, 1))] = 0;
2863 conn
->httpPostStrings
=
2864 curl_slist_append(conn
->httpPostStrings
, str2
);
2866 contentType
= Field(formItem
, 2);
2868 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2870 String_val(Field(contentType
, 0)),
2871 string_length(Field(contentType
, 0)));
2872 str3
[string_length(Field(contentType
, 0))] = 0;
2873 conn
->httpPostStrings
=
2874 curl_slist_append(conn
->httpPostStrings
, str3
);
2876 curl_formadd(&conn
->httpPostFirst
,
2877 &conn
->httpPostLast
,
2880 CURLFORM_NAMELENGTH
,
2881 string_length(Field(formItem
, 0)),
2884 CURLFORM_CONTENTTYPE
,
2890 failwith("Incorrect CURLFORM_FILE parameters");
2894 case 3: /* CURLFORM_BUFFER */
2895 if (Wosize_val(formItem
) < 4)
2897 failwith("Incorrect CURLFORM_BUFFER parameters");
2900 if (Is_long(Field(formItem
, 3)) &&
2901 Long_val(Field(formItem
, 3)) == 0)
2903 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2905 String_val(Field(formItem
, 0)),
2906 string_length(Field(formItem
, 0)));
2907 str1
[string_length(Field(formItem
, 0))] = 0;
2908 conn
->httpPostStrings
=
2909 curl_slist_append(conn
->httpPostStrings
, str1
);
2911 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2913 String_val(Field(formItem
, 1)),
2914 string_length(Field(formItem
, 1)));
2915 str2
[string_length(Field(formItem
, 1))] = 0;
2916 conn
->httpPostStrings
=
2917 curl_slist_append(conn
->httpPostStrings
, str2
);
2919 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2921 String_val(Field(formItem
, 2)),
2922 string_length(Field(formItem
, 2)));
2923 str3
[string_length(Field(formItem
, 2))] = 0;
2924 conn
->httpPostStrings
=
2925 curl_slist_append(conn
->httpPostStrings
, str3
);
2927 curl_formadd(&conn
->httpPostFirst
,
2928 &conn
->httpPostLast
,
2931 CURLFORM_NAMELENGTH
,
2932 string_length(Field(formItem
, 0)),
2937 CURLFORM_BUFFERLENGTH
,
2938 string_length(Field(formItem
, 2)),
2941 else if (Is_block(Field(formItem
, 3)))
2943 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2945 String_val(Field(formItem
, 0)),
2946 string_length(Field(formItem
, 0)));
2947 str1
[string_length(Field(formItem
, 0))] = 0;
2948 conn
->httpPostStrings
=
2949 curl_slist_append(conn
->httpPostStrings
, str1
);
2951 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2953 String_val(Field(formItem
, 1)),
2954 string_length(Field(formItem
, 1)));
2955 str2
[string_length(Field(formItem
, 1))] = 0;
2956 conn
->httpPostStrings
=
2957 curl_slist_append(conn
->httpPostStrings
, str2
);
2959 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2961 String_val(Field(formItem
, 2)),
2962 string_length(Field(formItem
, 2)));
2963 str3
[string_length(Field(formItem
, 2))] = 0;
2964 conn
->httpPostStrings
=
2965 curl_slist_append(conn
->httpPostStrings
, str3
);
2967 contentType
= Field(formItem
, 3);
2969 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2971 String_val(Field(contentType
, 0)),
2972 string_length(Field(contentType
, 0)));
2973 str4
[string_length(Field(contentType
, 0))] = 0;
2974 conn
->httpPostStrings
=
2975 curl_slist_append(conn
->httpPostStrings
, str4
);
2977 curl_formadd(&conn
->httpPostFirst
,
2978 &conn
->httpPostLast
,
2981 CURLFORM_NAMELENGTH
,
2982 string_length(Field(formItem
, 0)),
2987 CURLFORM_BUFFERLENGTH
,
2988 string_length(Field(formItem
, 2)),
2989 CURLFORM_CONTENTTYPE
,
2995 failwith("Incorrect CURLFORM_BUFFER parameters");
3000 listIter
= Field(listIter
, 1);
3003 result
= curl_easy_setopt(conn
->connection
,
3005 conn
->httpPostFirst
);
3007 if (result
!= CURLE_OK
)
3008 raiseError(conn
, result
);
3013 static void handleSSLCert(Connection
*conn
, value option
)
3016 CURLcode result
= CURLE_OK
;
3018 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3020 if (conn
->sslCert
!= NULL
)
3021 free(conn
->sslCert
);
3023 conn
->sslCert
= strdup(String_val(option
));
3025 result
= curl_easy_setopt(conn
->connection
,
3029 if (result
!= CURLE_OK
)
3030 raiseError(conn
, result
);
3035 static void handleSSLCertType(Connection
*conn
, value option
)
3038 CURLcode result
= CURLE_OK
;
3040 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3042 if (conn
->sslCertType
!= NULL
)
3043 free(conn
->sslCertType
);
3045 conn
->sslCertType
= strdup(String_val(option
));
3047 result
= curl_easy_setopt(conn
->connection
,
3048 CURLOPT_SSLCERTTYPE
,
3051 if (result
!= CURLE_OK
)
3052 raiseError(conn
, result
);
3057 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3060 CURLcode result
= CURLE_OK
;
3062 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3064 if (conn
->sslCertPasswd
!= NULL
)
3065 free(conn
->sslCertPasswd
);
3067 conn
->sslCertPasswd
= strdup(String_val(option
));
3069 result
= curl_easy_setopt(conn
->connection
,
3070 CURLOPT_SSLCERTPASSWD
,
3071 conn
->sslCertPasswd
);
3073 if (result
!= CURLE_OK
)
3074 raiseError(conn
, result
);
3079 static void handleSSLKey(Connection
*conn
, value option
)
3082 CURLcode result
= CURLE_OK
;
3084 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3086 if (conn
->sslKey
!= NULL
)
3089 conn
->sslKey
= strdup(String_val(option
));
3091 result
= curl_easy_setopt(conn
->connection
,
3095 if (result
!= CURLE_OK
)
3096 raiseError(conn
, result
);
3101 static void handleSSLKeyType(Connection
*conn
, value option
)
3104 CURLcode result
= CURLE_OK
;
3106 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3108 if (conn
->sslKeyType
!= NULL
)
3109 free(conn
->sslKeyType
);
3111 conn
->sslKeyType
= strdup(String_val(option
));
3113 result
= curl_easy_setopt(conn
->connection
,
3117 if (result
!= CURLE_OK
)
3118 raiseError(conn
, result
);
3123 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3126 CURLcode result
= CURLE_OK
;
3128 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3130 if (conn
->sslKeyPasswd
!= NULL
)
3131 free(conn
->sslKeyPasswd
);
3133 conn
->sslKeyPasswd
= strdup(String_val(option
));
3135 result
= curl_easy_setopt(conn
->connection
,
3136 CURLOPT_SSLKEYPASSWD
,
3137 conn
->sslKeyPasswd
);
3139 if (result
!= CURLE_OK
)
3140 raiseError(conn
, result
);
3145 static void handleSSLEngine(Connection
*conn
, value option
)
3148 CURLcode result
= CURLE_OK
;
3150 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3152 if (conn
->sslEngine
!= NULL
)
3153 free(conn
->sslEngine
);
3155 conn
->sslEngine
= strdup(String_val(option
));
3157 result
= curl_easy_setopt(conn
->connection
,
3161 if (result
!= CURLE_OK
)
3162 raiseError(conn
, result
);
3167 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3170 CURLcode result
= CURLE_OK
;
3172 result
= curl_easy_setopt(conn
->connection
,
3173 CURLOPT_SSLENGINE_DEFAULT
,
3176 if (result
!= CURLE_OK
)
3177 raiseError(conn
, result
);
3182 static void handleCRLF(Connection
*conn
, value option
)
3185 CURLcode result
= CURLE_OK
;
3187 result
= curl_easy_setopt(conn
->connection
,
3191 if (result
!= CURLE_OK
)
3192 raiseError(conn
, result
);
3197 static void handleQuote(Connection
*conn
, value option
)
3200 CAMLlocal1(listIter
);
3201 CURLcode result
= CURLE_OK
;
3204 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3206 if (conn
->quote
!= NULL
)
3207 free_curl_slist(conn
->quote
);
3213 while (!Is_long(listIter
))
3215 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3216 failwith("Not a string");
3218 str
= strdup(String_val(Field(listIter
, 0)));
3220 conn
->quote
= curl_slist_append(conn
->quote
, str
);
3222 listIter
= Field(listIter
, 1);
3225 result
= curl_easy_setopt(conn
->connection
,
3229 if (result
!= CURLE_OK
)
3230 raiseError(conn
, result
);
3235 static void handlePostQuote(Connection
*conn
, value option
)
3238 CAMLlocal1(listIter
);
3239 CURLcode result
= CURLE_OK
;
3242 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3244 if (conn
->postQuote
!= NULL
)
3245 free_curl_slist(conn
->postQuote
);
3247 conn
->postQuote
= NULL
;
3251 while (!Is_long(listIter
))
3253 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3254 failwith("Not a string");
3256 str
= strdup(String_val(Field(listIter
, 0)));
3258 conn
->postQuote
= curl_slist_append(conn
->postQuote
, str
);
3260 listIter
= Field(listIter
, 1);
3263 result
= curl_easy_setopt(conn
->connection
,
3267 if (result
!= CURLE_OK
)
3268 raiseError(conn
, result
);
3273 static void handleHeaderFunction(Connection
*conn
, value option
)
3276 CURLcode result
= CURLE_OK
;
3278 if (Tag_val(option
) == Closure_tag
)
3279 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3281 failwith("Not a proper closure");
3283 result
= curl_easy_setopt(conn
->connection
,
3284 CURLOPT_HEADERFUNCTION
,
3287 if (result
!= CURLE_OK
)
3288 raiseError(conn
, result
);
3290 result
= curl_easy_setopt(conn
->connection
,
3291 CURLOPT_WRITEHEADER
,
3294 if (result
!= CURLE_OK
)
3295 raiseError(conn
, result
);
3300 static void handleCookieFile(Connection
*conn
, value option
)
3303 CURLcode result
= CURLE_OK
;
3305 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3307 if (conn
->cookieFile
!= NULL
)
3308 free(conn
->cookieFile
);
3310 conn
->cookieFile
= strdup(String_val(option
));
3312 result
= curl_easy_setopt(conn
->connection
,
3316 if (result
!= CURLE_OK
)
3317 raiseError(conn
, result
);
3322 static void handleSSLVersion(Connection
*conn
, value option
)
3325 CURLcode result
= CURLE_OK
;
3327 result
= curl_easy_setopt(conn
->connection
,
3331 if (result
!= CURLE_OK
)
3332 raiseError(conn
, result
);
3337 static void handleTimeCondition(Connection
*conn
, value option
)
3340 CURLcode result
= CURLE_OK
;
3342 switch (Long_val(option
))
3344 case 0: /* TIMECOND_IFMODSINCE */
3345 result
= curl_easy_setopt(conn
->connection
,
3346 CURLOPT_TIMECONDITION
,
3347 CURL_TIMECOND_IFMODSINCE
);
3350 case 1: /* TIMECOND_IFUNMODSINCE */
3351 result
= curl_easy_setopt(conn
->connection
,
3352 CURLOPT_TIMECONDITION
,
3353 CURL_TIMECOND_IFUNMODSINCE
);
3357 failwith("Invalid TIMECOND Option");
3361 if (result
!= CURLE_OK
)
3362 raiseError(conn
, result
);
3367 static void handleTimeValue(Connection
*conn
, value option
)
3370 CURLcode result
= CURLE_OK
;
3372 result
= curl_easy_setopt(conn
->connection
,
3376 if (result
!= CURLE_OK
)
3377 raiseError(conn
, result
);
3382 static void handleCustomRequest(Connection
*conn
, value option
)
3385 CURLcode result
= CURLE_OK
;
3387 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3389 if (conn
->customRequest
!= NULL
)
3390 free(conn
->customRequest
);
3392 conn
->customRequest
= strdup(String_val(option
));
3394 result
= curl_easy_setopt(conn
->connection
,
3395 CURLOPT_CUSTOMREQUEST
,
3396 conn
->customRequest
);
3398 if (result
!= CURLE_OK
)
3399 raiseError(conn
, result
);
3404 static void handleInterface(Connection
*conn
, value option
)
3407 CURLcode result
= CURLE_OK
;
3409 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3411 if (conn
->interface
!= NULL
)
3412 free(conn
->interface
);
3414 conn
->interface
= strdup(String_val(option
));
3416 result
= curl_easy_setopt(conn
->connection
,
3420 if (result
!= CURLE_OK
)
3421 raiseError(conn
, result
);
3426 static void handleKRB4Level(Connection
*conn
, value option
)
3429 CURLcode result
= CURLE_OK
;
3431 switch (Long_val(option
))
3433 case 0: /* KRB4_NONE */
3434 result
= curl_easy_setopt(conn
->connection
,
3439 case 1: /* KRB4_CLEAR */
3440 result
= curl_easy_setopt(conn
->connection
,
3445 case 2: /* KRB4_SAFE */
3446 result
= curl_easy_setopt(conn
->connection
,
3451 case 3: /* KRB4_CONFIDENTIAL */
3452 result
= curl_easy_setopt(conn
->connection
,
3457 case 4: /* KRB4_PRIVATE */
3458 result
= curl_easy_setopt(conn
->connection
,
3464 failwith("Invalid KRB4 Option");
3468 if (result
!= CURLE_OK
)
3469 raiseError(conn
, result
);
3474 static void handleProgressFunction(Connection
*conn
, value option
)
3477 CURLcode result
= CURLE_OK
;
3479 if (Tag_val(option
) == Closure_tag
)
3480 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3482 failwith("Not a proper closure");
3484 result
= curl_easy_setopt(conn
->connection
,
3485 CURLOPT_PROGRESSFUNCTION
,
3487 if (result
!= CURLE_OK
)
3488 raiseError(conn
, result
);
3490 result
= curl_easy_setopt(conn
->connection
,
3491 CURLOPT_PROGRESSDATA
,
3494 if (result
!= CURLE_OK
)
3495 raiseError(conn
, result
);
3500 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3503 CURLcode result
= CURLE_OK
;
3505 result
= curl_easy_setopt(conn
->connection
,
3506 CURLOPT_SSL_VERIFYPEER
,
3509 if (result
!= CURLE_OK
)
3510 raiseError(conn
, result
);
3515 static void handleCAInfo(Connection
*conn
, value option
)
3518 CURLcode result
= CURLE_OK
;
3520 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3522 if (conn
->caInfo
!= NULL
)
3525 conn
->caInfo
= strdup(String_val(option
));
3527 result
= curl_easy_setopt(conn
->connection
,
3531 if (result
!= CURLE_OK
)
3532 raiseError(conn
, result
);
3537 static void handleCAPath(Connection
*conn
, value option
)
3540 CURLcode result
= CURLE_OK
;
3542 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3544 if (conn
->caPath
!= NULL
)
3547 conn
->caPath
= strdup(String_val(option
));
3549 result
= curl_easy_setopt(conn
->connection
,
3553 if (result
!= CURLE_OK
)
3554 raiseError(conn
, result
);
3559 static void handleFileTime(Connection
*conn
, value option
)
3562 CURLcode result
= CURLE_OK
;
3564 result
= curl_easy_setopt(conn
->connection
,
3568 if (result
!= CURLE_OK
)
3569 raiseError(conn
, result
);
3574 static void handleMaxRedirs(Connection
*conn
, value option
)
3577 CURLcode result
= CURLE_OK
;
3579 result
= curl_easy_setopt(conn
->connection
,
3583 if (result
!= CURLE_OK
)
3584 raiseError(conn
, result
);
3589 static void handleMaxConnects(Connection
*conn
, value option
)
3592 CURLcode result
= CURLE_OK
;
3594 result
= curl_easy_setopt(conn
->connection
,
3595 CURLOPT_MAXCONNECTS
,
3598 if (result
!= CURLE_OK
)
3599 raiseError(conn
, result
);
3604 static void handleClosePolicy(Connection
*conn
, value option
)
3607 CURLcode result
= CURLE_OK
;
3609 switch (Long_val(option
))
3611 case 0: /* CLOSEPOLICY_OLDEST */
3612 result
= curl_easy_setopt(conn
->connection
,
3613 CURLOPT_CLOSEPOLICY
,
3614 CURLCLOSEPOLICY_OLDEST
);
3617 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3618 result
= curl_easy_setopt(conn
->connection
,
3619 CURLOPT_CLOSEPOLICY
,
3620 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3624 failwith("Invalid CLOSEPOLICY Option");
3628 if (result
!= CURLE_OK
)
3629 raiseError(conn
, result
);
3634 static void handleFreshConnect(Connection
*conn
, value option
)
3637 CURLcode result
= CURLE_OK
;
3639 result
= curl_easy_setopt(conn
->connection
,
3640 CURLOPT_FRESH_CONNECT
,
3643 if (result
!= CURLE_OK
)
3644 raiseError(conn
, result
);
3649 static void handleForbidReuse(Connection
*conn
, value option
)
3652 CURLcode result
= CURLE_OK
;
3654 result
= curl_easy_setopt(conn
->connection
,
3655 CURLOPT_FORBID_REUSE
,
3658 if (result
!= CURLE_OK
)
3659 raiseError(conn
, result
);
3664 static void handleRandomFile(Connection
*conn
, value option
)
3667 CURLcode result
= CURLE_OK
;
3669 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3671 if (conn
->randomFile
!= NULL
)
3672 free(conn
->randomFile
);
3674 conn
->randomFile
= strdup(String_val(option
));
3676 result
= curl_easy_setopt(conn
->connection
,
3677 CURLOPT_RANDOM_FILE
,
3680 if (result
!= CURLE_OK
)
3681 raiseError(conn
, result
);
3686 static void handleEGDSocket(Connection
*conn
, value option
)
3689 CURLcode result
= CURLE_OK
;
3691 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3693 if (conn
->egdSocket
!= NULL
)
3694 free(conn
->egdSocket
);
3696 conn
->egdSocket
= strdup(String_val(option
));
3698 result
= curl_easy_setopt(conn
->connection
,
3702 if (result
!= CURLE_OK
)
3703 raiseError(conn
, result
);
3708 static void handleConnectTimeout(Connection
*conn
, value option
)
3711 CURLcode result
= CURLE_OK
;
3713 result
= curl_easy_setopt(conn
->connection
,
3714 CURLOPT_CONNECTTIMEOUT
,
3717 if (result
!= CURLE_OK
)
3718 raiseError(conn
, result
);
3723 static void handleHTTPGet(Connection
*conn
, value option
)
3726 CURLcode result
= CURLE_OK
;
3728 result
= curl_easy_setopt(conn
->connection
,
3732 if (result
!= CURLE_OK
)
3733 raiseError(conn
, result
);
3738 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3741 CURLcode result
= CURLE_OK
;
3743 switch (Long_val(option
))
3745 case 0: /* SSLVERIFYHOST_EXISTENCE */
3746 result
= curl_easy_setopt(conn
->connection
,
3747 CURLOPT_SSL_VERIFYHOST
,
3751 case 1: /* SSLVERIFYHOST_HOSTNAME */
3752 result
= curl_easy_setopt(conn
->connection
,
3753 CURLOPT_SSL_VERIFYHOST
,
3758 failwith("Invalid SSLVERIFYHOST Option");
3762 if (result
!= CURLE_OK
)
3763 raiseError(conn
, result
);
3768 static void handleCookieJar(Connection
*conn
, value option
)
3771 CURLcode result
= CURLE_OK
;
3773 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3775 if (conn
->cookieJar
!= NULL
)
3776 free(conn
->cookieJar
);
3778 conn
->cookieJar
= strdup(String_val(option
));
3780 result
= curl_easy_setopt(conn
->connection
,
3784 if (result
!= CURLE_OK
)
3785 raiseError(conn
, result
);
3790 static void handleSSLCipherList(Connection
*conn
, value option
)
3793 CURLcode result
= CURLE_OK
;
3795 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3797 if (conn
->sslCipherList
!= NULL
)
3798 free(conn
->sslCipherList
);
3800 conn
->sslCipherList
= strdup(String_val(option
));
3802 result
= curl_easy_setopt(conn
->connection
,
3803 CURLOPT_SSL_CIPHER_LIST
,
3804 conn
->sslCipherList
);
3806 if (result
!= CURLE_OK
)
3807 raiseError(conn
, result
);
3812 static void handleHTTPVersion(Connection
*conn
, value option
)
3815 CURLcode result
= CURLE_OK
;
3817 switch (Long_val(option
))
3819 case 0: /* HTTP_VERSION_NONE */
3820 result
= curl_easy_setopt(conn
->connection
,
3821 CURLOPT_HTTP_VERSION
,
3822 CURL_HTTP_VERSION_NONE
);
3825 case 1: /* HTTP_VERSION_1_0 */
3826 result
= curl_easy_setopt(conn
->connection
,
3827 CURLOPT_HTTP_VERSION
,
3828 CURL_HTTP_VERSION_1_0
);
3831 case 2: /* HTTP_VERSION_1_1 */
3832 result
= curl_easy_setopt(conn
->connection
,
3833 CURLOPT_HTTP_VERSION
,
3834 CURL_HTTP_VERSION_1_1
);
3838 failwith("Invalid HTTP_VERSION Option");
3842 if (result
!= CURLE_OK
)
3843 raiseError(conn
, result
);
3848 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3851 CURLcode result
= CURLE_OK
;
3853 result
= curl_easy_setopt(conn
->connection
,
3854 CURLOPT_FTP_USE_EPSV
,
3857 if (result
!= CURLE_OK
)
3858 raiseError(conn
, result
);
3863 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3866 CURLcode result
= CURLE_OK
;
3868 result
= curl_easy_setopt(conn
->connection
,
3869 CURLOPT_DNS_CACHE_TIMEOUT
,
3872 if (result
!= CURLE_OK
)
3873 raiseError(conn
, result
);
3878 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3881 CURLcode result
= CURLE_OK
;
3883 result
= curl_easy_setopt(conn
->connection
,
3884 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3887 if (result
!= CURLE_OK
)
3888 raiseError(conn
, result
);
3893 static void handleDebugFunction(Connection
*conn
, value option
)
3896 CURLcode result
= CURLE_OK
;
3898 if (Tag_val(option
) == Closure_tag
)
3899 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3901 failwith("Not a proper closure");
3903 result
= curl_easy_setopt(conn
->connection
,
3904 CURLOPT_DEBUGFUNCTION
,
3906 if (result
!= CURLE_OK
)
3907 raiseError(conn
, result
);
3909 result
= curl_easy_setopt(conn
->connection
,
3913 if (result
!= CURLE_OK
)
3914 raiseError(conn
, result
);
3919 static void handlePrivate(Connection
*conn
, value option
)
3921 #if HAVE_DECL_CURLOPT_PRIVATE
3923 CURLcode result
= CURLE_OK
;
3925 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
3927 if (conn
->private != NULL
)
3928 free(conn
->private);
3930 conn
->private = strdup(String_val(option
));
3932 result
= curl_easy_setopt(conn
->connection
,
3936 if (result
!= CURLE_OK
)
3937 raiseError(conn
, result
);
3941 #warning "libcurl does not implement CURLOPT_PRIVATE"
3942 failwith("libcurl does not implement CURLOPT_PRIVATE");
3946 static void handleHTTP200Aliases(Connection
*conn
, value option
)
3948 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3950 CAMLlocal1(listIter
);
3951 CURLcode result
= CURLE_OK
;
3954 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
3956 if (conn
->http200Aliases
!= NULL
)
3957 free_curl_slist(conn
->http200Aliases
);
3959 conn
->http200Aliases
= NULL
;
3963 while (!Is_long(listIter
))
3965 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3966 failwith("Not a string");
3968 str
= strdup(String_val(Field(listIter
, 0)));
3970 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, str
);
3972 listIter
= Field(listIter
, 1);
3975 result
= curl_easy_setopt(conn
->connection
,
3976 CURLOPT_HTTP200ALIASES
,
3977 conn
->http200Aliases
);
3979 if (result
!= CURLE_OK
)
3980 raiseError(conn
, result
);
3984 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
3985 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
3989 static void handleUnrestrictedAuth(Connection
*conn
, value option
)
3991 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
3993 CURLcode result
= CURLE_OK
;
3995 result
= curl_easy_setopt(conn
->connection
,
3996 CURLOPT_UNRESTRICTED_AUTH
,
3999 if (result
!= CURLE_OK
)
4000 raiseError(conn
, result
);
4004 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4005 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4009 static void handleFTPUseEPRT(Connection
*conn
, value option
)
4011 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4013 CURLcode result
= CURLE_OK
;
4015 result
= curl_easy_setopt(conn
->connection
,
4016 CURLOPT_FTP_USE_EPRT
,
4019 if (result
!= CURLE_OK
)
4020 raiseError(conn
, result
);
4024 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4025 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4029 static void handleHTTPAuth(Connection
*conn
, value option
)
4031 #if HAVE_DECL_CURLOPT_HTTPAUTH
4033 CAMLlocal1(listIter
);
4034 CURLcode result
= CURLE_OK
;
4035 long auth
= CURLAUTH_NONE
;
4039 while (!Is_long(listIter
))
4041 switch (Long_val(Field(listIter
, 0)))
4043 case 0: /* CURLAUTH_BASIC */
4044 auth
|= CURLAUTH_BASIC
;
4047 case 1: /* CURLAUTH_DIGEST */
4048 auth
|= CURLAUTH_DIGEST
;
4051 case 2: /* CURLAUTH_GSSNEGOTIATE */
4052 auth
|= CURLAUTH_GSSNEGOTIATE
;
4055 case 3: /* CURLAUTH_NTLM */
4056 auth
|= CURLAUTH_NTLM
;
4059 case 4: /* CURLAUTH_ANY */
4060 auth
|= CURLAUTH_ANY
;
4063 case 5: /* CURLAUTH_ANYSAFE */
4064 auth
|= CURLAUTH_ANYSAFE
;
4068 failwith("Invalid HTTPAUTH Value");
4072 listIter
= Field(listIter
, 1);
4075 result
= curl_easy_setopt(conn
->connection
,
4079 if (result
!= CURLE_OK
)
4080 raiseError(conn
, result
);
4084 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4085 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4089 static void handleFTPCreateMissingDirs(Connection
*conn
, value option
)
4091 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4093 CURLcode result
= CURLE_OK
;
4095 result
= curl_easy_setopt(conn
->connection
,
4096 CURLOPT_FTP_CREATE_MISSING_DIRS
,
4099 if (result
!= CURLE_OK
)
4100 raiseError(conn
, result
);
4104 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4105 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4109 static void handleProxyAuth(Connection
*conn
, value option
)
4111 #if HAVE_DECL_CURLOPT_PROXYAUTH
4113 CAMLlocal1(listIter
);
4114 CURLcode result
= CURLE_OK
;
4115 long auth
= CURLAUTH_NONE
;
4119 while (!Is_long(listIter
))
4121 switch (Long_val(Field(listIter
, 0)))
4123 case 0: /* CURLAUTH_BASIC */
4124 auth
|= CURLAUTH_BASIC
;
4127 case 1: /* CURLAUTH_DIGEST */
4128 auth
|= CURLAUTH_DIGEST
;
4131 case 2: /* CURLAUTH_GSSNEGOTIATE */
4132 auth
|= CURLAUTH_GSSNEGOTIATE
;
4135 case 3: /* CURLAUTH_NTLM */
4136 auth
|= CURLAUTH_NTLM
;
4139 case 4: /* CURLAUTH_ANY */
4140 auth
|= CURLAUTH_ANY
;
4143 case 5: /* CURLAUTH_ANYSAFE */
4144 auth
|= CURLAUTH_ANYSAFE
;
4148 failwith("Invalid HTTPAUTH Value");
4152 listIter
= Field(listIter
, 1);
4155 result
= curl_easy_setopt(conn
->connection
,
4159 if (result
!= CURLE_OK
)
4160 raiseError(conn
, result
);
4164 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4165 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4169 static void handleFTPResponseTimeout(Connection
*conn
, value option
)
4171 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4173 CURLcode result
= CURLE_OK
;
4175 result
= curl_easy_setopt(conn
->connection
,
4176 CURLOPT_FTP_RESPONSE_TIMEOUT
,
4179 if (result
!= CURLE_OK
)
4180 raiseError(conn
, result
);
4184 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4185 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4189 static void handleIPResolve(Connection
*conn
, value option
)
4191 #if HAVE_DECL_CURLOPT_IPRESOLVE
4193 CURLcode result
= CURLE_OK
;
4195 switch (Long_val(option
))
4197 case 0: /* CURL_IPRESOLVE_WHATEVER */
4198 result
= curl_easy_setopt(conn
->connection
,
4200 CURL_IPRESOLVE_WHATEVER
);
4203 case 1: /* CURL_IPRESOLVE_V4 */
4204 result
= curl_easy_setopt(conn
->connection
,
4209 case 2: /* CURL_IPRESOLVE_V6 */
4210 result
= curl_easy_setopt(conn
->connection
,
4216 failwith("Invalid IPRESOLVE Value");
4220 if (result
!= CURLE_OK
)
4221 raiseError(conn
, result
);
4225 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4226 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4230 static void handleMaxFileSize(Connection
*conn
, value option
)
4232 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4234 CURLcode result
= CURLE_OK
;
4236 result
= curl_easy_setopt(conn
->connection
,
4237 CURLOPT_MAXFILESIZE
,
4240 if (result
!= CURLE_OK
)
4241 raiseError(conn
, result
);
4245 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4246 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4250 static void handleInFileSizeLarge(Connection
*conn
, value option
)
4252 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4254 CURLcode result
= CURLE_OK
;
4256 result
= curl_easy_setopt(conn
->connection
,
4257 CURLOPT_INFILESIZE_LARGE
,
4260 if (result
!= CURLE_OK
)
4261 raiseError(conn
, result
);
4265 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4266 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4270 static void handleResumeFromLarge(Connection
*conn
, value option
)
4272 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4274 CURLcode result
= CURLE_OK
;
4276 result
= curl_easy_setopt(conn
->connection
,
4277 CURLOPT_RESUME_FROM_LARGE
,
4280 if (result
!= CURLE_OK
)
4281 raiseError(conn
, result
);
4285 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4286 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4290 static void handleMaxFileSizeLarge(Connection
*conn
, value option
)
4292 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4294 CURLcode result
= CURLE_OK
;
4296 result
= curl_easy_setopt(conn
->connection
,
4297 CURLOPT_MAXFILESIZE_LARGE
,
4300 if (result
!= CURLE_OK
)
4301 raiseError(conn
, result
);
4305 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4306 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4310 static void handleNETRCFile(Connection
*conn
, value option
)
4312 #if HAVE_DECL_CURLOPT_NETRC_FILE
4314 CURLcode result
= CURLE_OK
;
4316 Store_field(conn
->ocamlValues
, OcamlNETRCFile
, option
);
4318 if (conn
->netrcFile
!= NULL
)
4319 free(conn
->netrcFile
);
4321 conn
->netrcFile
= strdup(String_val(option
));
4323 result
= curl_easy_setopt(conn
->connection
,
4327 if (result
!= CURLE_OK
)
4328 raiseError(conn
, result
);
4332 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4333 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4337 static void handleFTPSSL(Connection
*conn
, value option
)
4339 #if HAVE_DECL_CURLOPT_FTP_SSL
4341 CURLcode result
= CURLE_OK
;
4343 switch (Long_val(option
))
4345 case 0: /* CURLFTPSSL_NONE */
4346 result
= curl_easy_setopt(conn
->connection
,
4351 case 1: /* CURLFTPSSL_TRY */
4352 result
= curl_easy_setopt(conn
->connection
,
4357 case 2: /* CURLFTPSSL_CONTROL */
4358 result
= curl_easy_setopt(conn
->connection
,
4360 CURLFTPSSL_CONTROL
);
4363 case 3: /* CURLFTPSSL_ALL */
4364 result
= curl_easy_setopt(conn
->connection
,
4370 failwith("Invalid FTP_SSL Value");
4374 if (result
!= CURLE_OK
)
4375 raiseError(conn
, result
);
4379 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4380 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4384 static void handlePostFieldSizeLarge(Connection
*conn
, value option
)
4386 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4388 CURLcode result
= CURLE_OK
;
4390 result
= curl_easy_setopt(conn
->connection
,
4391 CURLOPT_POSTFIELDSIZE_LARGE
,
4394 if (result
!= CURLE_OK
)
4395 raiseError(conn
, result
);
4399 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4400 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4404 static void handleTCPNoDelay(Connection
*conn
, value option
)
4406 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4408 CURLcode result
= CURLE_OK
;
4410 result
= curl_easy_setopt(conn
->connection
,
4411 CURLOPT_TCP_NODELAY
,
4414 if (result
!= CURLE_OK
)
4415 raiseError(conn
, result
);
4419 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4420 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4424 static void handleFTPSSLAuth(Connection
*conn
, value option
)
4426 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4428 CURLcode result
= CURLE_OK
;
4430 switch (Long_val(option
))
4432 case 0: /* CURLFTPAUTH_DEFAULT */
4433 result
= curl_easy_setopt(conn
->connection
,
4435 CURLFTPAUTH_DEFAULT
);
4438 case 1: /* CURLFTPAUTH_SSL */
4439 result
= curl_easy_setopt(conn
->connection
,
4444 case 2: /* CURLFTPAUTH_TLS */
4445 result
= curl_easy_setopt(conn
->connection
,
4451 failwith("Invalid FTPSSLAUTH value");
4455 if (result
!= CURLE_OK
)
4456 raiseError(conn
, result
);
4460 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4461 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4465 static void handleIOCTLFunction(Connection
*conn
, value option
)
4467 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4469 CURLcode result
= CURLE_OK
;
4471 if (Tag_val(option
) == Closure_tag
)
4472 Store_field(conn
->ocamlValues
, OcamlIOCTLCallback
, option
);
4474 failwith("Not a proper closure");
4476 result
= curl_easy_setopt(conn
->connection
,
4477 CURLOPT_IOCTLFUNCTION
,
4479 if (result
!= CURLE_OK
)
4480 raiseError(conn
, result
);
4482 result
= curl_easy_setopt(conn
->connection
,
4486 if (result
!= CURLE_OK
)
4487 raiseError(conn
, result
);
4491 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4492 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4496 static void handleFTPAccount(Connection
*conn
, value option
)
4498 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4500 CURLcode result
= CURLE_OK
;
4502 Store_field(conn
->ocamlValues
, OcamlFTPAccount
, option
);
4504 if (conn
->ftpaccount
!= NULL
)
4505 free(conn
->ftpaccount
);
4507 conn
->ftpaccount
= strdup(String_val(option
));
4509 result
= curl_easy_setopt(conn
->connection
,
4510 CURLOPT_FTP_ACCOUNT
,
4513 if (result
!= CURLE_OK
)
4514 raiseError(conn
, result
);
4518 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4519 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4523 static void handleCookieList(Connection
*conn
, value option
)
4525 #if HAVE_DECL_CURLOPT_COOKIELIST
4527 CURLcode result
= CURLE_OK
;
4529 Store_field(conn
->ocamlValues
, OcamlCookieList
, option
);
4531 if (conn
->cookielist
!= NULL
)
4532 free(conn
->cookielist
);
4534 conn
->cookielist
= strdup(String_val(option
));
4536 result
= curl_easy_setopt(conn
->connection
,
4540 if (result
!= CURLE_OK
)
4541 raiseError(conn
, result
);
4545 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4546 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4550 static void handleIgnoreContentLength(Connection
*conn
, value option
)
4552 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4554 CURLcode result
= CURLE_OK
;
4556 result
= curl_easy_setopt(conn
->connection
,
4557 CURLOPT_IGNORE_CONTENT_LENGTH
,
4560 if (result
!= CURLE_OK
)
4561 raiseError(conn
, result
);
4565 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4566 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4570 static void handleFTPSkipPASVIP(Connection
*conn
, value option
)
4572 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4574 CURLcode result
= CURLE_OK
;
4576 result
= curl_easy_setopt(conn
->connection
,
4577 CURLOPT_FTP_SKIP_PASV_IP
,
4580 if (result
!= CURLE_OK
)
4581 raiseError(conn
, result
);
4585 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4586 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4590 static void handleFTPFileMethod(Connection
*conn
, value option
)
4592 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4594 CURLcode result
= CURLE_OK
;
4596 switch (Long_val(option
))
4598 case 0: /* CURLFTPMETHOD_DEFAULT */
4599 result
= curl_easy_setopt(conn
->connection
,
4600 CURLOPT_FTP_FILEMETHOD
,
4601 CURLFTPMETHOD_DEFAULT
);
4604 case 1: /* CURLFTMETHOD_MULTICWD */
4605 result
= curl_easy_setopt(conn
->connection
,
4606 CURLOPT_FTP_FILEMETHOD
,
4607 CURLFTPMETHOD_MULTICWD
);
4610 case 2: /* CURLFTPMETHOD_NOCWD */
4611 result
= curl_easy_setopt(conn
->connection
,
4612 CURLOPT_FTP_FILEMETHOD
,
4613 CURLFTPMETHOD_NOCWD
);
4616 case 3: /* CURLFTPMETHOD_SINGLECWD */
4617 result
= curl_easy_setopt(conn
->connection
,
4618 CURLOPT_FTP_FILEMETHOD
,
4619 CURLFTPMETHOD_SINGLECWD
);
4622 failwith("Invalid FTP_FILEMETHOD value");
4626 if (result
!= CURLE_OK
)
4627 raiseError(conn
, result
);
4631 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4632 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4636 static void handleLocalPort(Connection
*conn
, value option
)
4638 #if HAVE_DECL_CURLOPT_LOCALPORT
4640 CURLcode result
= CURLE_OK
;
4642 result
= curl_easy_setopt(conn
->connection
,
4646 if (result
!= CURLE_OK
)
4647 raiseError(conn
, result
);
4651 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4652 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4656 static void handleLocalPortRange(Connection
*conn
, value option
)
4658 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4660 CURLcode result
= CURLE_OK
;
4662 result
= curl_easy_setopt(conn
->connection
,
4663 CURLOPT_LOCALPORTRANGE
,
4666 if (result
!= CURLE_OK
)
4667 raiseError(conn
, result
);
4671 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4672 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4676 static void handleConnectOnly(Connection
*conn
, value option
)
4678 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4680 CURLcode result
= CURLE_OK
;
4682 result
= curl_easy_setopt(conn
->connection
,
4683 CURLOPT_CONNECT_ONLY
,
4686 if (result
!= CURLE_OK
)
4687 raiseError(conn
, result
);
4691 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4692 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4696 static void handleMaxSendSpeedLarge(Connection
*conn
, value option
)
4698 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4700 CURLcode result
= CURLE_OK
;
4702 result
= curl_easy_setopt(conn
->connection
,
4703 CURLOPT_MAX_SEND_SPEED_LARGE
,
4706 if (result
!= CURLE_OK
)
4707 raiseError(conn
, result
);
4711 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4712 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4716 static void handleMaxRecvSpeedLarge(Connection
*conn
, value option
)
4718 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4720 CURLcode result
= CURLE_OK
;
4722 result
= curl_easy_setopt(conn
->connection
,
4723 CURLOPT_MAX_RECV_SPEED_LARGE
,
4726 if (result
!= CURLE_OK
)
4727 raiseError(conn
, result
);
4731 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4732 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4736 static void handleFTPAlternativeToUser(Connection
*conn
, value option
)
4738 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4740 CURLcode result
= CURLE_OK
;
4742 Store_field(conn
->ocamlValues
, OcamlFTPAlternativeToUser
, option
);
4744 if (conn
->ftpAlternativeToUser
!= NULL
)
4745 free(conn
->ftpAlternativeToUser
);
4747 conn
->ftpAlternativeToUser
= strdup(String_val(option
));
4749 result
= curl_easy_setopt(conn
->connection
,
4750 CURLOPT_FTP_ALTERNATIVE_TO_USER
,
4751 conn
->ftpAlternativeToUser
);
4753 if (result
!= CURLE_OK
)
4754 raiseError(conn
, result
);
4758 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4759 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4763 static void handleSSLSessionIdCache(Connection
*conn
, value option
)
4765 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4767 CURLcode result
= CURLE_OK
;
4769 result
= curl_easy_setopt(conn
->connection
,
4770 CURLOPT_SSL_SESSIONID_CACHE
,
4773 if (result
!= CURLE_OK
)
4774 raiseError(conn
, result
);
4778 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4779 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4783 static void handleSSHAuthTypes(Connection
*conn
, value option
)
4785 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4787 CAMLlocal1(listIter
);
4788 CURLcode result
= CURLE_OK
;
4789 long authTypes
= CURLSSH_AUTH_NONE
;
4793 while (!Is_long(listIter
))
4795 switch (Long_val(Field(listIter
, 0)))
4797 case 0: /* CURLSSH_AUTH_ANY */
4798 authTypes
|= CURLSSH_AUTH_ANY
;
4801 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4802 authTypes
|= CURLSSH_AUTH_PUBLICKEY
;
4805 case 2: /* CURLSSH_AUTH_PASSWORD */
4806 authTypes
|= CURLSSH_AUTH_PASSWORD
;
4809 case 3: /* CURLSSH_AUTH_HOST */
4810 authTypes
|= CURLSSH_AUTH_HOST
;
4813 case 4: /* CURLSSH_AUTH_KEYBOARD */
4814 authTypes
|= CURLSSH_AUTH_KEYBOARD
;
4818 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4822 listIter
= Field(listIter
, 1);
4825 result
= curl_easy_setopt(conn
->connection
,
4826 CURLOPT_SSH_AUTH_TYPES
,
4829 if (result
!= CURLE_OK
)
4830 raiseError(conn
, result
);
4834 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4835 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4839 static void handleSSHPublicKeyFile(Connection
*conn
, value option
)
4841 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4843 CURLcode result
= CURLE_OK
;
4845 Store_field(conn
->ocamlValues
, OcamlSSHPublicKeyFile
, option
);
4847 if (conn
->sshPublicKeyFile
!= NULL
)
4848 free(conn
->sshPublicKeyFile
);
4850 conn
->sshPublicKeyFile
= strdup(String_val(option
));
4852 result
= curl_easy_setopt(conn
->connection
,
4853 CURLOPT_SSH_PUBLIC_KEYFILE
,
4854 conn
->sshPublicKeyFile
);
4856 if (result
!= CURLE_OK
)
4857 raiseError(conn
, result
);
4861 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4862 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4866 static void handleSSHPrivateKeyFile(Connection
*conn
, value option
)
4868 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4870 CURLcode result
= CURLE_OK
;
4872 Store_field(conn
->ocamlValues
, OcamlSSHPrivateKeyFile
, option
);
4874 if (conn
->sshPrivateKeyFile
!= NULL
)
4875 free(conn
->sshPrivateKeyFile
);
4877 conn
->sshPrivateKeyFile
= strdup(String_val(option
));
4879 result
= curl_easy_setopt(conn
->connection
,
4880 CURLOPT_SSH_PRIVATE_KEYFILE
,
4881 conn
->sshPrivateKeyFile
);
4883 if (result
!= CURLE_OK
)
4884 raiseError(conn
, result
);
4888 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4889 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4893 static void handleFTPSSLCCC(Connection
*conn
, value option
)
4895 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4897 CURLcode result
= CURLE_OK
;
4899 switch (Long_val(option
))
4901 case 0: /* CURLFTPSSL_CCC_NONE */
4902 result
= curl_easy_setopt(conn
->connection
,
4903 CURLOPT_FTP_SSL_CCC
,
4904 CURLFTPSSL_CCC_NONE
);
4907 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4908 result
= curl_easy_setopt(conn
->connection
,
4909 CURLOPT_FTP_SSL_CCC
,
4910 CURLFTPSSL_CCC_PASSIVE
);
4913 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4914 result
= curl_easy_setopt(conn
->connection
,
4915 CURLOPT_FTP_SSL_CCC
,
4916 CURLFTPSSL_CCC_ACTIVE
);
4920 failwith("Invalid FTPSSL_CCC value");
4924 if (result
!= CURLE_OK
)
4925 raiseError(conn
, result
);
4929 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4930 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4934 static void handleTimeoutMS(Connection
*conn
, value option
)
4936 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4938 CURLcode result
= CURLE_OK
;
4940 result
= curl_easy_setopt(conn
->connection
,
4944 if (result
!= CURLE_OK
)
4945 raiseError(conn
, result
);
4949 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4950 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4954 static void handleConnectTimeoutMS(Connection
*conn
, value option
)
4956 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4958 CURLcode result
= CURLE_OK
;
4960 result
= curl_easy_setopt(conn
->connection
,
4961 CURLOPT_CONNECTTIMEOUT_MS
,
4964 if (result
!= CURLE_OK
)
4965 raiseError(conn
, result
);
4969 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4970 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
4974 static void handleHTTPTransferDecoding(Connection
*conn
, value option
)
4976 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
4978 CURLcode result
= CURLE_OK
;
4980 result
= curl_easy_setopt(conn
->connection
,
4981 CURLOPT_HTTP_TRANSFER_DECODING
,
4984 if (result
!= CURLE_OK
)
4985 raiseError(conn
, result
);
4989 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
4990 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
4994 static void handleHTTPContentDecoding(Connection
*conn
, value option
)
4996 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
4998 CURLcode result
= CURLE_OK
;
5000 result
= curl_easy_setopt(conn
->connection
,
5001 CURLOPT_HTTP_CONTENT_DECODING
,
5004 if (result
!= CURLE_OK
)
5005 raiseError(conn
, result
);
5009 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5010 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5014 static void handleNewFilePerms(Connection
*conn
, value option
)
5016 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5018 CURLcode result
= CURLE_OK
;
5020 result
= curl_easy_setopt(conn
->connection
,
5021 CURLOPT_NEW_FILE_PERMS
,
5024 if (result
!= CURLE_OK
)
5025 raiseError(conn
, result
);
5029 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5030 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5034 static void handleNewDirectoryPerms(Connection
*conn
, value option
)
5036 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5038 CURLcode result
= CURLE_OK
;
5040 result
= curl_easy_setopt(conn
->connection
,
5041 CURLOPT_NEW_DIRECTORY_PERMS
,
5044 if (result
!= CURLE_OK
)
5045 raiseError(conn
, result
);
5049 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5050 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5054 static void handlePost301(Connection
*conn
, value option
)
5056 #if HAVE_DECL_CURLOPT_POST301
5058 CURLcode result
= CURLE_OK
;
5060 result
= curl_easy_setopt(conn
->connection
,
5064 if (result
!= CURLE_OK
)
5065 raiseError(conn
, result
);
5069 #warning "libcurl does not implement CURLOPT_POST301"
5070 failwith("libcurl does not implement CURLOPT_POST301");
5074 static void handleSSHHostPublicKeyMD5(Connection
*conn
, value option
)
5076 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5078 CURLcode result
= CURLE_OK
;
5080 Store_field(conn
->ocamlValues
, OcamlSSHHostPublicKeyMD5
, option
);
5082 if (conn
->sshHostPublicKeyMD5
!= NULL
)
5083 free(conn
->sshHostPublicKeyMD5
);
5085 conn
->sshHostPublicKeyMD5
= strdup(String_val(option
));
5087 result
= curl_easy_setopt(conn
->connection
,
5088 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
,
5089 conn
->sshHostPublicKeyMD5
);
5091 if (result
!= CURLE_OK
)
5092 raiseError(conn
, result
);
5096 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5097 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5101 static void handleCopyPostFields(Connection
*conn
, value option
)
5103 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5105 CURLcode result
= CURLE_OK
;
5107 Store_field(conn
->ocamlValues
, OcamlCopyPostFields
, option
);
5109 if (conn
->copyPostFields
!= NULL
)
5110 free(conn
->copyPostFields
);
5112 conn
->copyPostFields
= strdup(String_val(option
));
5114 result
= curl_easy_setopt(conn
->connection
,
5115 CURLOPT_COPYPOSTFIELDS
,
5116 conn
->copyPostFields
);
5118 if (result
!= CURLE_OK
)
5119 raiseError(conn
, result
);
5123 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5124 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5128 static void handleProxyTransferMode(Connection
*conn
, value option
)
5130 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5132 CURLcode result
= CURLE_OK
;
5134 result
= curl_easy_setopt(conn
->connection
,
5135 CURLOPT_PROXY_TRANSFER_MODE
,
5138 if (result
!= CURLE_OK
)
5139 raiseError(conn
, result
);
5143 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5144 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5148 static void handleSeekFunction(Connection
*conn
, value option
)
5150 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5152 CURLcode result
= CURLE_OK
;
5154 if (Tag_val(option
) == Closure_tag
)
5155 Store_field(conn
->ocamlValues
, OcamlSeekFunctionCallback
, option
);
5157 failwith("Not a proper closure");
5159 result
= curl_easy_setopt(conn
->connection
,
5160 CURLOPT_SEEKFUNCTION
,
5163 if (result
!= CURLE_OK
)
5164 raiseError(conn
, result
);
5166 result
= curl_easy_setopt(conn
->connection
,
5170 if (result
!= CURLE_OK
)
5171 raiseError(conn
, result
);
5175 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5176 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5181 ** curl_easy_setopt helper function
5184 CAMLprim value
helper_curl_easy_setopt(value conn
, value option
)
5186 CAMLparam2(conn
, option
);
5188 Connection
*connection
= Connection_val(conn
);
5190 checkConnection(connection
);
5192 if (Is_long(option
))
5196 sprintf(error
, "Unimplemented Option: %s",
5197 findOption(unimplementedOptionMap
,
5198 (CURLoption
)(Long_val(option
))));
5203 if (!Is_block(option
))
5204 failwith("Not a block");
5206 if (Wosize_val(option
) < 1)
5207 failwith("Insufficient data in block");
5209 data
= Field(option
, 0);
5211 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5212 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5215 failwith("Invalid CURLOPT Option");
5217 CAMLreturn(Val_unit
);
5221 ** curl_easy_perform helper function
5224 CAMLprim value
helper_curl_easy_perform(value conn
)
5227 CURLcode result
= CURLE_OK
;
5228 Connection
*connection
= Connection_val(conn
);
5230 checkConnection(connection
);
5232 enter_blocking_section();
5233 result
= curl_easy_perform(connection
->connection
);
5234 leave_blocking_section();
5236 if (result
!= CURLE_OK
)
5237 raiseError(connection
, result
);
5239 CAMLreturn(Val_unit
);
5243 ** curl_easy_cleanup helper function
5246 CAMLprim value
helper_curl_easy_cleanup(value conn
)
5249 Connection
*connection
= Connection_val(conn
);
5251 checkConnection(connection
);
5253 removeConnection(connection
);
5255 CAMLreturn(Val_unit
);
5259 ** curl_easy_duphandle helper function
5262 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5266 Connection
*connection
= Connection_val(conn
);
5268 checkConnection(connection
);
5270 result
= alloc(1, Abstract_tag
);
5271 Store_field(result
, 0, (value
)duplicateConnection(connection
));
5277 ** curl_easy_getinfo helper function
5280 enum GetInfoResultType
{
5281 StringValue
, LongValue
, DoubleValue
, StringListValue
5284 value
convertStringList(struct curl_slist
*slist
)
5287 CAMLlocal3(result
, current
, next
);
5288 struct curl_slist
*p
= slist
;
5290 result
= Val_int(0);
5291 current
= Val_int(0);
5296 next
= alloc_tuple(2);
5297 Store_field(next
, 0, copy_string(p
->data
));
5298 Store_field(next
, 1, Val_int(0));
5300 if (result
== Val_int(0))
5303 if (current
!= Val_int(0))
5304 Store_field(current
, 1, next
);
5311 curl_slist_free_all(slist
);
5316 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5318 CAMLparam2(conn
, option
);
5320 CURLcode curlResult
;
5321 Connection
*connection
= Connection_val(conn
);
5322 enum GetInfoResultType resultType
;
5323 char *strValue
= NULL
;
5326 struct curl_slist
*stringListValue
= NULL
;
5328 checkConnection(connection
);
5330 switch(Long_val(option
))
5332 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5333 case 0: /* CURLINFO_EFFECTIVE_URL */
5334 resultType
= StringValue
;
5336 curlResult
= curl_easy_getinfo(connection
->connection
,
5337 CURLINFO_EFFECTIVE_URL
,
5341 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5344 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5345 case 1: /* CURLINFO_HTTP_CODE */
5346 case 2: /* CURLINFO_RESPONSE_CODE */
5347 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5348 resultType
= LongValue
;
5350 curlResult
= curl_easy_getinfo(connection
->connection
,
5351 CURLINFO_RESPONSE_CODE
,
5354 resultType
= LongValue
;
5356 curlResult
= curl_easy_getinfo(connection
->connection
,
5363 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5364 case 3: /* CURLINFO_TOTAL_TIME */
5365 resultType
= DoubleValue
;
5367 curlResult
= curl_easy_getinfo(connection
->connection
,
5368 CURLINFO_TOTAL_TIME
,
5373 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5374 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5375 resultType
= DoubleValue
;
5377 curlResult
= curl_easy_getinfo(connection
->connection
,
5378 CURLINFO_NAMELOOKUP_TIME
,
5383 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5384 case 5: /* CURLINFO_CONNECT_TIME */
5385 resultType
= DoubleValue
;
5387 curlResult
= curl_easy_getinfo(connection
->connection
,
5388 CURLINFO_CONNECT_TIME
,
5393 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5394 case 6: /* CURLINFO_PRETRANSFER_TIME */
5395 resultType
= DoubleValue
;
5397 curlResult
= curl_easy_getinfo(connection
->connection
,
5398 CURLINFO_PRETRANSFER_TIME
,
5403 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5404 case 7: /* CURLINFO_SIZE_UPLOAD */
5405 resultType
= DoubleValue
;
5407 curlResult
= curl_easy_getinfo(connection
->connection
,
5408 CURLINFO_SIZE_UPLOAD
,
5413 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5414 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5415 resultType
= DoubleValue
;
5417 curlResult
= curl_easy_getinfo(connection
->connection
,
5418 CURLINFO_SIZE_DOWNLOAD
,
5423 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5424 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5425 resultType
= DoubleValue
;
5427 curlResult
= curl_easy_getinfo(connection
->connection
,
5428 CURLINFO_SPEED_DOWNLOAD
,
5433 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5434 case 10: /* CURLINFO_SPEED_UPLOAD */
5435 resultType
= DoubleValue
;
5437 curlResult
= curl_easy_getinfo(connection
->connection
,
5438 CURLINFO_SPEED_UPLOAD
,
5444 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5445 case 11: /* CURLINFO_HEADER_SIZE */
5446 resultType
= LongValue
;
5448 curlResult
= curl_easy_getinfo(connection
->connection
,
5449 CURLINFO_HEADER_SIZE
,
5454 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5455 case 12: /* CURLINFO_REQUEST_SIZE */
5456 resultType
= LongValue
;
5458 curlResult
= curl_easy_getinfo(connection
->connection
,
5459 CURLINFO_REQUEST_SIZE
,
5464 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5465 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5466 resultType
= LongValue
;
5468 curlResult
= curl_easy_getinfo(connection
->connection
,
5469 CURLINFO_SSL_VERIFYRESULT
,
5474 #if HAVE_DECL_CURLINFO_FILETIME
5475 case 14: /* CURLINFO_FILETIME */
5476 resultType
= DoubleValue
;
5478 curlResult
= curl_easy_getinfo(connection
->connection
,
5484 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5485 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5486 resultType
= DoubleValue
;
5488 curlResult
= curl_easy_getinfo(connection
->connection
,
5489 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5494 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5495 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5496 resultType
= DoubleValue
;
5498 curlResult
= curl_easy_getinfo(connection
->connection
,
5499 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5504 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5505 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5506 resultType
= DoubleValue
;
5508 curlResult
= curl_easy_getinfo(connection
->connection
,
5509 CURLINFO_STARTTRANSFER_TIME
,
5514 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5515 case 18: /* CURLINFO_CONTENT_TYPE */
5516 resultType
= StringValue
;
5518 curlResult
= curl_easy_getinfo(connection
->connection
,
5519 CURLINFO_CONTENT_TYPE
,
5524 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5525 case 19: /* CURLINFO_REDIRECT_TIME */
5526 resultType
= DoubleValue
;
5528 curlResult
= curl_easy_getinfo(connection
->connection
,
5529 CURLINFO_REDIRECT_TIME
,
5534 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5535 case 20: /* CURLINFO_REDIRECT_COUNT */
5536 resultType
= LongValue
;
5538 curlResult
= curl_easy_getinfo(connection
->connection
,
5539 CURLINFO_REDIRECT_COUNT
,
5544 #if HAVE_DECL_CURLINFO_PRIVATE
5545 case 21: /* CURLINFO_PRIVATE */
5546 resultType
= StringValue
;
5548 curlResult
= curl_easy_getinfo(connection
->connection
,
5554 #if HAVE_DECL_CURLINFO_HTTP_CONNECT_CODE
5555 case 22: /* CURLINFO_HTTP_CONNECT_CODE */
5556 resultType
= LongValue
;
5558 curlResult
= curl_easy_getinfo(connection
->connection
,
5559 CURLINFO_HTTP_CONNECT_CODE
,
5564 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5565 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5566 resultType
= LongValue
;
5568 curlResult
= curl_easy_getinfo(connection
->connection
,
5569 CURLINFO_HTTPAUTH_AVAIL
,
5574 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5575 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5576 resultType
= LongValue
;
5578 curlResult
= curl_easy_getinfo(connection
->connection
,
5579 CURLINFO_PROXYAUTH_AVAIL
,
5584 #if HAVE_DECL_CURLINFO_OS_ERRNO
5585 case 25: /* CURLINFO_OS_ERRNO */
5586 resultType
= LongValue
;
5588 curlResult
= curl_easy_getinfo(connection
->connection
,
5594 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5595 case 26: /* CURLINFO_NUM_CONNECTS */
5596 resultType
= LongValue
;
5598 curlResult
= curl_easy_getinfo(connection
->connection
,
5599 CURLINFO_NUM_CONNECTS
,
5604 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5605 case 27: /* CURLINFO_SSL_ENGINES */
5606 resultType
= StringListValue
;
5608 curlResult
= curl_easy_getinfo(connection
->connection
,
5609 CURLINFO_SSL_ENGINES
,
5614 #if HAVE_DECL_CURLINFO_COOKIELIST
5615 case 28: /* CURLINFO_COOKIELIST */
5616 resultType
= StringListValue
;
5618 curlResult
= curl_easy_getinfo(connection
->connection
,
5619 CURLINFO_COOKIELIST
,
5624 #if HAVE_DECL_CURLINFO_LASTSOCKET
5625 case 29: /* CURLINFO_LASTSOCKET */
5626 resultType
= LongValue
;
5628 curlResult
= curl_easy_getinfo(connection
->connection
,
5629 CURLINFO_LASTSOCKET
,
5635 failwith("Invalid CURLINFO Option");
5639 if (curlResult
!= CURLE_OK
)
5640 raiseError(connection
, curlResult
);
5645 result
= alloc(1, StringValue
);
5647 libcurl can return NULL, e.g. for CONTENT_TYPE or PRIVATE
5648 alternative: add StringOptionValue and break API..
5650 Store_field(result
, 0, copy_string(strValue
?strValue
:""));
5654 result
= alloc(1, LongValue
);
5655 Store_field(result
, 0, Val_long(longValue
));
5659 result
= alloc(1, DoubleValue
);
5660 Store_field(result
, 0, copy_double(doubleValue
));
5663 case StringListValue
:
5664 result
= alloc(1, StringListValue
);
5665 Store_field(result
, 0, convertStringList(stringListValue
));
5673 ** curl_escape helper function
5676 CAMLprim value
helper_curl_escape(value str
)
5682 curlResult
= curl_escape(String_val(str
), string_length(str
));
5683 result
= copy_string(curlResult
);
5690 ** curl_unescape helper function
5693 CAMLprim value
helper_curl_unescape(value str
)
5699 curlResult
= curl_unescape(String_val(str
), string_length(str
));
5700 result
= copy_string(curlResult
);
5707 ** curl_getdate helper function
5710 CAMLprim value
helper_curl_getdate(value str
, value now
)
5712 CAMLparam2(str
, now
);
5717 curlNow
= (time_t)Double_val(now
);
5718 curlResult
= curl_getdate(String_val(str
), &curlNow
);
5719 result
= copy_double((double)curlResult
);
5725 ** curl_version helper function
5728 CAMLprim value
helper_curl_version(void)
5734 str
= curl_version();
5735 result
= copy_string(str
);
5741 * Curl multi stack support
5743 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5744 * Other exported functions are prefixed with caml_curlm_, some of them
5745 * can/should be decomposed into smaller parts.
5748 #define CURLM_val(v) ((CURLM*)v)
5749 #define Val_CURLM(h) ((value)h)
5751 CAMLprim value
caml_curl_multi_init(value unit
)
5756 h
= curl_multi_init();
5759 failwith("caml_curl_multi_init");
5761 CAMLreturn(Val_CURLM(h
));
5764 CAMLprim value
caml_curl_multi_cleanup(value handle
)
5768 if (CURLM_OK
!= curl_multi_cleanup(CURLM_val(handle
)))
5769 failwith("caml_curl_multi_cleanup");
5771 CAMLreturn(Val_unit
);
5774 static CURL
* curlm_remove_finished(CURLM
* multi_handle
)
5776 int msgs_in_queue
= 0;
5780 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
5781 if (NULL
== msg
) return NULL
;
5782 if (CURLMSG_DONE
== msg
->msg
)
5784 CURL
* easy_handle
= msg
->easy_handle
;
5785 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
5787 //failwith("curlm_remove_finished");
5794 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
5796 CAMLparam1(v_multi
);
5799 CURLM
* multi_handle
;
5801 multi_handle
= CURLM_val(v_multi
);
5803 caml_enter_blocking_section();
5804 handle
= curlm_remove_finished(multi_handle
);
5805 caml_leave_blocking_section();
5809 CAMLreturn(Val_none
);
5814 v_easy
= alloc(1, Abstract_tag
);
5815 Store_field(v_easy
, 0, (value
)findConnection(handle
));
5816 CAMLreturn(Val_some(v_easy
));
5820 static int curlm_wait_data(CURLM
* multi_handle
)
5822 struct timeval timeout
;
5834 /* set a suitable timeout */
5836 timeout
.tv_usec
= 0;
5838 /* get file descriptors from the transfers */
5839 ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
5841 if (ret
== CURLM_OK
&& maxfd
>= 0)
5843 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
5844 if (-1 != rc
) return 0;
5845 //printf("select error\n");
5849 //printf("curl_multi_fdset error\n");
5854 CAMLprim value
caml_curlm_wait_data(value v_multi
)
5856 CAMLparam1(v_multi
);
5860 h
= CURLM_val(v_multi
);
5862 caml_enter_blocking_section();
5863 ret
= curlm_wait_data(h
);
5864 caml_leave_blocking_section();
5866 CAMLreturn(Val_bool(0 == ret
));
5869 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
5871 CAMLparam2(v_multi
,v_easy
);
5873 if (CURLM_OK
!= curl_multi_add_handle(CURLM_val(v_multi
), Connection_val(v_easy
)->connection
))
5874 failwith("caml_curl_multi_add_handle");
5876 CAMLreturn(Val_unit
);
5879 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
5881 CAMLparam1(v_multi
);
5883 int still_running
= 0;
5885 h
= CURLM_val(v_multi
);
5887 caml_enter_blocking_section();
5888 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
5889 caml_leave_blocking_section();
5891 CAMLreturn(Val_int(still_running
));