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."
25 void leave_blocking_section(void);
26 void enter_blocking_section(void);
28 #define Val_none Val_int(0)
35 some
= caml_alloc(1, 0);
36 Store_field( some
, 0, v
);
40 typedef struct Connection Connection
;
41 typedef struct ConnectionList ConnectionList
;
43 #define Connection_val(v) ((Connection *)Field(v, 0))
56 OcamlProgressCallback
,
61 OcamlSeekFunctionCallback
,
93 OcamlFTPAlternativeToUser
,
94 OcamlSSHPublicKeyFile
,
95 OcamlSSHPrivateKeyFile
,
96 OcamlSSHHostPublicKeyMD5
,
99 /* Not used, last for size */
123 struct curl_slist
*httpHeader
;
124 struct curl_httppost
*httpPostFirst
;
125 struct curl_httppost
*httpPostLast
;
126 struct curl_slist
*httpPostStrings
;
134 struct curl_slist
*quote
;
135 struct curl_slist
*postQuote
;
146 struct curl_slist
*http200Aliases
;
150 char *ftpAlternativeToUser
;
151 char *sshPublicKeyFile
;
152 char *sshPrivateKeyFile
;
153 char *sshHostPublicKeyMD5
;
154 char *copyPostFields
;
157 struct ConnectionList
163 static ConnectionList connectionList
= {NULL
, NULL
};
165 typedef struct CURLErrorMapping CURLErrorMapping
;
167 struct CURLErrorMapping
173 CURLErrorMapping errorMap
[] =
175 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
176 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL
},
178 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
180 #if HAVE_DECL_CURLE_FAILED_INIT
181 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT
},
183 {"CURLE_FAILED_INIT", -1},
185 #if HAVE_DECL_CURLE_URL_MALFORMAT
186 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT
},
188 {"CURLE_URL_MALFORMAT", -1},
190 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
191 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER
},
193 {"CURLE_URL_MALFORMAT_USER", -1},
195 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
196 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY
},
198 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
200 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
201 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST
},
203 {"CURLE_COULDNT_RESOLVE_HOST", -1},
205 #if HAVE_DECL_CURLE_COULDNT_CONNECT
206 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT
},
208 {"CURLE_COULDNT_CONNECT", -1},
210 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
211 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY
},
213 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
215 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
216 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED
},
218 {"CURLE_FTP_ACCESS_DENIED", -1},
220 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
221 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT
},
223 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
225 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
226 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY
},
228 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
230 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
231 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY
},
233 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
235 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
236 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY
},
238 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
240 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
241 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT
},
243 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
245 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
246 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST
},
248 {"CURLE_FTP_CANT_GET_HOST", -1},
250 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
251 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT
},
253 {"CURLE_FTP_CANT_RECONNECT", -1},
255 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
256 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY
},
258 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
260 #if HAVE_DECL_CURLE_PARTIAL_FILE
261 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE
},
263 {"CURLE_PARTIAL_FILE", -1},
265 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
266 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE
},
268 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
270 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
271 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR
},
273 {"CURLE_FTP_WRITE_ERROR", -1},
275 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
276 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR
},
278 {"CURLE_FTP_QUOTE_ERROR", -1},
280 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
281 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND
},
283 {"CURLE_HTTP_NOT_FOUND", -1},
285 #if HAVE_DECL_CURLE_WRITE_ERROR
286 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR
},
288 {"CURLE_WRITE_ERROR", -1},
290 #if HAVE_DECL_CURLE_MALFORMAT_USER
291 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER
},
293 {"CURLE_MALFORMAT_USER", -1},
295 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
296 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE
},
298 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
300 #if HAVE_DECL_CURLE_READ_ERROR
301 {"CURLE_READ_ERROR", CURLE_READ_ERROR
},
303 {"CURLE_READ_ERROR", -1},
305 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
306 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY
},
308 {"CURLE_OUT_OF_MEMORY", -1},
310 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
311 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED
},
313 {"CURLE_OPERATION_TIMEOUTED", -1},
315 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
316 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII
},
318 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
320 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
321 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED
},
323 {"CURLE_FTP_PORT_FAILED", -1},
325 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
326 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST
},
328 {"CURLE_FTP_COULDNT_USE_REST", -1},
330 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
331 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE
},
333 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
335 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
336 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR
},
338 {"CURLE_HTTP_RANGE_ERROR", -1},
340 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
341 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR
},
343 {"CURLE_HTTP_POST_ERROR", -1},
345 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
346 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR
},
348 {"CURLE_SSL_CONNECT_ERROR", -1},
350 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
351 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME
},
353 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
355 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
356 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE
},
358 {"CURLE_FILE_COULDNT_READ_FILE", -1},
360 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
361 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND
},
363 {"CURLE_LDAP_CANNOT_BIND", -1},
365 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
366 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED
},
368 {"CURLE_LDAP_SEARCH_FAILED", -1},
370 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
371 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND
},
373 {"CURLE_LIBRARY_NOT_FOUND", -1},
375 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
376 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND
},
378 {"CURLE_FUNCTION_NOT_FOUND", -1},
380 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
381 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK
},
383 {"CURLE_ABORTED_BY_CALLBACK", -1},
385 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
386 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT
},
388 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
390 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
391 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER
},
393 {"CURLE_BAD_CALLING_ORDER", -1},
395 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
396 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED
},
398 {"CURLE_HTTP_PORT_FAILED", -1},
400 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
401 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED
},
403 {"CURLE_BAD_PASSWORD_ENTERED", -1},
405 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
406 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS
},
408 {"CURLE_TOO_MANY_REDIRECTS", -1},
410 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
411 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION
},
413 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
415 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
416 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX
},
418 {"CURLE_TELNET_OPTION_SYNTAX", -1},
420 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
421 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE
},
423 {"CURLE_SSL_PEER_CERTIFICATE", -1},
425 #if HAVE_DECL_CURLE_GOT_NOTHING
426 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING
},
428 {"CURLE_GOT_NOTHING", -1},
430 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
431 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND
},
433 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
435 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
436 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED
},
438 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
440 #if HAVE_DECL_CURLE_SEND_ERROR
441 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR
},
443 {"CURLE_SEND_ERROR", -1},
445 #if HAVE_DECL_CURLE_RECV_ERROR
446 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR
},
448 {"CURLE_RECV_ERROR", -1},
450 #if HAVE_DECL_CURLE_SHARE_IN_USE
451 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE
},
453 {"CURLE_SHARE_IN_USE", -1},
455 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
456 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM
},
458 {"CURLE_SSL_CERTPROBLEN", -1},
460 #if HAVE_DECL_CURLE_SSL_CIPHER
461 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER
},
463 {"CURLE_SSL_CIPHER", -1},
465 #if HAVE_DECL_CURLE_SSL_CACERT
466 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT
},
468 {"CURLE_SSL_CACERT", -1},
470 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
471 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING
},
473 {"CURLE_BAD_CONTENT_ENCODING", -1},
475 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
476 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL
},
478 {"CURLE_LDAP_INVALID_URL", -1},
480 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
481 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED
},
483 {"CURLE_FILESIZE_EXCEEDED", -1},
485 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
486 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED
},
488 {"CURLE_FTP_SSL_FAILED", -1},
490 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
491 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND
},
493 {"CURLE_SEND_FAIL_REWIND", -1},
495 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
496 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED
},
498 {"CURLE_SSL_ENGINE_INITFAILED", -1},
500 #if HAVE_DECL_CURLE_LOGIN_DENIED
501 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED
},
503 {"CURLE_LOGIN_DENIED", -1},
505 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
506 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND
},
508 {"CURLE_TFTP_NOTFOUND", -1},
510 #if HAVE_DECL_CURLE_TFTP_PERM
511 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM
},
513 {"CURLE_TFTP_PERM", -1},
515 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
516 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL
},
518 {"CURLE_REMOTE_DISK_FULL", -1},
520 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
521 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL
},
523 {"CURLE_TFTP_ILLEGAL", -1},
525 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
526 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID
},
528 {"CURLE_TFTP_UNKNOWNID", -1},
530 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
531 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS
},
533 {"CURLE_REMOTE_FILE_EXISTS", -1},
535 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
536 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER
},
538 {"CURLE_TFTP_NOSUCHUSER", -1},
540 #if HAVE_DECL_CURLE_CONV_FAILED
541 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED
},
543 {"CURLE_CONV_FAILED", -1},
545 #if HAVE_DECL_CURLE_CONV_REQUIRED
546 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED
},
548 {"CURLE_CONV_REQUIRED", -1},
550 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
551 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE
},
553 {"CURLE_SSL_CACERT_BADFILE", -1},
555 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
556 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND
},
558 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
560 #if HAVE_DECL_CURLE_SSH
561 {"CURLE_SSH", CURLE_SSH
},
565 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
566 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED
},
568 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
570 #if HAVE_DECL_CURLE_AGAIN
571 {"CURLE_AGAIN", CURLE_AGAIN
},
575 {"CURLE_OK", CURLE_OK
},
579 typedef struct CURLOptionMapping CURLOptionMapping
;
581 struct CURLOptionMapping
583 void (*optionHandler
)(Connection
*, value
);
588 CURLOptionMapping unimplementedOptionMap
[] =
590 {NULL
, "CURLOPT_STDERR", CURLOPT_STDERR
},
594 static void handleWriteFunction(Connection
*, value
);
595 static void handleReadFunction(Connection
*, value
);
596 static void handleInFileSize(Connection
*, value
);
597 static void handleURL(Connection
*, value
);
598 static void handleProxy(Connection
*, value
);
599 static void handleProxyPort(Connection
*, value
);
600 static void handleHTTPProxyTunnel(Connection
*, value
);
601 static void handleVerbose(Connection
*, value
);
602 static void handleHeader(Connection
*, value
);
603 static void handleNoProgress(Connection
*, value
);
604 static void handleNoSignal(Connection
*, value
);
605 static void handleNoBody(Connection
*, value
);
606 static void handleFailOnError(Connection
*, value
);
607 static void handleUpload(Connection
*, value
);
608 static void handlePost(Connection
*, value
);
609 static void handleFTPListOnly(Connection
*, value
);
610 static void handleFTPAppend(Connection
*, value
);
611 static void handleNETRC(Connection
*, value
);
612 static void handleEncoding(Connection
*, value
);
613 static void handleFollowLocation(Connection
*, value
);
614 static void handleTransferText(Connection
*, value
);
615 static void handlePut(Connection
*, value
);
616 static void handleUserPwd(Connection
*, value
);
617 static void handleProxyUserPwd(Connection
*, value
);
618 static void handleRange(Connection
*, value
);
619 static void handleErrorBuffer(Connection
*, value
);
620 static void handleTimeout(Connection
*, value
);
621 static void handlePostFields(Connection
*, value
);
622 static void handlePostFieldSize(Connection
*, value
);
623 static void handleReferer(Connection
*, value
);
624 static void handleUserAgent(Connection
*, value
);
625 static void handleFTPPort(Connection
*, value
);
626 static void handleLowSpeedLimit(Connection
*, value
);
627 static void handleLowSpeedTime(Connection
*, value
);
628 static void handleResumeFrom(Connection
*, value
);
629 static void handleCookie(Connection
*, value
);
630 static void handleHTTPHeader(Connection
*, value
);
631 static void handleHTTPPost(Connection
*, value
);
632 static void handleSSLCert(Connection
*, value
);
633 static void handleSSLCertType(Connection
*, value
);
634 static void handleSSLCertPasswd(Connection
*, value
);
635 static void handleSSLKey(Connection
*, value
);
636 static void handleSSLKeyType(Connection
*, value
);
637 static void handleSSLKeyPasswd(Connection
*, value
);
638 static void handleSSLEngine(Connection
*, value
);
639 static void handleSSLEngineDefault(Connection
*, value
);
640 static void handleCRLF(Connection
*, value
);
641 static void handleQuote(Connection
*, value
);
642 static void handlePostQuote(Connection
*, value
);
643 static void handleHeaderFunction(Connection
*, value
);
644 static void handleCookieFile(Connection
*, value
);
645 static void handleSSLVersion(Connection
*, value
);
646 static void handleTimeCondition(Connection
*, value
);
647 static void handleTimeValue(Connection
*, value
);
648 static void handleCustomRequest(Connection
*, value
);
649 static void handleInterface(Connection
*, value
);
650 static void handleKRB4Level(Connection
*, value
);
651 static void handleProgressFunction(Connection
*, value
);
652 static void handleSSLVerifyPeer(Connection
*, value
);
653 static void handleCAInfo(Connection
*, value
);
654 static void handleCAPath(Connection
*, value
);
655 static void handlePasswdFunction(Connection
*, value
);
656 static void handleFileTime(Connection
*, value
);
657 static void handleMaxRedirs(Connection
*, value
);
658 static void handleMaxConnects(Connection
*, value
);
659 static void handleClosePolicy(Connection
*, value
);
660 static void handleFreshConnect(Connection
*, value
);
661 static void handleForbidReuse(Connection
*, value
);
662 static void handleRandomFile(Connection
*, value
);
663 static void handleEGDSocket(Connection
*, value
);
664 static void handleConnectTimeout(Connection
*, value
);
665 static void handleHTTPGet(Connection
*, value
);
666 static void handleSSLVerifyHost(Connection
*, value
);
667 static void handleCookieJar(Connection
*, value
);
668 static void handleSSLCipherList(Connection
*, value
);
669 static void handleHTTPVersion(Connection
*, value
);
670 static void handleFTPUseEPSV(Connection
*, value
);
671 static void handleDNSCacheTimeout(Connection
*, value
);
672 static void handleDNSUseGlobalCache(Connection
*, value
);
673 static void handleDebugFunction(Connection
*, value
);
674 static void handlePrivate(Connection
*, value
);
675 static void handleHTTP200Aliases(Connection
*, value
);
676 static void handleUnrestrictedAuth(Connection
*, value
);
677 static void handleFTPUseEPRT(Connection
*, value
);
678 static void handleHTTPAuth(Connection
*, value
);
679 static void handleFTPCreateMissingDirs(Connection
*, value
);
680 static void handleProxyAuth(Connection
*, value
);
681 static void handleFTPResponseTimeout(Connection
*, value
);
682 static void handleIPResolve(Connection
*, value
);
683 static void handleMaxFileSize(Connection
*, value
);
684 static void handleInFileSizeLarge(Connection
*, value
);
685 static void handleResumeFromLarge(Connection
*, value
);
686 static void handleMaxFileSizeLarge(Connection
*, value
);
687 static void handleNETRCFile(Connection
*, value
);
688 static void handleFTPSSL(Connection
*, value
);
689 static void handlePostFieldSizeLarge(Connection
*, value
);
690 static void handleTCPNoDelay(Connection
*, value
);
691 static void handleFTPSSLAuth(Connection
*, value
);
692 static void handleIOCTLFunction(Connection
*, value
);
693 static void handleFTPAccount(Connection
*, value
);
694 static void handleCookieList(Connection
*, value
);
695 static void handleIgnoreContentLength(Connection
*, value
);
696 static void handleFTPSkipPASVIP(Connection
*, value
);
697 static void handleFTPFileMethod(Connection
*, value
);
698 static void handleLocalPort(Connection
*, value
);
699 static void handleLocalPortRange(Connection
*, value
);
700 static void handleConnectOnly(Connection
*, value
);
701 static void handleMaxSendSpeedLarge(Connection
*, value
);
702 static void handleMaxRecvSpeedLarge(Connection
*, value
);
703 static void handleFTPAlternativeToUser(Connection
*, value
);
704 static void handleSSLSessionIdCache(Connection
*, value
);
705 static void handleSSHAuthTypes(Connection
*, value
);
706 static void handleSSHPublicKeyFile(Connection
*, value
);
707 static void handleSSHPrivateKeyFile(Connection
*, value
);
708 static void handleFTPSSLCCC(Connection
*, value
);
709 static void handleTimeoutMS(Connection
*, value
);
710 static void handleConnectTimeoutMS(Connection
*, value
);
711 static void handleHTTPTransferDecoding(Connection
*, value
);
712 static void handleHTTPContentDecoding(Connection
*, value
);
713 static void handleNewFilePerms(Connection
*, value
);
714 static void handleNewDirectoryPerms(Connection
*, value
);
715 static void handlePost301(Connection
*, value
);
716 static void handleSSHHostPublicKeyMD5(Connection
*, value
);
717 static void handleCopyPostFields(Connection
*, value
);
718 static void handleProxyTransferMode(Connection
*, value
);
719 static void handleSeekFunction(Connection
*, value
);
721 CURLOptionMapping implementedOptionMap
[] =
723 {handleWriteFunction
, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION
},
724 {handleReadFunction
, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION
},
725 {handleInFileSize
, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE
},
726 {handleURL
, "CURLOPT_URL", CURLOPT_URL
},
727 {handleProxy
, "CURLOPT_PROXY", CURLOPT_PROXY
},
728 {handleProxyPort
, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT
},
729 {handleHTTPProxyTunnel
, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL
},
730 {handleVerbose
, "CURLOPT_VERBOSE", CURLOPT_VERBOSE
},
731 {handleHeader
, "CURLOPT_HEADER", CURLOPT_HEADER
},
732 {handleNoProgress
, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS
},
733 #if HAVE_DECL_CURLOPT_NOSIGNAL
734 {handleNoSignal
, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL
},
736 {handleNoSignal
, "CURLOPT_NOSIGNAL", 0},
738 {handleNoBody
, "CURLOPT_NOBODY", CURLOPT_NOBODY
},
739 {handleFailOnError
, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR
},
740 {handleUpload
, "CURLOPT_UPLOAD", CURLOPT_UPLOAD
},
741 {handlePost
, "CURLOPT_POST", CURLOPT_POST
},
742 {handleFTPListOnly
, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY
},
743 {handleFTPAppend
, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND
},
744 {handleNETRC
, "CURLOPT_NETRC", CURLOPT_NETRC
},
745 #if HAVE_DECL_CURLOPT_ENCODING
746 {handleEncoding
, "CURLOPT_ENCODING", CURLOPT_ENCODING
},
748 {handleEncoding
, "CURLOPT_ENCODING", 0},
750 {handleFollowLocation
, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION
},
751 {handleTransferText
, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT
},
752 {handlePut
, "CURLOPT_PUT", CURLOPT_PUT
},
753 {handleUserPwd
, "CURLOPT_USERPWD", CURLOPT_USERPWD
},
754 {handleProxyUserPwd
, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD
},
755 {handleRange
, "CURLOPT_RANGE", CURLOPT_RANGE
},
756 {handleErrorBuffer
, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER
},
757 {handleTimeout
, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT
},
758 {handlePostFields
, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS
},
759 {handlePostFieldSize
, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE
},
760 {handleReferer
, "CURLOPT_REFERER", CURLOPT_REFERER
},
761 {handleUserAgent
, "CURLOPT_USERAGENT", CURLOPT_USERAGENT
},
762 {handleFTPPort
, "CURLOPT_FTPPORT", CURLOPT_FTPPORT
},
763 {handleLowSpeedLimit
, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT
},
764 {handleLowSpeedTime
, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME
},
765 {handleResumeFrom
, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM
},
766 {handleCookie
, "CURLOPT_COOKIE", CURLOPT_COOKIE
},
767 {handleHTTPHeader
, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER
},
768 {handleHTTPPost
, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST
},
769 {handleSSLCert
, "CURLOPT_SSLCERT", CURLOPT_SSLCERT
},
770 {handleSSLCertType
, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE
},
771 {handleSSLCertPasswd
, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD
},
772 {handleSSLKey
, "CURLOPT_SSLKEY", CURLOPT_SSLKEY
},
773 {handleSSLKeyType
, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE
},
774 {handleSSLKeyPasswd
, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD
},
775 {handleSSLEngine
, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE
},
776 {handleSSLEngineDefault
, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT
},
777 {handleCRLF
, "CURLOPT_CRLF", CURLOPT_CRLF
},
778 {handleQuote
, "CURLOPT_QUOTE", CURLOPT_QUOTE
},
779 {handlePostQuote
, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE
},
780 {handleHeaderFunction
, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION
},
781 {handleCookieFile
, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE
},
782 {handleSSLVersion
, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION
},
783 {handleTimeCondition
, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION
},
784 {handleTimeValue
, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE
},
785 {handleCustomRequest
, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST
},
786 {handleInterface
, "CURLOPT_INTERFACE", CURLOPT_INTERFACE
},
787 {handleKRB4Level
, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL
},
788 {handleProgressFunction
, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION
},
789 {handleSSLVerifyPeer
, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER
},
790 {handleCAInfo
, "CURLOPT_CAINFO", CURLOPT_CAINFO
},
791 {handleCAPath
, "CURLOPT_CAPATH", CURLOPT_CAPATH
},
792 {handleFileTime
, "CURLOPT_FILETIME", CURLOPT_FILETIME
},
793 {handleMaxRedirs
, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS
},
794 {handleMaxConnects
, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS
},
795 {handleClosePolicy
, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY
},
796 {handleFreshConnect
, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT
},
797 {handleForbidReuse
, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE
},
798 {handleRandomFile
, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE
},
799 {handleEGDSocket
, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET
},
800 {handleConnectTimeout
, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT
},
801 {handleHTTPGet
, "CURLOPT_HTTPGET", CURLOPT_HTTPGET
},
802 {handleSSLVerifyHost
, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST
},
803 {handleCookieJar
, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR
},
804 {handleSSLCipherList
, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST
},
805 {handleHTTPVersion
, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION
},
806 {handleFTPUseEPSV
, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV
},
807 {handleDNSCacheTimeout
, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT
},
808 {handleDNSUseGlobalCache
, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE
},
809 {handleDebugFunction
, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION
},
810 #if HAVE_DECL_CURLOPT_PRIVATE
811 {handlePrivate
, "CURLOPT_PRIVATE", CURLOPT_PRIVATE
},
813 {handlePrivate
, "CURLOPT_PRIVATE", 0},
815 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
816 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES
},
818 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", 0},
820 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
821 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH
},
823 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", 0},
825 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
826 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT
},
828 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", 0},
830 #if HAVE_DECL_CURLOPT_HTTPAUTH
831 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH
},
833 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", 0},
835 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
836 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS
},
838 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
840 #if HAVE_DECL_CURLOPT_PROXYAUTH
841 {handleProxyAuth
, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH
},
843 {handleProxyAuth
, "CURLOPT_PROXYAUTH", 0},
845 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
846 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT
},
848 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
850 #if HAVE_DECL_CURLOPT_IPRESOLVE
851 {handleIPResolve
, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE
},
853 {handleIPResolve
, "CURLOPT_IPRESOLVE", 0},
855 #if HAVE_DECL_CURLOPT_MAXFILESIZE
856 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE
},
858 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", 0},
860 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
861 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE
},
863 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", 0},
865 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
866 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE
},
868 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", 0},
870 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
871 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE
},
873 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", 0},
875 #if HAVE_DECL_CURLOPT_NETRC_FILE
876 {handleNETRCFile
, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE
},
878 {handleNETRCFile
, "CURLOPT_NETRC_FILE", 0},
880 #if HAVE_DECL_CURLOPT_FTP_SSL
881 {handleFTPSSL
, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL
},
883 {handleFTPSSL
, "CURLOPT_FTP_SSL", 0},
885 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
886 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE
},
888 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
890 #if HAVE_DECL_CURLOPT_TCP_NODELAY
891 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY
},
893 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", 0},
895 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
896 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH
},
898 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", 0},
900 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
901 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION
},
903 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", 0},
905 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
906 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT
},
908 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", 0},
910 #if HAVE_DECL_CURLOPT_COOKIELIST
911 {handleCookieList
, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST
},
913 {handleCookieList
, "CURLOPT_COOKIELIST", 0},
915 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
916 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH
},
918 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
920 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
921 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP
},
923 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", 0},
925 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
926 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD
},
928 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", 0},
930 #if HAVE_DECL_CURLOPT_LOCALPORT
931 {handleLocalPort
, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT
},
933 {handleLocalPort
, "CURLOPT_LOCALPORT", 0},
935 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
936 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE
},
938 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", 0},
940 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
941 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY
},
943 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", 0},
945 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
946 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE
},
948 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
950 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
951 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE
},
953 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
955 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
956 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER
},
958 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
960 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
961 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE
},
963 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", 0},
965 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
966 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES
},
968 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", 0},
970 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
971 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE
},
973 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
975 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
976 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE
},
978 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
980 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
981 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC
},
983 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", 0},
985 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
986 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS
},
988 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", 0},
990 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
991 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS
},
993 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", 0},
995 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
996 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING
},
998 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
1000 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1001 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING
},
1003 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1005 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1006 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS
},
1008 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", 0},
1010 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1011 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS
},
1013 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1015 #if HAVE_DECL_CURLOPT_POST301
1016 {handlePost301
, "CURLOPT_POST301", CURLOPT_POST301
},
1018 {handlePost301
, "CURLOPT_POST301", 0},
1020 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1021 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
},
1023 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1025 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1026 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS
},
1028 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", 0},
1030 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1031 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE
},
1033 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1035 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1036 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION
},
1038 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", 0},
1042 static char *findOption(CURLOptionMapping optionMap
[],
1045 return optionMap
[option
].name
;
1048 static void free_curl_slist(struct curl_slist
*slist
)
1050 struct curl_slist
*item
;
1057 while (item
!= NULL
)
1064 curl_slist_free_all(slist
);
1067 static void raiseError(Connection
*conn
, CURLcode code
)
1070 CAMLlocal1(exceptionData
);
1072 char *errorString
= "Unknown Error";
1075 for (i
= 0; errorMap
[i
].name
!= NULL
; i
++)
1077 if (errorMap
[i
].error
== code
)
1079 errorString
= errorMap
[i
].name
;
1084 exceptionData
= alloc(3, 0);
1086 Field(exceptionData
, 0) = Val_int(code
);
1087 Field(exceptionData
, 1) = Val_int(code
);
1088 Field(exceptionData
, 2) = copy_string(errorString
);
1090 if (conn
!= NULL
&& conn
->errorBuffer
!= NULL
)
1092 Field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0) =
1093 copy_string(conn
->errorBuffer
);
1096 exception
= caml_named_value("CurlException");
1098 if (exception
== NULL
)
1099 failwith(errorString
);
1101 raise_with_arg(*exception
, exceptionData
);
1106 static Connection
*newConnection(void)
1108 Connection
*connection
;
1111 connection
= (Connection
*)malloc(sizeof(Connection
));
1113 enter_blocking_section();
1114 connection
->connection
= curl_easy_init();
1115 leave_blocking_section();
1117 connection
->next
= NULL
;
1118 connection
->prev
= NULL
;
1120 if (connectionList
.tail
== NULL
)
1122 connectionList
.tail
= connection
;
1123 connectionList
.head
= connection
;
1127 connection
->prev
= connectionList
.head
;
1128 connectionList
.head
->next
= connection
;
1129 connectionList
.head
= connection
;
1132 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1133 for (i
= 0; i
< OcamlValuesSize
; i
++)
1134 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1136 register_global_root(&connection
->ocamlValues
);
1138 connection
->url
= NULL
;
1139 connection
->proxy
= NULL
;
1140 connection
->userPwd
= NULL
;
1141 connection
->proxyUserPwd
= NULL
;
1142 connection
->range
= NULL
;
1143 connection
->errorBuffer
= NULL
;
1144 connection
->postFields
= NULL
;
1145 connection
->postFieldSize
= -1;
1146 connection
->referer
= NULL
;
1147 connection
->userAgent
= NULL
;
1148 connection
->ftpPort
= NULL
;
1149 connection
->cookie
= NULL
;
1150 connection
->httpHeader
= NULL
;
1151 connection
->httpPostFirst
= NULL
;
1152 connection
->httpPostLast
= NULL
;
1153 connection
->httpPostStrings
= NULL
;
1154 connection
->sslCert
= NULL
;
1155 connection
->sslCertType
= NULL
;
1156 connection
->sslCertPasswd
= NULL
;
1157 connection
->sslKey
= NULL
;
1158 connection
->sslKeyType
= NULL
;
1159 connection
->sslKeyPasswd
= NULL
;
1160 connection
->sslEngine
= NULL
;
1161 connection
->quote
= NULL
;
1162 connection
->postQuote
= NULL
;
1163 connection
->cookieFile
= NULL
;
1164 connection
->customRequest
= NULL
;
1165 connection
->interface
= NULL
;
1166 connection
->caInfo
= NULL
;
1167 connection
->caPath
= NULL
;
1168 connection
->randomFile
= NULL
;
1169 connection
->egdSocket
= NULL
;
1170 connection
->cookieJar
= NULL
;
1171 connection
->sslCipherList
= NULL
;
1172 connection
->private = NULL
;
1173 connection
->http200Aliases
= NULL
;
1174 connection
->netrcFile
= NULL
;
1175 connection
->ftpaccount
= NULL
;
1176 connection
->cookielist
= NULL
;
1177 connection
->ftpAlternativeToUser
= NULL
;
1178 connection
->sshPublicKeyFile
= NULL
;
1179 connection
->sshPrivateKeyFile
= NULL
;
1180 connection
->copyPostFields
= NULL
;
1185 static Connection
*duplicateConnection(Connection
*original
)
1187 Connection
*connection
;
1190 connection
= (Connection
*)malloc(sizeof(Connection
));
1192 enter_blocking_section();
1193 connection
->connection
= curl_easy_duphandle(original
->connection
);
1194 leave_blocking_section();
1196 connection
->next
= NULL
;
1197 connection
->prev
= NULL
;
1199 if (connectionList
.tail
== NULL
)
1201 connectionList
.tail
= connection
;
1202 connectionList
.head
= connection
;
1206 connection
->prev
= connectionList
.head
;
1207 connectionList
.head
->next
= connection
;
1208 connectionList
.head
= connection
;
1211 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1212 for (i
= 0; i
< OcamlValuesSize
; i
++)
1213 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1215 register_global_root(&connection
->ocamlValues
);
1217 Store_field(connection
->ocamlValues
, OcamlWriteCallback
,
1218 Field(original
->ocamlValues
, OcamlWriteCallback
));
1219 Store_field(connection
->ocamlValues
, OcamlReadCallback
,
1220 Field(original
->ocamlValues
, OcamlReadCallback
));
1221 Store_field(connection
->ocamlValues
, OcamlErrorBuffer
,
1222 Field(original
->ocamlValues
, OcamlErrorBuffer
));
1223 Store_field(connection
->ocamlValues
, OcamlPostFields
,
1224 Field(original
->ocamlValues
, OcamlPostFields
));
1225 Store_field(connection
->ocamlValues
, OcamlHTTPHeader
,
1226 Field(original
->ocamlValues
, OcamlHTTPHeader
));
1227 Store_field(connection
->ocamlValues
, OcamlQuote
,
1228 Field(original
->ocamlValues
, OcamlQuote
));
1229 Store_field(connection
->ocamlValues
, OcamlPostQuote
,
1230 Field(original
->ocamlValues
, OcamlPostQuote
));
1231 Store_field(connection
->ocamlValues
, OcamlHeaderCallback
,
1232 Field(original
->ocamlValues
, OcamlHeaderCallback
));
1233 Store_field(connection
->ocamlValues
, OcamlProgressCallback
,
1234 Field(original
->ocamlValues
, OcamlProgressCallback
));
1235 Store_field(connection
->ocamlValues
, OcamlPasswdCallback
,
1236 Field(original
->ocamlValues
, OcamlPasswdCallback
));
1237 Store_field(connection
->ocamlValues
, OcamlDebugCallback
,
1238 Field(original
->ocamlValues
, OcamlDebugCallback
));
1239 Store_field(connection
->ocamlValues
, OcamlHTTP200Aliases
,
1240 Field(original
->ocamlValues
, OcamlHTTP200Aliases
));
1241 Store_field(connection
->ocamlValues
, OcamlIOCTLCallback
,
1242 Field(original
->ocamlValues
, OcamlIOCTLCallback
));
1243 Store_field(connection
->ocamlValues
, OcamlSeekFunctionCallback
,
1244 Field(original
->ocamlValues
, OcamlSeekFunctionCallback
));
1246 connection
->url
= NULL
;
1247 connection
->proxy
= NULL
;
1248 connection
->userPwd
= NULL
;
1249 connection
->proxyUserPwd
= NULL
;
1250 connection
->range
= NULL
;
1251 connection
->errorBuffer
= NULL
;
1252 connection
->postFields
= NULL
;
1253 connection
->postFieldSize
= -1;
1254 connection
->referer
= NULL
;
1255 connection
->userAgent
= NULL
;
1256 connection
->ftpPort
= NULL
;
1257 connection
->cookie
= NULL
;
1258 connection
->httpHeader
= NULL
;
1259 connection
->httpPostFirst
= NULL
;
1260 connection
->httpPostLast
= NULL
;
1261 connection
->httpPostStrings
= NULL
;
1262 connection
->sslCert
= NULL
;
1263 connection
->sslCertType
= NULL
;
1264 connection
->sslCertPasswd
= NULL
;
1265 connection
->sslKey
= NULL
;
1266 connection
->sslKeyType
= NULL
;
1267 connection
->sslKeyPasswd
= NULL
;
1268 connection
->sslEngine
= NULL
;
1269 connection
->quote
= NULL
;
1270 connection
->postQuote
= NULL
;
1271 connection
->cookieFile
= NULL
;
1272 connection
->customRequest
= NULL
;
1273 connection
->interface
= NULL
;
1274 connection
->caInfo
= NULL
;
1275 connection
->caPath
= NULL
;
1276 connection
->randomFile
= NULL
;
1277 connection
->egdSocket
= NULL
;
1278 connection
->cookieJar
= NULL
;
1279 connection
->sslCipherList
= NULL
;
1280 connection
->private = NULL
;
1281 connection
->http200Aliases
= NULL
;
1282 connection
->netrcFile
= NULL
;
1283 connection
->ftpaccount
= NULL
;
1284 connection
->cookielist
= NULL
;
1285 connection
->sshPublicKeyFile
= NULL
;
1286 connection
->sshPrivateKeyFile
= NULL
;
1287 connection
->copyPostFields
= NULL
;
1289 if (Field(original
->ocamlValues
, OcamlURL
) != Val_unit
)
1290 handleURL(connection
, Field(original
->ocamlValues
,
1292 if (Field(original
->ocamlValues
, OcamlProxy
) != Val_unit
)
1293 handleProxy(connection
, Field(original
->ocamlValues
,
1295 if (Field(original
->ocamlValues
, OcamlUserPWD
) != Val_unit
)
1296 handleUserPwd(connection
, Field(original
->ocamlValues
,
1298 if (Field(original
->ocamlValues
, OcamlProxyUserPWD
) != Val_unit
)
1299 handleProxyUserPwd(connection
, Field(original
->ocamlValues
,
1300 OcamlProxyUserPWD
));
1301 if (Field(original
->ocamlValues
, OcamlRange
) != Val_unit
)
1302 handleRange(connection
, Field(original
->ocamlValues
,
1304 if (Field(original
->ocamlValues
, OcamlErrorBuffer
) != Val_unit
)
1305 handleErrorBuffer(connection
, Field(original
->ocamlValues
,
1307 if (Field(original
->ocamlValues
, OcamlPostFields
) != Val_unit
)
1308 handlePostFields(connection
, Field(original
->ocamlValues
,
1310 if (Field(original
->ocamlValues
, OcamlReferer
) != Val_unit
)
1311 handleReferer(connection
, Field(original
->ocamlValues
,
1313 if (Field(original
->ocamlValues
, OcamlUserAgent
) != Val_unit
)
1314 handleUserAgent(connection
, Field(original
->ocamlValues
,
1316 if (Field(original
->ocamlValues
, OcamlFTPPort
) != Val_unit
)
1317 handleFTPPort(connection
, Field(original
->ocamlValues
,
1319 if (Field(original
->ocamlValues
, OcamlCookie
) != Val_unit
)
1320 handleCookie(connection
, Field(original
->ocamlValues
,
1322 if (Field(original
->ocamlValues
, OcamlHTTPHeader
) != Val_unit
)
1323 handleHTTPHeader(connection
, Field(original
->ocamlValues
,
1325 if (Field(original
->ocamlValues
, OcamlHTTPPost
) != Val_unit
)
1326 handleHTTPPost(connection
, Field(original
->ocamlValues
,
1328 if (Field(original
->ocamlValues
, OcamlSSLCert
) != Val_unit
)
1329 handleSSLCert(connection
, Field(original
->ocamlValues
,
1331 if (Field(original
->ocamlValues
, OcamlSSLCertType
) != Val_unit
)
1332 handleSSLCertType(connection
, Field(original
->ocamlValues
,
1334 if (Field(original
->ocamlValues
, OcamlSSLCertPasswd
) != Val_unit
)
1335 handleSSLCertPasswd(connection
, Field(original
->ocamlValues
,
1336 OcamlSSLCertPasswd
));
1337 if (Field(original
->ocamlValues
, OcamlSSLKey
) != Val_unit
)
1338 handleSSLKey(connection
, Field(original
->ocamlValues
,
1340 if (Field(original
->ocamlValues
, OcamlSSLKeyType
) != Val_unit
)
1341 handleSSLKeyType(connection
, Field(original
->ocamlValues
,
1343 if (Field(original
->ocamlValues
, OcamlSSLKeyPasswd
) != Val_unit
)
1344 handleSSLKeyPasswd(connection
, Field(original
->ocamlValues
,
1345 OcamlSSLKeyPasswd
));
1346 if (Field(original
->ocamlValues
, OcamlSSLEngine
) != Val_unit
)
1347 handleSSLEngine(connection
, Field(original
->ocamlValues
,
1349 if (Field(original
->ocamlValues
, OcamlQuote
) != Val_unit
)
1350 handleQuote(connection
, Field(original
->ocamlValues
,
1352 if (Field(original
->ocamlValues
, OcamlPostQuote
) != Val_unit
)
1353 handlePostQuote(connection
, Field(original
->ocamlValues
,
1355 if (Field(original
->ocamlValues
, OcamlCookieFile
) != Val_unit
)
1356 handleCookieFile(connection
, Field(original
->ocamlValues
,
1358 if (Field(original
->ocamlValues
, OcamlCustomRequest
) != Val_unit
)
1359 handleCustomRequest(connection
, Field(original
->ocamlValues
,
1360 OcamlCustomRequest
));
1361 if (Field(original
->ocamlValues
, OcamlInterface
) != Val_unit
)
1362 handleInterface(connection
, Field(original
->ocamlValues
,
1364 if (Field(original
->ocamlValues
, OcamlCAInfo
) != Val_unit
)
1365 handleCAInfo(connection
, Field(original
->ocamlValues
,
1367 if (Field(original
->ocamlValues
, OcamlCAPath
) != Val_unit
)
1368 handleCAPath(connection
, Field(original
->ocamlValues
,
1370 if (Field(original
->ocamlValues
, OcamlRandomFile
) != Val_unit
)
1371 handleRandomFile(connection
, Field(original
->ocamlValues
,
1373 if (Field(original
->ocamlValues
, OcamlEGDSocket
) != Val_unit
)
1374 handleEGDSocket(connection
, Field(original
->ocamlValues
,
1376 if (Field(original
->ocamlValues
, OcamlCookieJar
) != Val_unit
)
1377 handleCookieJar(connection
, Field(original
->ocamlValues
,
1379 if (Field(original
->ocamlValues
, OcamlSSLCipherList
) != Val_unit
)
1380 handleSSLCipherList(connection
, Field(original
->ocamlValues
,
1381 OcamlSSLCipherList
));
1382 if (Field(original
->ocamlValues
, OcamlPrivate
) != Val_unit
)
1383 handlePrivate(connection
, Field(original
->ocamlValues
,
1385 if (Field(original
->ocamlValues
, OcamlHTTP200Aliases
) != Val_unit
)
1386 handleHTTP200Aliases(connection
, Field(original
->ocamlValues
,
1387 OcamlHTTP200Aliases
));
1388 if (Field(original
->ocamlValues
, OcamlNETRCFile
) != Val_unit
)
1389 handleNETRCFile(connection
, Field(original
->ocamlValues
,
1391 if (Field(original
->ocamlValues
, OcamlFTPAccount
) != Val_unit
)
1392 handleFTPAccount(connection
, Field(original
->ocamlValues
,
1394 if (Field(original
->ocamlValues
, OcamlCookieList
) != Val_unit
)
1395 handleCookieList(connection
, Field(original
->ocamlValues
,
1397 if (Field(original
->ocamlValues
, OcamlFTPAlternativeToUser
) != Val_unit
)
1398 handleFTPAlternativeToUser(connection
,
1399 Field(original
->ocamlValues
,
1400 OcamlFTPAlternativeToUser
));
1401 if (Field(original
->ocamlValues
, OcamlSSHPublicKeyFile
) != Val_unit
)
1402 handleSSHPublicKeyFile(connection
,
1403 Field(original
->ocamlValues
,
1404 OcamlSSHPublicKeyFile
));
1405 if (Field(original
->ocamlValues
, OcamlSSHPrivateKeyFile
) != Val_unit
)
1406 handleSSHPrivateKeyFile(connection
,
1407 Field(original
->ocamlValues
,
1408 OcamlSSHPrivateKeyFile
));
1409 if (Field(original
->ocamlValues
, OcamlCopyPostFields
) != Val_unit
)
1410 handleCopyPostFields(connection
,
1411 Field(original
->ocamlValues
,
1412 OcamlCopyPostFields
));
1417 static void removeConnection(Connection
*connection
)
1419 enter_blocking_section();
1420 curl_easy_cleanup(connection
->connection
);
1421 leave_blocking_section();
1423 if (connectionList
.tail
== connection
)
1424 connectionList
.tail
= connectionList
.tail
->next
;
1425 if (connectionList
.head
== connection
)
1426 connectionList
.head
= connectionList
.head
->prev
;
1428 if (connection
->next
!= NULL
)
1429 connection
->next
->prev
= connection
->prev
;
1430 if (connection
->prev
!= NULL
)
1431 connection
->prev
->next
= connection
->next
;
1433 remove_global_root(&connection
->ocamlValues
);
1435 if (connection
->url
!= NULL
)
1436 free(connection
->url
);
1437 if (connection
->proxy
!= NULL
)
1438 free(connection
->proxy
);
1439 if (connection
->userPwd
!= NULL
)
1440 free(connection
->userPwd
);
1441 if (connection
->proxyUserPwd
!= NULL
)
1442 free(connection
->proxyUserPwd
);
1443 if (connection
->range
!= NULL
)
1444 free(connection
->range
);
1445 if (connection
->errorBuffer
!= NULL
)
1446 free(connection
->range
);
1447 if (connection
->postFields
!= NULL
)
1448 free(connection
->postFields
);
1449 if (connection
->referer
!= NULL
)
1450 free(connection
->referer
);
1451 if (connection
->userAgent
!= NULL
)
1452 free(connection
->userAgent
);
1453 if (connection
->ftpPort
!= NULL
)
1454 free(connection
->ftpPort
);
1455 if (connection
->cookie
!= NULL
)
1456 free(connection
->cookie
);
1457 if (connection
->httpHeader
!= NULL
)
1458 free_curl_slist(connection
->httpHeader
);
1459 if (connection
->httpPostFirst
!= NULL
)
1460 curl_formfree(connection
->httpPostFirst
);
1461 if (connection
->httpPostStrings
!= NULL
)
1462 free_curl_slist(connection
->httpPostStrings
);
1463 if (connection
->sslCert
!= NULL
)
1464 free(connection
->sslCert
);
1465 if (connection
->sslCertType
!= NULL
)
1466 free(connection
->sslCertType
);
1467 if (connection
->sslCertPasswd
!= NULL
)
1468 free(connection
->sslCertPasswd
);
1469 if (connection
->sslKey
!= NULL
)
1470 free(connection
->sslKey
);
1471 if (connection
->sslKeyType
!= NULL
)
1472 free(connection
->sslKeyType
);
1473 if (connection
->sslKeyPasswd
!= NULL
)
1474 free(connection
->sslKeyPasswd
);
1475 if (connection
->sslEngine
!= NULL
)
1476 free(connection
->sslEngine
);
1477 if (connection
->quote
!= NULL
)
1478 free_curl_slist(connection
->quote
);
1479 if (connection
->postQuote
!= NULL
)
1480 free_curl_slist(connection
->postQuote
);
1481 if (connection
->cookieFile
!= NULL
)
1482 free(connection
->cookieFile
);
1483 if (connection
->customRequest
!= NULL
)
1484 free(connection
->customRequest
);
1485 if (connection
->interface
!= NULL
)
1486 free(connection
->interface
);
1487 if (connection
->caInfo
!= NULL
)
1488 free(connection
->caInfo
);
1489 if (connection
->caPath
!= NULL
)
1490 free(connection
->caPath
);
1491 if (connection
->randomFile
!= NULL
)
1492 free(connection
->randomFile
);
1493 if (connection
->egdSocket
!= NULL
)
1494 free(connection
->egdSocket
);
1495 if (connection
->cookieJar
!= NULL
)
1496 free(connection
->cookieJar
);
1497 if (connection
->sslCipherList
!= NULL
)
1498 free(connection
->sslCipherList
);
1499 if (connection
->private != NULL
)
1500 free(connection
->private);
1501 if (connection
->http200Aliases
!= NULL
)
1502 free_curl_slist(connection
->http200Aliases
);
1503 if (connection
->netrcFile
!= NULL
)
1504 free(connection
->netrcFile
);
1505 if (connection
->ftpaccount
!= NULL
)
1506 free(connection
->ftpaccount
);
1507 if (connection
->cookielist
!= NULL
)
1508 free(connection
->cookielist
);
1509 if (connection
->ftpAlternativeToUser
!= NULL
)
1510 free(connection
->ftpAlternativeToUser
);
1511 if (connection
->sshPublicKeyFile
!= NULL
)
1512 free(connection
->sshPublicKeyFile
);
1513 if (connection
->sshPrivateKeyFile
!= NULL
)
1514 free(connection
->sshPrivateKeyFile
);
1515 if (connection
->copyPostFields
!= NULL
)
1516 free(connection
->copyPostFields
);
1521 static void checkConnection(Connection
*connection
)
1523 Connection
*listIter
;
1525 listIter
= connectionList
.tail
;
1527 while (listIter
!= NULL
)
1529 if (listIter
== connection
)
1532 listIter
= listIter
->next
;
1535 failwith("Invalid Connection");
1538 static Connection
* findConnection(CURL
* h
)
1540 Connection
*listIter
;
1542 listIter
= connectionList
.tail
;
1544 while (listIter
!= NULL
)
1546 if (listIter
->connection
== h
)
1549 listIter
= listIter
->next
;
1552 failwith("Unknown handle");
1555 #define WRAP_DATA_CALLBACK(f) \
1556 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1559 leave_blocking_section();\
1560 result = f##_nolock(ptr,size,nmemb,data);\
1561 enter_blocking_section();\
1565 static size_t writeFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1568 CAMLlocal2(result
, str
);
1569 Connection
*conn
= (Connection
*)data
;
1572 checkConnection(conn
);
1574 str
= alloc_string(size
*nmemb
);
1576 for (i
= 0; i
< size
*nmemb
; i
++)
1577 Byte(str
, i
) = ptr
[i
];
1579 result
= callback(Field(conn
->ocamlValues
, OcamlWriteCallback
), str
);
1581 CAMLreturnT(size_t, Int_val(result
));
1584 WRAP_DATA_CALLBACK(writeFunction
)
1586 static size_t readFunction_nolock(void *ptr
, size_t size
, size_t nmemb
, void *data
)
1590 Connection
*conn
= (Connection
*)data
;
1593 checkConnection(conn
);
1595 result
= callback(Field(conn
->ocamlValues
, OcamlReadCallback
),
1596 Val_int(size
*nmemb
));
1598 length
= string_length(result
);
1600 if (length
>= size
*nmemb
)
1601 length
= size
*nmemb
;
1603 memcpy(ptr
, String_val(result
), length
);
1605 CAMLreturnT(size_t,length
);
1608 WRAP_DATA_CALLBACK(readFunction
)
1610 static size_t headerFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1613 CAMLlocal2(result
,str
);
1614 Connection
*conn
= (Connection
*)data
;
1617 checkConnection(conn
);
1619 str
= alloc_string(size
*nmemb
);
1621 for (i
= 0; i
< size
*nmemb
; i
++)
1622 Byte(str
, i
) = ptr
[i
];
1624 result
= callback(Field(conn
->ocamlValues
, OcamlHeaderCallback
), str
);
1626 CAMLreturnT(size_t, Int_val(result
));
1629 WRAP_DATA_CALLBACK(headerFunction
)
1631 static int progressFunction_nolock(void *data
,
1639 CAMLlocalN(callbackData
, 4);
1640 Connection
*conn
= (Connection
*)data
;
1642 checkConnection(conn
);
1644 callbackData
[0] = copy_double(dlTotal
);
1645 callbackData
[1] = copy_double(dlNow
);
1646 callbackData
[2] = copy_double(ulTotal
);
1647 callbackData
[3] = copy_double(ulNow
);
1649 result
= callbackN(Field(conn
->ocamlValues
, OcamlProgressCallback
),
1652 CAMLreturnT(int, Bool_val(result
));
1655 static int progressFunction(void *data
,
1662 leave_blocking_section();
1663 r
= progressFunction_nolock(data
,dlTotal
,dlNow
,ulTotal
,ulNow
);
1664 enter_blocking_section();
1668 static int passwdFunction_nolock(void *data
,
1674 CAMLlocal2(ocamlPasswd
, ocamlPrompt
);
1676 Connection
*conn
= (Connection
*)data
;
1678 checkConnection(conn
);
1680 ocamlPrompt
= copy_string(prompt
);
1682 ocamlPasswd
= callback2(Field(conn
->ocamlValues
, OcamlPasswdCallback
),
1684 Val_long(bufferLength
));
1686 if (Wosize_val(ocamlPasswd
) != 2)
1691 length
= string_length(Field(ocamlPasswd
, 1));
1692 if (length
> bufferLength
- 1)
1693 length
= bufferLength
- 1;
1695 memcpy(buffer
, String_val(Field(ocamlPasswd
, 0)), length
);
1699 CAMLreturnT(int, !(Bool_val(Field(ocamlPasswd
, 0))));
1702 static int passwdFunction(void *data
,
1708 leave_blocking_section();
1709 r
= passwdFunction_nolock(data
,prompt
,buffer
,bufferLength
);
1710 enter_blocking_section();
1714 static int debugFunction_nolock(CURL
*debugConnection
,
1715 curl_infotype infoType
,
1717 size_t bufferLength
,
1721 CAMLlocal3(camlDebugConnection
, camlInfoType
, camlMessage
);
1723 Connection
*conn
= (Connection
*)data
;
1725 checkConnection(conn
);
1727 camlDebugConnection
= (value
)conn
;
1728 camlInfoType
= Val_long(infoType
);
1729 camlMessage
= alloc_string(bufferLength
);
1731 for (i
= 0; i
< bufferLength
; i
++)
1732 Byte(camlMessage
, i
) = buffer
[i
];
1734 callback3(Field(conn
->ocamlValues
, OcamlDebugCallback
),
1735 camlDebugConnection
,
1739 CAMLreturnT(int, 0);
1742 static int debugFunction(CURL
*debugConnection
,
1743 curl_infotype infoType
,
1745 size_t bufferLength
,
1749 leave_blocking_section();
1750 r
= debugFunction_nolock(debugConnection
, infoType
, buffer
, bufferLength
, data
);
1751 enter_blocking_section();
1755 static curlioerr
ioctlFunction_nolock(CURL
*ioctl
,
1760 CAMLlocal3(camlResult
, camlConnection
, camlCmd
);
1761 Connection
*conn
= (Connection
*)data
;
1762 curlioerr result
= CURLIOE_OK
;
1764 checkConnection(conn
);
1766 if (cmd
== CURLIOCMD_NOP
)
1767 camlCmd
= Val_long(0);
1768 else if (cmd
== CURLIOCMD_RESTARTREAD
)
1769 camlCmd
= Val_long(1);
1771 failwith("Invalid IOCTL Cmd!");
1773 camlConnection
= alloc(1, Abstract_tag
);
1774 Store_field(camlConnection
, 0, (value
)conn
);
1776 camlResult
= callback2(Field(conn
->ocamlValues
, OcamlIOCTLCallback
),
1780 switch (Long_val(camlResult
))
1782 case 0: /* CURLIOE_OK */
1783 result
= CURLIOE_OK
;
1786 case 1: /* CURLIOE_UNKNOWNCMD */
1787 result
= CURLIOE_UNKNOWNCMD
;
1790 case 2: /* CURLIOE_FAILRESTART */
1791 result
= CURLIOE_FAILRESTART
;
1794 default: /* Incorrect return value, but let's handle it */
1795 result
= CURLIOE_FAILRESTART
;
1799 CAMLreturnT(curlioerr
, result
);
1802 static curlioerr
ioctlFunction(CURL
*ioctl
,
1807 leave_blocking_section();
1808 r
= ioctlFunction_nolock(ioctl
, cmd
, data
);
1809 enter_blocking_section();
1813 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1814 static int seekFunction_nolock(void *data
,
1819 CAMLlocal3(camlResult
, camlOffset
, camlOrigin
);
1820 Connection
*conn
= (Connection
*)data
;
1823 camlOffset
= copy_int64(offset
);
1825 if (SEEK_SET
== origin
)
1826 camlOrigin
= Val_long(0);
1827 else if (SEEK_CUR
== origin
)
1828 camlOrigin
= Val_long(1);
1829 else if (SEEK_END
== origin
)
1830 camlOrigin
= Val_long(2);
1832 camlOrigin
= Val_long(0);
1834 camlResult
= callback2(Field(conn
->ocamlValues
,
1835 OcamlSeekFunctionCallback
),
1839 result
= Int_val(camlResult
);
1841 CAMLreturnT(int, result
);
1844 static int seekFunction(void *data
,
1849 leave_blocking_section();
1850 r
= seekFunction_nolock(data
,offset
,origin
);
1851 enter_blocking_section();
1858 ** curl_global_init helper function
1861 CAMLprim value
helper_curl_global_init(value initOption
)
1863 CAMLparam1(initOption
);
1865 switch (Long_val(initOption
))
1867 case 0: /* CURLINIT_GLOBALALL */
1868 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL
)));
1871 case 1: /* CURLINIT_GLOBALSSL */
1872 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL
)));
1875 case 2: /* CURLINIT_GLOBALWIN32 */
1876 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32
)));
1879 case 3: /* CURLINIT_GLOBALNOTHING */
1880 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING
)));
1884 failwith("Invalid Initialization Option");
1888 CAMLreturn(Val_unit
);
1892 ** curl_global_cleanup helper function
1895 CAMLprim
void helper_curl_global_cleanup(void)
1899 curl_global_cleanup();
1905 ** curl_easy_init helper function
1908 CAMLprim value
helper_curl_easy_init(void)
1913 Connection
*conn
= newConnection();
1915 result
= alloc(1, Abstract_tag
);
1916 Store_field(result
, 0, (value
)conn
);
1922 ** curl_easy_setopt helper utility functions
1925 static void handleWriteFunction(Connection
*conn
, value option
)
1928 CURLcode result
= CURLE_OK
;
1930 if (Tag_val(option
) == Closure_tag
)
1931 Store_field(conn
->ocamlValues
, OcamlWriteCallback
, option
);
1933 failwith("Not a proper closure");
1935 result
= curl_easy_setopt(conn
->connection
,
1936 CURLOPT_WRITEFUNCTION
,
1939 if (result
!= CURLE_OK
)
1940 raiseError(conn
, result
);
1942 result
= curl_easy_setopt(conn
->connection
,
1946 if (result
!= CURLE_OK
)
1947 raiseError(conn
, result
);
1952 static void handleReadFunction(Connection
*conn
, value option
)
1955 CURLcode result
= CURLE_OK
;
1957 if (Tag_val(option
) == Closure_tag
)
1958 Store_field(conn
->ocamlValues
, OcamlReadCallback
, option
);
1960 failwith("Not a proper closure");
1962 result
= curl_easy_setopt(conn
->connection
,
1963 CURLOPT_READFUNCTION
,
1966 if (result
!= CURLE_OK
)
1967 raiseError(conn
, result
);
1969 result
= curl_easy_setopt(conn
->connection
,
1973 if (result
!= CURLE_OK
)
1974 raiseError(conn
, result
);
1979 static void handleURL(Connection
*conn
, value option
)
1982 CURLcode result
= CURLE_OK
;
1984 Store_field(conn
->ocamlValues
, OcamlURL
, option
);
1986 if (conn
->url
!= NULL
)
1989 conn
->url
= strdup(String_val(option
));
1991 result
= curl_easy_setopt(conn
->connection
,
1995 if (result
!= CURLE_OK
)
1996 raiseError(conn
, result
);
2001 static void handleInFileSize(Connection
*conn
, value option
)
2004 CURLcode result
= CURLE_OK
;
2006 result
= curl_easy_setopt(conn
->connection
,
2010 if (result
!= CURLE_OK
)
2011 raiseError(conn
, result
);
2016 static void handleProxy(Connection
*conn
, value option
)
2019 CURLcode result
= CURLE_OK
;
2021 Store_field(conn
->ocamlValues
, OcamlProxy
, option
);
2023 if (conn
->proxy
!= NULL
)
2026 conn
->proxy
= strdup(String_val(option
));
2028 result
= curl_easy_setopt(conn
->connection
,
2032 if (result
!= CURLE_OK
)
2033 raiseError(conn
, result
);
2038 static void handleProxyPort(Connection
*conn
, value option
)
2041 CURLcode result
= CURLE_OK
;
2043 result
= curl_easy_setopt(conn
->connection
,
2047 if (result
!= CURLE_OK
)
2048 raiseError(conn
, result
);
2053 static void handleHTTPProxyTunnel(Connection
*conn
, value option
)
2056 CURLcode result
= CURLE_OK
;
2058 result
= curl_easy_setopt(conn
->connection
,
2059 CURLOPT_HTTPPROXYTUNNEL
,
2062 if (result
!= CURLE_OK
)
2063 raiseError(conn
, result
);
2068 static void handleVerbose(Connection
*conn
, value option
)
2071 CURLcode result
= CURLE_OK
;
2073 result
= curl_easy_setopt(conn
->connection
,
2077 if (result
!= CURLE_OK
)
2078 raiseError(conn
, result
);
2083 static void handleHeader(Connection
*conn
, value option
)
2086 CURLcode result
= CURLE_OK
;
2088 result
= curl_easy_setopt(conn
->connection
,
2092 if (result
!= CURLE_OK
)
2093 raiseError(conn
, result
);
2098 static void handleNoProgress(Connection
*conn
, value option
)
2101 CURLcode result
= CURLE_OK
;
2103 result
= curl_easy_setopt(conn
->connection
,
2107 if (result
!= CURLE_OK
)
2108 raiseError(conn
, result
);
2113 static void handleNoSignal(Connection
*conn
, value option
)
2115 #if HAVE_DECL_CURLOPT_NOSIGNAL
2117 CURLcode result
= CURLE_OK
;
2119 result
= curl_easy_setopt(conn
->connection
,
2123 if (result
!= CURLE_OK
)
2124 raiseError(conn
, result
);
2128 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2129 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2133 static void handleNoBody(Connection
*conn
, value option
)
2136 CURLcode result
= CURLE_OK
;
2138 result
= curl_easy_setopt(conn
->connection
,
2142 if (result
!= CURLE_OK
)
2143 raiseError(conn
, result
);
2148 static void handleFailOnError(Connection
*conn
, value option
)
2151 CURLcode result
= CURLE_OK
;
2153 result
= curl_easy_setopt(conn
->connection
,
2154 CURLOPT_FAILONERROR
,
2157 if (result
!= CURLE_OK
)
2158 raiseError(conn
, result
);
2163 static void handleUpload(Connection
*conn
, value option
)
2166 CURLcode result
= CURLE_OK
;
2168 result
= curl_easy_setopt(conn
->connection
,
2172 if (result
!= CURLE_OK
)
2173 raiseError(conn
, result
);
2178 static void handlePost(Connection
*conn
, value option
)
2181 CURLcode result
= CURLE_OK
;
2183 result
= curl_easy_setopt(conn
->connection
,
2187 if (result
!= CURLE_OK
)
2188 raiseError(conn
, result
);
2193 static void handleFTPListOnly(Connection
*conn
, value option
)
2196 CURLcode result
= CURLE_OK
;
2198 result
= curl_easy_setopt(conn
->connection
,
2199 CURLOPT_FTPLISTONLY
,
2202 if (result
!= CURLE_OK
)
2203 raiseError(conn
, result
);
2208 static void handleFTPAppend(Connection
*conn
, value option
)
2211 CURLcode result
= CURLE_OK
;
2213 result
= curl_easy_setopt(conn
->connection
,
2217 if (result
!= CURLE_OK
)
2218 raiseError(conn
, result
);
2223 static void handleNETRC(Connection
*conn
, value option
)
2226 CURLcode result
= CURLE_OK
;
2229 switch (Long_val(option
))
2231 case 0: /* CURL_NETRC_OPTIONAL */
2232 netrc
= CURL_NETRC_OPTIONAL
;
2235 case 1:/* CURL_NETRC_IGNORED */
2236 netrc
= CURL_NETRC_IGNORED
;
2239 case 2: /* CURL_NETRC_REQUIRED */
2240 netrc
= CURL_NETRC_REQUIRED
;
2244 failwith("Invalid NETRC Option");
2248 result
= curl_easy_setopt(conn
->connection
,
2252 if (result
!= CURLE_OK
)
2253 raiseError(conn
, result
);
2258 static void handleEncoding(Connection
*conn
, value option
)
2260 #if HAVE_DECL_CURLOPT_ENCODING
2262 CURLcode result
= CURLE_OK
;
2264 switch (Long_val(option
))
2266 case 0: /* CURL_ENCODING_NONE */
2267 result
= curl_easy_setopt(conn
->connection
,
2272 case 1: /* CURL_ENCODING_DEFLATE */
2273 result
= curl_easy_setopt(conn
->connection
,
2279 failwith("Invalid Encoding Option");
2283 if (result
!= CURLE_OK
)
2284 raiseError(conn
, result
);
2288 #warning "libcurl does not implement CURLOPT_ENCODING"
2289 failwith("libcurl does not implement CURLOPT_ENCODING");
2293 static void handleFollowLocation(Connection
*conn
, value option
)
2296 CURLcode result
= CURLE_OK
;
2298 result
= curl_easy_setopt(conn
->connection
,
2299 CURLOPT_FOLLOWLOCATION
,
2302 if (result
!= CURLE_OK
)
2303 raiseError(conn
, result
);
2308 static void handleTransferText(Connection
*conn
, value option
)
2311 CURLcode result
= CURLE_OK
;
2313 result
= curl_easy_setopt(conn
->connection
,
2314 CURLOPT_TRANSFERTEXT
,
2317 if (result
!= CURLE_OK
)
2318 raiseError(conn
, result
);
2323 static void handlePut(Connection
*conn
, value option
)
2326 CURLcode result
= CURLE_OK
;
2328 result
= curl_easy_setopt(conn
->connection
,
2332 if (result
!= CURLE_OK
)
2333 raiseError(conn
, result
);
2338 static void handleUserPwd(Connection
*conn
, value option
)
2341 CURLcode result
= CURLE_OK
;
2343 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2345 if (conn
->userPwd
!= NULL
)
2346 free(conn
->userPwd
);
2348 conn
->userPwd
= strdup(String_val(option
));
2350 result
= curl_easy_setopt(conn
->connection
,
2354 if (result
!= CURLE_OK
)
2355 raiseError(conn
, result
);
2360 static void handleProxyUserPwd(Connection
*conn
, value option
)
2363 CURLcode result
= CURLE_OK
;
2365 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2367 if (conn
->proxyUserPwd
!= NULL
)
2368 free(conn
->proxyUserPwd
);
2370 conn
->proxyUserPwd
= strdup(String_val(option
));
2372 result
= curl_easy_setopt(conn
->connection
,
2373 CURLOPT_PROXYUSERPWD
,
2374 conn
->proxyUserPwd
);
2376 if (result
!= CURLE_OK
)
2377 raiseError(conn
, result
);
2382 static void handleRange(Connection
*conn
, value option
)
2385 CURLcode result
= CURLE_OK
;
2387 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2389 if (conn
->range
!= NULL
)
2392 conn
->range
= strdup(String_val(option
));
2394 result
= curl_easy_setopt(conn
->connection
,
2398 if (result
!= CURLE_OK
)
2399 raiseError(conn
, result
);
2404 static void handleErrorBuffer(Connection
*conn
, value option
)
2407 CURLcode result
= CURLE_OK
;
2409 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2411 if (conn
->errorBuffer
!= NULL
)
2412 free(conn
->errorBuffer
);
2414 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2416 result
= curl_easy_setopt(conn
->connection
,
2417 CURLOPT_ERRORBUFFER
,
2420 if (result
!= CURLE_OK
)
2421 raiseError(conn
, result
);
2426 static void handleTimeout(Connection
*conn
, value option
)
2429 CURLcode result
= CURLE_OK
;
2431 result
= curl_easy_setopt(conn
->connection
,
2435 if (result
!= CURLE_OK
)
2436 raiseError(conn
, result
);
2441 static void handlePostFields(Connection
*conn
, value option
)
2444 CURLcode result
= CURLE_OK
;
2446 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2448 if (conn
->postFields
!= NULL
)
2449 free(conn
->postFields
);
2451 conn
->postFields
= malloc(string_length(option
)+1);
2452 memcpy(conn
->postFields
, String_val(option
), string_length(option
));
2454 result
= curl_easy_setopt(conn
->connection
,
2458 if (result
!= CURLE_OK
)
2459 raiseError(conn
, result
);
2464 static void handlePostFieldSize(Connection
*conn
, value option
)
2467 CURLcode result
= CURLE_OK
;
2469 result
= curl_easy_setopt(conn
->connection
,
2470 CURLOPT_POSTFIELDSIZE
,
2473 if (result
!= CURLE_OK
)
2474 raiseError(conn
, result
);
2479 static void handleReferer(Connection
*conn
, value option
)
2482 CURLcode result
= CURLE_OK
;
2484 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2486 if (conn
->referer
!= NULL
)
2487 free(conn
->referer
);
2489 conn
->referer
= strdup(String_val(option
));
2491 result
= curl_easy_setopt(conn
->connection
,
2495 if (result
!= CURLE_OK
)
2496 raiseError(conn
, result
);
2501 static void handleUserAgent(Connection
*conn
, value option
)
2504 CURLcode result
= CURLE_OK
;
2506 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2508 if (conn
->userAgent
!= NULL
)
2509 free(conn
->userAgent
);
2511 conn
->userAgent
= strdup(String_val(option
));
2513 result
= curl_easy_setopt(conn
->connection
,
2517 if (result
!= CURLE_OK
)
2518 raiseError(conn
, result
);
2523 static void handleFTPPort(Connection
*conn
, value option
)
2526 CURLcode result
= CURLE_OK
;
2528 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2530 if (conn
->ftpPort
!= NULL
)
2531 free(conn
->ftpPort
);
2533 conn
->ftpPort
= strdup(String_val(option
));
2535 result
= curl_easy_setopt(conn
->connection
,
2539 if (result
!= CURLE_OK
)
2540 raiseError(conn
, result
);
2545 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2548 CURLcode result
= CURLE_OK
;
2550 result
= curl_easy_setopt(conn
->connection
,
2551 CURLOPT_LOW_SPEED_LIMIT
,
2554 if (result
!= CURLE_OK
)
2555 raiseError(conn
, result
);
2560 static void handleLowSpeedTime(Connection
*conn
, value option
)
2563 CURLcode result
= CURLE_OK
;
2565 result
= curl_easy_setopt(conn
->connection
,
2566 CURLOPT_LOW_SPEED_TIME
,
2569 if (result
!= CURLE_OK
)
2570 raiseError(conn
, result
);
2575 static void handleResumeFrom(Connection
*conn
, value option
)
2578 CURLcode result
= CURLE_OK
;
2580 result
= curl_easy_setopt(conn
->connection
,
2581 CURLOPT_RESUME_FROM
,
2584 if (result
!= CURLE_OK
)
2585 raiseError(conn
, result
);
2590 static void handleCookie(Connection
*conn
, value option
)
2593 CURLcode result
= CURLE_OK
;
2595 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2597 if (conn
->cookie
!= NULL
)
2600 conn
->cookie
= strdup(String_val(option
));
2602 result
= curl_easy_setopt(conn
->connection
,
2606 if (result
!= CURLE_OK
)
2607 raiseError(conn
, result
);
2612 static void handleHTTPHeader(Connection
*conn
, value option
)
2615 CAMLlocal1(listIter
);
2616 CURLcode result
= CURLE_OK
;
2619 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2621 if (conn
->httpHeader
!= NULL
)
2622 free_curl_slist(conn
->httpHeader
);
2624 conn
->httpHeader
= NULL
;
2628 while (!Is_long(listIter
))
2630 if (Tag_val(Field(listIter
, 0)) != String_tag
)
2631 failwith("Not a string");
2633 str
= strdup(String_val(Field(listIter
, 0)));
2635 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, str
);
2637 listIter
= Field(listIter
, 1);
2640 result
= curl_easy_setopt(conn
->connection
,
2644 if (result
!= CURLE_OK
)
2645 raiseError(conn
, result
);
2650 static void handleHTTPPost(Connection
*conn
, value option
)
2653 CAMLlocal3(listIter
, formItem
, contentType
);
2654 CURLcode result
= CURLE_OK
;
2655 char *str1
, *str2
, *str3
, *str4
;
2659 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2661 if (conn
->httpPostFirst
!= NULL
)
2662 curl_formfree(conn
->httpPostFirst
);
2664 conn
->httpPostFirst
= NULL
;
2665 conn
->httpPostLast
= NULL
;
2667 if (conn
->httpPostStrings
!= NULL
)
2668 free_curl_slist(conn
->httpPostStrings
);
2670 while (!Is_long(listIter
))
2672 formItem
= Field(listIter
, 0);
2674 switch (Tag_val(formItem
))
2676 case 0: /* CURLFORM_CONTENT */
2677 if (Wosize_val(formItem
) < 3)
2679 failwith("Incorrect CURLFORM_CONTENT parameters");
2682 if (Is_long(Field(formItem
, 2)) &&
2683 Long_val(Field(formItem
, 2)) == 0)
2685 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2687 String_val(Field(formItem
, 0)),
2688 string_length(Field(formItem
, 0)));
2689 str1
[string_length(Field(formItem
, 0))] = 0;
2690 conn
->httpPostStrings
=
2691 curl_slist_append(conn
->httpPostStrings
, str1
);
2693 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2695 String_val(Field(formItem
, 1)),
2696 string_length(Field(formItem
, 1)));
2697 str2
[string_length(Field(formItem
, 1))] = 0;
2698 conn
->httpPostStrings
=
2699 curl_slist_append(conn
->httpPostStrings
, str2
);
2701 curl_formadd(&conn
->httpPostFirst
,
2702 &conn
->httpPostLast
,
2705 CURLFORM_NAMELENGTH
,
2706 string_length(Field(formItem
, 0)),
2707 CURLFORM_PTRCONTENTS
,
2709 CURLFORM_CONTENTSLENGTH
,
2710 string_length(Field(formItem
, 1)),
2713 else if (Is_block(Field(formItem
, 2)))
2715 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2717 String_val(Field(formItem
, 0)),
2718 string_length(Field(formItem
, 0)));
2719 str1
[string_length(Field(formItem
, 0))] = 0;
2720 conn
->httpPostStrings
=
2721 curl_slist_append(conn
->httpPostStrings
, str1
);
2723 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2725 String_val(Field(formItem
, 1)),
2726 string_length(Field(formItem
, 1)));
2727 str2
[string_length(Field(formItem
, 1))] = 0;
2728 conn
->httpPostStrings
=
2729 curl_slist_append(conn
->httpPostStrings
, str2
);
2731 contentType
= Field(formItem
, 2);
2733 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2735 String_val(Field(contentType
, 0)),
2736 string_length(Field(contentType
, 0)));
2737 str3
[string_length(Field(contentType
, 0))] = 0;
2738 conn
->httpPostStrings
=
2739 curl_slist_append(conn
->httpPostStrings
, str3
);
2741 curl_formadd(&conn
->httpPostFirst
,
2742 &conn
->httpPostLast
,
2745 CURLFORM_NAMELENGTH
,
2746 string_length(Field(formItem
, 0)),
2747 CURLFORM_PTRCONTENTS
,
2749 CURLFORM_CONTENTSLENGTH
,
2750 string_length(Field(formItem
, 1)),
2751 CURLFORM_CONTENTTYPE
,
2757 failwith("Incorrect CURLFORM_CONTENT parameters");
2761 case 1: /* CURLFORM_FILECONTENT */
2762 if (Wosize_val(formItem
) < 3)
2764 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2767 if (Is_long(Field(formItem
, 2)) &&
2768 Long_val(Field(formItem
, 2)) == 0)
2770 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2772 String_val(Field(formItem
, 0)),
2773 string_length(Field(formItem
, 0)));
2774 str1
[string_length(Field(formItem
, 0))] = 0;
2775 conn
->httpPostStrings
=
2776 curl_slist_append(conn
->httpPostStrings
, str1
);
2778 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2780 String_val(Field(formItem
, 1)),
2781 string_length(Field(formItem
, 1)));
2782 str2
[string_length(Field(formItem
, 1))] = 0;
2783 conn
->httpPostStrings
=
2784 curl_slist_append(conn
->httpPostStrings
, str2
);
2786 curl_formadd(&conn
->httpPostFirst
,
2787 &conn
->httpPostLast
,
2790 CURLFORM_NAMELENGTH
,
2791 string_length(Field(formItem
, 0)),
2792 CURLFORM_FILECONTENT
,
2796 else if (Is_block(Field(formItem
, 2)))
2798 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2800 String_val(Field(formItem
, 0)),
2801 string_length(Field(formItem
, 0)));
2802 str1
[string_length(Field(formItem
, 0))] = 0;
2803 conn
->httpPostStrings
=
2804 curl_slist_append(conn
->httpPostStrings
, str1
);
2806 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2808 String_val(Field(formItem
, 1)),
2809 string_length(Field(formItem
, 1)));
2810 str2
[string_length(Field(formItem
, 1))] = 0;
2811 conn
->httpPostStrings
=
2812 curl_slist_append(conn
->httpPostStrings
, str2
);
2814 contentType
= Field(formItem
, 2);
2816 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2818 String_val(Field(contentType
, 0)),
2819 string_length(Field(contentType
, 0)));
2820 str3
[string_length(Field(contentType
, 0))] = 0;
2821 conn
->httpPostStrings
=
2822 curl_slist_append(conn
->httpPostStrings
, str3
);
2824 curl_formadd(&conn
->httpPostFirst
,
2825 &conn
->httpPostLast
,
2828 CURLFORM_NAMELENGTH
,
2829 string_length(Field(formItem
, 0)),
2830 CURLFORM_FILECONTENT
,
2832 CURLFORM_CONTENTTYPE
,
2838 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2842 case 2: /* CURLFORM_FILE */
2843 if (Wosize_val(formItem
) < 3)
2845 failwith("Incorrect CURLFORM_FILE parameters");
2848 if (Is_long(Field(formItem
, 2)) &&
2849 Long_val(Field(formItem
, 2)) == 0)
2851 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2853 String_val(Field(formItem
, 0)),
2854 string_length(Field(formItem
, 0)));
2855 str1
[string_length(Field(formItem
, 0))] = 0;
2856 conn
->httpPostStrings
=
2857 curl_slist_append(conn
->httpPostStrings
, str1
);
2859 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2861 String_val(Field(formItem
, 1)),
2862 string_length(Field(formItem
, 1)));
2863 str2
[string_length(Field(formItem
, 1))] = 0;
2864 conn
->httpPostStrings
=
2865 curl_slist_append(conn
->httpPostStrings
, str2
);
2867 curl_formadd(&conn
->httpPostFirst
,
2868 &conn
->httpPostLast
,
2871 CURLFORM_NAMELENGTH
,
2872 string_length(Field(formItem
, 0)),
2877 else if (Is_block(Field(formItem
, 2)))
2879 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2881 String_val(Field(formItem
, 0)),
2882 string_length(Field(formItem
, 0)));
2883 str1
[string_length(Field(formItem
, 0))] = 0;
2884 conn
->httpPostStrings
=
2885 curl_slist_append(conn
->httpPostStrings
, str1
);
2887 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2889 String_val(Field(formItem
, 1)),
2890 string_length(Field(formItem
, 1)));
2891 str2
[string_length(Field(formItem
, 1))] = 0;
2892 conn
->httpPostStrings
=
2893 curl_slist_append(conn
->httpPostStrings
, str2
);
2895 contentType
= Field(formItem
, 2);
2897 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2899 String_val(Field(contentType
, 0)),
2900 string_length(Field(contentType
, 0)));
2901 str3
[string_length(Field(contentType
, 0))] = 0;
2902 conn
->httpPostStrings
=
2903 curl_slist_append(conn
->httpPostStrings
, str3
);
2905 curl_formadd(&conn
->httpPostFirst
,
2906 &conn
->httpPostLast
,
2909 CURLFORM_NAMELENGTH
,
2910 string_length(Field(formItem
, 0)),
2913 CURLFORM_CONTENTTYPE
,
2919 failwith("Incorrect CURLFORM_FILE parameters");
2923 case 3: /* CURLFORM_BUFFER */
2924 if (Wosize_val(formItem
) < 4)
2926 failwith("Incorrect CURLFORM_BUFFER parameters");
2929 if (Is_long(Field(formItem
, 3)) &&
2930 Long_val(Field(formItem
, 3)) == 0)
2932 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2934 String_val(Field(formItem
, 0)),
2935 string_length(Field(formItem
, 0)));
2936 str1
[string_length(Field(formItem
, 0))] = 0;
2937 conn
->httpPostStrings
=
2938 curl_slist_append(conn
->httpPostStrings
, str1
);
2940 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2942 String_val(Field(formItem
, 1)),
2943 string_length(Field(formItem
, 1)));
2944 str2
[string_length(Field(formItem
, 1))] = 0;
2945 conn
->httpPostStrings
=
2946 curl_slist_append(conn
->httpPostStrings
, str2
);
2948 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2950 String_val(Field(formItem
, 2)),
2951 string_length(Field(formItem
, 2)));
2952 str3
[string_length(Field(formItem
, 2))] = 0;
2953 conn
->httpPostStrings
=
2954 curl_slist_append(conn
->httpPostStrings
, str3
);
2956 curl_formadd(&conn
->httpPostFirst
,
2957 &conn
->httpPostLast
,
2960 CURLFORM_NAMELENGTH
,
2961 string_length(Field(formItem
, 0)),
2966 CURLFORM_BUFFERLENGTH
,
2967 string_length(Field(formItem
, 2)),
2970 else if (Is_block(Field(formItem
, 3)))
2972 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2974 String_val(Field(formItem
, 0)),
2975 string_length(Field(formItem
, 0)));
2976 str1
[string_length(Field(formItem
, 0))] = 0;
2977 conn
->httpPostStrings
=
2978 curl_slist_append(conn
->httpPostStrings
, str1
);
2980 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2982 String_val(Field(formItem
, 1)),
2983 string_length(Field(formItem
, 1)));
2984 str2
[string_length(Field(formItem
, 1))] = 0;
2985 conn
->httpPostStrings
=
2986 curl_slist_append(conn
->httpPostStrings
, str2
);
2988 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2990 String_val(Field(formItem
, 2)),
2991 string_length(Field(formItem
, 2)));
2992 str3
[string_length(Field(formItem
, 2))] = 0;
2993 conn
->httpPostStrings
=
2994 curl_slist_append(conn
->httpPostStrings
, str3
);
2996 contentType
= Field(formItem
, 3);
2998 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
3000 String_val(Field(contentType
, 0)),
3001 string_length(Field(contentType
, 0)));
3002 str4
[string_length(Field(contentType
, 0))] = 0;
3003 conn
->httpPostStrings
=
3004 curl_slist_append(conn
->httpPostStrings
, str4
);
3006 curl_formadd(&conn
->httpPostFirst
,
3007 &conn
->httpPostLast
,
3010 CURLFORM_NAMELENGTH
,
3011 string_length(Field(formItem
, 0)),
3016 CURLFORM_BUFFERLENGTH
,
3017 string_length(Field(formItem
, 2)),
3018 CURLFORM_CONTENTTYPE
,
3024 failwith("Incorrect CURLFORM_BUFFER parameters");
3029 listIter
= Field(listIter
, 1);
3032 result
= curl_easy_setopt(conn
->connection
,
3034 conn
->httpPostFirst
);
3036 if (result
!= CURLE_OK
)
3037 raiseError(conn
, result
);
3042 static void handleSSLCert(Connection
*conn
, value option
)
3045 CURLcode result
= CURLE_OK
;
3047 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3049 if (conn
->sslCert
!= NULL
)
3050 free(conn
->sslCert
);
3052 conn
->sslCert
= strdup(String_val(option
));
3054 result
= curl_easy_setopt(conn
->connection
,
3058 if (result
!= CURLE_OK
)
3059 raiseError(conn
, result
);
3064 static void handleSSLCertType(Connection
*conn
, value option
)
3067 CURLcode result
= CURLE_OK
;
3069 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3071 if (conn
->sslCertType
!= NULL
)
3072 free(conn
->sslCertType
);
3074 conn
->sslCertType
= strdup(String_val(option
));
3076 result
= curl_easy_setopt(conn
->connection
,
3077 CURLOPT_SSLCERTTYPE
,
3080 if (result
!= CURLE_OK
)
3081 raiseError(conn
, result
);
3086 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3089 CURLcode result
= CURLE_OK
;
3091 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3093 if (conn
->sslCertPasswd
!= NULL
)
3094 free(conn
->sslCertPasswd
);
3096 conn
->sslCertPasswd
= strdup(String_val(option
));
3098 result
= curl_easy_setopt(conn
->connection
,
3099 CURLOPT_SSLCERTPASSWD
,
3100 conn
->sslCertPasswd
);
3102 if (result
!= CURLE_OK
)
3103 raiseError(conn
, result
);
3108 static void handleSSLKey(Connection
*conn
, value option
)
3111 CURLcode result
= CURLE_OK
;
3113 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3115 if (conn
->sslKey
!= NULL
)
3118 conn
->sslKey
= strdup(String_val(option
));
3120 result
= curl_easy_setopt(conn
->connection
,
3124 if (result
!= CURLE_OK
)
3125 raiseError(conn
, result
);
3130 static void handleSSLKeyType(Connection
*conn
, value option
)
3133 CURLcode result
= CURLE_OK
;
3135 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3137 if (conn
->sslKeyType
!= NULL
)
3138 free(conn
->sslKeyType
);
3140 conn
->sslKeyType
= strdup(String_val(option
));
3142 result
= curl_easy_setopt(conn
->connection
,
3146 if (result
!= CURLE_OK
)
3147 raiseError(conn
, result
);
3152 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3155 CURLcode result
= CURLE_OK
;
3157 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3159 if (conn
->sslKeyPasswd
!= NULL
)
3160 free(conn
->sslKeyPasswd
);
3162 conn
->sslKeyPasswd
= strdup(String_val(option
));
3164 result
= curl_easy_setopt(conn
->connection
,
3165 CURLOPT_SSLKEYPASSWD
,
3166 conn
->sslKeyPasswd
);
3168 if (result
!= CURLE_OK
)
3169 raiseError(conn
, result
);
3174 static void handleSSLEngine(Connection
*conn
, value option
)
3177 CURLcode result
= CURLE_OK
;
3179 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3181 if (conn
->sslEngine
!= NULL
)
3182 free(conn
->sslEngine
);
3184 conn
->sslEngine
= strdup(String_val(option
));
3186 result
= curl_easy_setopt(conn
->connection
,
3190 if (result
!= CURLE_OK
)
3191 raiseError(conn
, result
);
3196 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3199 CURLcode result
= CURLE_OK
;
3201 result
= curl_easy_setopt(conn
->connection
,
3202 CURLOPT_SSLENGINE_DEFAULT
,
3205 if (result
!= CURLE_OK
)
3206 raiseError(conn
, result
);
3211 static void handleCRLF(Connection
*conn
, value option
)
3214 CURLcode result
= CURLE_OK
;
3216 result
= curl_easy_setopt(conn
->connection
,
3220 if (result
!= CURLE_OK
)
3221 raiseError(conn
, result
);
3226 static void handleQuote(Connection
*conn
, value option
)
3229 CAMLlocal1(listIter
);
3230 CURLcode result
= CURLE_OK
;
3233 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3235 if (conn
->quote
!= NULL
)
3236 free_curl_slist(conn
->quote
);
3242 while (!Is_long(listIter
))
3244 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3245 failwith("Not a string");
3247 str
= strdup(String_val(Field(listIter
, 0)));
3249 conn
->quote
= curl_slist_append(conn
->quote
, str
);
3251 listIter
= Field(listIter
, 1);
3254 result
= curl_easy_setopt(conn
->connection
,
3258 if (result
!= CURLE_OK
)
3259 raiseError(conn
, result
);
3264 static void handlePostQuote(Connection
*conn
, value option
)
3267 CAMLlocal1(listIter
);
3268 CURLcode result
= CURLE_OK
;
3271 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3273 if (conn
->postQuote
!= NULL
)
3274 free_curl_slist(conn
->postQuote
);
3276 conn
->postQuote
= NULL
;
3280 while (!Is_long(listIter
))
3282 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3283 failwith("Not a string");
3285 str
= strdup(String_val(Field(listIter
, 0)));
3287 conn
->postQuote
= curl_slist_append(conn
->postQuote
, str
);
3289 listIter
= Field(listIter
, 1);
3292 result
= curl_easy_setopt(conn
->connection
,
3296 if (result
!= CURLE_OK
)
3297 raiseError(conn
, result
);
3302 static void handleHeaderFunction(Connection
*conn
, value option
)
3305 CURLcode result
= CURLE_OK
;
3307 if (Tag_val(option
) == Closure_tag
)
3308 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3310 failwith("Not a proper closure");
3312 result
= curl_easy_setopt(conn
->connection
,
3313 CURLOPT_HEADERFUNCTION
,
3316 if (result
!= CURLE_OK
)
3317 raiseError(conn
, result
);
3319 result
= curl_easy_setopt(conn
->connection
,
3320 CURLOPT_WRITEHEADER
,
3323 if (result
!= CURLE_OK
)
3324 raiseError(conn
, result
);
3329 static void handleCookieFile(Connection
*conn
, value option
)
3332 CURLcode result
= CURLE_OK
;
3334 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3336 if (conn
->cookieFile
!= NULL
)
3337 free(conn
->cookieFile
);
3339 conn
->cookieFile
= strdup(String_val(option
));
3341 result
= curl_easy_setopt(conn
->connection
,
3345 if (result
!= CURLE_OK
)
3346 raiseError(conn
, result
);
3351 static void handleSSLVersion(Connection
*conn
, value option
)
3354 CURLcode result
= CURLE_OK
;
3356 result
= curl_easy_setopt(conn
->connection
,
3360 if (result
!= CURLE_OK
)
3361 raiseError(conn
, result
);
3366 static void handleTimeCondition(Connection
*conn
, value option
)
3369 CURLcode result
= CURLE_OK
;
3371 switch (Long_val(option
))
3373 case 0: /* TIMECOND_IFMODSINCE */
3374 result
= curl_easy_setopt(conn
->connection
,
3375 CURLOPT_TIMECONDITION
,
3376 CURL_TIMECOND_IFMODSINCE
);
3379 case 1: /* TIMECOND_IFUNMODSINCE */
3380 result
= curl_easy_setopt(conn
->connection
,
3381 CURLOPT_TIMECONDITION
,
3382 CURL_TIMECOND_IFUNMODSINCE
);
3386 failwith("Invalid TIMECOND Option");
3390 if (result
!= CURLE_OK
)
3391 raiseError(conn
, result
);
3396 static void handleTimeValue(Connection
*conn
, value option
)
3399 CURLcode result
= CURLE_OK
;
3401 result
= curl_easy_setopt(conn
->connection
,
3405 if (result
!= CURLE_OK
)
3406 raiseError(conn
, result
);
3411 static void handleCustomRequest(Connection
*conn
, value option
)
3414 CURLcode result
= CURLE_OK
;
3416 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3418 if (conn
->customRequest
!= NULL
)
3419 free(conn
->customRequest
);
3421 conn
->customRequest
= strdup(String_val(option
));
3423 result
= curl_easy_setopt(conn
->connection
,
3424 CURLOPT_CUSTOMREQUEST
,
3425 conn
->customRequest
);
3427 if (result
!= CURLE_OK
)
3428 raiseError(conn
, result
);
3433 static void handleInterface(Connection
*conn
, value option
)
3436 CURLcode result
= CURLE_OK
;
3438 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3440 if (conn
->interface
!= NULL
)
3441 free(conn
->interface
);
3443 conn
->interface
= strdup(String_val(option
));
3445 result
= curl_easy_setopt(conn
->connection
,
3449 if (result
!= CURLE_OK
)
3450 raiseError(conn
, result
);
3455 static void handleKRB4Level(Connection
*conn
, value option
)
3458 CURLcode result
= CURLE_OK
;
3460 switch (Long_val(option
))
3462 case 0: /* KRB4_NONE */
3463 result
= curl_easy_setopt(conn
->connection
,
3468 case 1: /* KRB4_CLEAR */
3469 result
= curl_easy_setopt(conn
->connection
,
3474 case 2: /* KRB4_SAFE */
3475 result
= curl_easy_setopt(conn
->connection
,
3480 case 3: /* KRB4_CONFIDENTIAL */
3481 result
= curl_easy_setopt(conn
->connection
,
3486 case 4: /* KRB4_PRIVATE */
3487 result
= curl_easy_setopt(conn
->connection
,
3493 failwith("Invalid KRB4 Option");
3497 if (result
!= CURLE_OK
)
3498 raiseError(conn
, result
);
3503 static void handleProgressFunction(Connection
*conn
, value option
)
3506 CURLcode result
= CURLE_OK
;
3508 if (Tag_val(option
) == Closure_tag
)
3509 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3511 failwith("Not a proper closure");
3513 result
= curl_easy_setopt(conn
->connection
,
3514 CURLOPT_PROGRESSFUNCTION
,
3516 if (result
!= CURLE_OK
)
3517 raiseError(conn
, result
);
3519 result
= curl_easy_setopt(conn
->connection
,
3520 CURLOPT_PROGRESSDATA
,
3523 if (result
!= CURLE_OK
)
3524 raiseError(conn
, result
);
3529 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3532 CURLcode result
= CURLE_OK
;
3534 result
= curl_easy_setopt(conn
->connection
,
3535 CURLOPT_SSL_VERIFYPEER
,
3538 if (result
!= CURLE_OK
)
3539 raiseError(conn
, result
);
3544 static void handleCAInfo(Connection
*conn
, value option
)
3547 CURLcode result
= CURLE_OK
;
3549 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3551 if (conn
->caInfo
!= NULL
)
3554 conn
->caInfo
= strdup(String_val(option
));
3556 result
= curl_easy_setopt(conn
->connection
,
3560 if (result
!= CURLE_OK
)
3561 raiseError(conn
, result
);
3566 static void handleCAPath(Connection
*conn
, value option
)
3569 CURLcode result
= CURLE_OK
;
3571 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3573 if (conn
->caPath
!= NULL
)
3576 conn
->caPath
= strdup(String_val(option
));
3578 result
= curl_easy_setopt(conn
->connection
,
3582 if (result
!= CURLE_OK
)
3583 raiseError(conn
, result
);
3588 static void handleFileTime(Connection
*conn
, value option
)
3591 CURLcode result
= CURLE_OK
;
3593 result
= curl_easy_setopt(conn
->connection
,
3597 if (result
!= CURLE_OK
)
3598 raiseError(conn
, result
);
3603 static void handleMaxRedirs(Connection
*conn
, value option
)
3606 CURLcode result
= CURLE_OK
;
3608 result
= curl_easy_setopt(conn
->connection
,
3612 if (result
!= CURLE_OK
)
3613 raiseError(conn
, result
);
3618 static void handleMaxConnects(Connection
*conn
, value option
)
3621 CURLcode result
= CURLE_OK
;
3623 result
= curl_easy_setopt(conn
->connection
,
3624 CURLOPT_MAXCONNECTS
,
3627 if (result
!= CURLE_OK
)
3628 raiseError(conn
, result
);
3633 static void handleClosePolicy(Connection
*conn
, value option
)
3636 CURLcode result
= CURLE_OK
;
3638 switch (Long_val(option
))
3640 case 0: /* CLOSEPOLICY_OLDEST */
3641 result
= curl_easy_setopt(conn
->connection
,
3642 CURLOPT_CLOSEPOLICY
,
3643 CURLCLOSEPOLICY_OLDEST
);
3646 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3647 result
= curl_easy_setopt(conn
->connection
,
3648 CURLOPT_CLOSEPOLICY
,
3649 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3653 failwith("Invalid CLOSEPOLICY Option");
3657 if (result
!= CURLE_OK
)
3658 raiseError(conn
, result
);
3663 static void handleFreshConnect(Connection
*conn
, value option
)
3666 CURLcode result
= CURLE_OK
;
3668 result
= curl_easy_setopt(conn
->connection
,
3669 CURLOPT_FRESH_CONNECT
,
3672 if (result
!= CURLE_OK
)
3673 raiseError(conn
, result
);
3678 static void handleForbidReuse(Connection
*conn
, value option
)
3681 CURLcode result
= CURLE_OK
;
3683 result
= curl_easy_setopt(conn
->connection
,
3684 CURLOPT_FORBID_REUSE
,
3687 if (result
!= CURLE_OK
)
3688 raiseError(conn
, result
);
3693 static void handleRandomFile(Connection
*conn
, value option
)
3696 CURLcode result
= CURLE_OK
;
3698 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3700 if (conn
->randomFile
!= NULL
)
3701 free(conn
->randomFile
);
3703 conn
->randomFile
= strdup(String_val(option
));
3705 result
= curl_easy_setopt(conn
->connection
,
3706 CURLOPT_RANDOM_FILE
,
3709 if (result
!= CURLE_OK
)
3710 raiseError(conn
, result
);
3715 static void handleEGDSocket(Connection
*conn
, value option
)
3718 CURLcode result
= CURLE_OK
;
3720 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3722 if (conn
->egdSocket
!= NULL
)
3723 free(conn
->egdSocket
);
3725 conn
->egdSocket
= strdup(String_val(option
));
3727 result
= curl_easy_setopt(conn
->connection
,
3731 if (result
!= CURLE_OK
)
3732 raiseError(conn
, result
);
3737 static void handleConnectTimeout(Connection
*conn
, value option
)
3740 CURLcode result
= CURLE_OK
;
3742 result
= curl_easy_setopt(conn
->connection
,
3743 CURLOPT_CONNECTTIMEOUT
,
3746 if (result
!= CURLE_OK
)
3747 raiseError(conn
, result
);
3752 static void handleHTTPGet(Connection
*conn
, value option
)
3755 CURLcode result
= CURLE_OK
;
3757 result
= curl_easy_setopt(conn
->connection
,
3761 if (result
!= CURLE_OK
)
3762 raiseError(conn
, result
);
3767 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3770 CURLcode result
= CURLE_OK
;
3772 switch (Long_val(option
))
3774 case 0: /* SSLVERIFYHOST_EXISTENCE */
3775 result
= curl_easy_setopt(conn
->connection
,
3776 CURLOPT_SSL_VERIFYHOST
,
3780 case 1: /* SSLVERIFYHOST_HOSTNAME */
3781 result
= curl_easy_setopt(conn
->connection
,
3782 CURLOPT_SSL_VERIFYHOST
,
3787 failwith("Invalid SSLVERIFYHOST Option");
3791 if (result
!= CURLE_OK
)
3792 raiseError(conn
, result
);
3797 static void handleCookieJar(Connection
*conn
, value option
)
3800 CURLcode result
= CURLE_OK
;
3802 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3804 if (conn
->cookieJar
!= NULL
)
3805 free(conn
->cookieJar
);
3807 conn
->cookieJar
= strdup(String_val(option
));
3809 result
= curl_easy_setopt(conn
->connection
,
3813 if (result
!= CURLE_OK
)
3814 raiseError(conn
, result
);
3819 static void handleSSLCipherList(Connection
*conn
, value option
)
3822 CURLcode result
= CURLE_OK
;
3824 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3826 if (conn
->sslCipherList
!= NULL
)
3827 free(conn
->sslCipherList
);
3829 conn
->sslCipherList
= strdup(String_val(option
));
3831 result
= curl_easy_setopt(conn
->connection
,
3832 CURLOPT_SSL_CIPHER_LIST
,
3833 conn
->sslCipherList
);
3835 if (result
!= CURLE_OK
)
3836 raiseError(conn
, result
);
3841 static void handleHTTPVersion(Connection
*conn
, value option
)
3844 CURLcode result
= CURLE_OK
;
3846 switch (Long_val(option
))
3848 case 0: /* HTTP_VERSION_NONE */
3849 result
= curl_easy_setopt(conn
->connection
,
3850 CURLOPT_HTTP_VERSION
,
3851 CURL_HTTP_VERSION_NONE
);
3854 case 1: /* HTTP_VERSION_1_0 */
3855 result
= curl_easy_setopt(conn
->connection
,
3856 CURLOPT_HTTP_VERSION
,
3857 CURL_HTTP_VERSION_1_0
);
3860 case 2: /* HTTP_VERSION_1_1 */
3861 result
= curl_easy_setopt(conn
->connection
,
3862 CURLOPT_HTTP_VERSION
,
3863 CURL_HTTP_VERSION_1_1
);
3867 failwith("Invalid HTTP_VERSION Option");
3871 if (result
!= CURLE_OK
)
3872 raiseError(conn
, result
);
3877 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3880 CURLcode result
= CURLE_OK
;
3882 result
= curl_easy_setopt(conn
->connection
,
3883 CURLOPT_FTP_USE_EPSV
,
3886 if (result
!= CURLE_OK
)
3887 raiseError(conn
, result
);
3892 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3895 CURLcode result
= CURLE_OK
;
3897 result
= curl_easy_setopt(conn
->connection
,
3898 CURLOPT_DNS_CACHE_TIMEOUT
,
3901 if (result
!= CURLE_OK
)
3902 raiseError(conn
, result
);
3907 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3910 CURLcode result
= CURLE_OK
;
3912 result
= curl_easy_setopt(conn
->connection
,
3913 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3916 if (result
!= CURLE_OK
)
3917 raiseError(conn
, result
);
3922 static void handleDebugFunction(Connection
*conn
, value option
)
3925 CURLcode result
= CURLE_OK
;
3927 if (Tag_val(option
) == Closure_tag
)
3928 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3930 failwith("Not a proper closure");
3932 result
= curl_easy_setopt(conn
->connection
,
3933 CURLOPT_DEBUGFUNCTION
,
3935 if (result
!= CURLE_OK
)
3936 raiseError(conn
, result
);
3938 result
= curl_easy_setopt(conn
->connection
,
3942 if (result
!= CURLE_OK
)
3943 raiseError(conn
, result
);
3948 static void handlePrivate(Connection
*conn
, value option
)
3950 #if HAVE_DECL_CURLOPT_PRIVATE
3952 CURLcode result
= CURLE_OK
;
3954 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
3956 if (conn
->private != NULL
)
3957 free(conn
->private);
3959 conn
->private = strdup(String_val(option
));
3961 result
= curl_easy_setopt(conn
->connection
,
3965 if (result
!= CURLE_OK
)
3966 raiseError(conn
, result
);
3970 #warning "libcurl does not implement CURLOPT_PRIVATE"
3971 failwith("libcurl does not implement CURLOPT_PRIVATE");
3975 static void handleHTTP200Aliases(Connection
*conn
, value option
)
3977 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3979 CAMLlocal1(listIter
);
3980 CURLcode result
= CURLE_OK
;
3983 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
3985 if (conn
->http200Aliases
!= NULL
)
3986 free_curl_slist(conn
->http200Aliases
);
3988 conn
->http200Aliases
= NULL
;
3992 while (!Is_long(listIter
))
3994 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3995 failwith("Not a string");
3997 str
= strdup(String_val(Field(listIter
, 0)));
3999 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, str
);
4001 listIter
= Field(listIter
, 1);
4004 result
= curl_easy_setopt(conn
->connection
,
4005 CURLOPT_HTTP200ALIASES
,
4006 conn
->http200Aliases
);
4008 if (result
!= CURLE_OK
)
4009 raiseError(conn
, result
);
4013 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
4014 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
4018 static void handleUnrestrictedAuth(Connection
*conn
, value option
)
4020 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
4022 CURLcode result
= CURLE_OK
;
4024 result
= curl_easy_setopt(conn
->connection
,
4025 CURLOPT_UNRESTRICTED_AUTH
,
4028 if (result
!= CURLE_OK
)
4029 raiseError(conn
, result
);
4033 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4034 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4038 static void handleFTPUseEPRT(Connection
*conn
, value option
)
4040 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4042 CURLcode result
= CURLE_OK
;
4044 result
= curl_easy_setopt(conn
->connection
,
4045 CURLOPT_FTP_USE_EPRT
,
4048 if (result
!= CURLE_OK
)
4049 raiseError(conn
, result
);
4053 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4054 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4058 static void handleHTTPAuth(Connection
*conn
, value option
)
4060 #if HAVE_DECL_CURLOPT_HTTPAUTH
4062 CAMLlocal1(listIter
);
4063 CURLcode result
= CURLE_OK
;
4064 long auth
= CURLAUTH_NONE
;
4068 while (!Is_long(listIter
))
4070 switch (Long_val(Field(listIter
, 0)))
4072 case 0: /* CURLAUTH_BASIC */
4073 auth
|= CURLAUTH_BASIC
;
4076 case 1: /* CURLAUTH_DIGEST */
4077 auth
|= CURLAUTH_DIGEST
;
4080 case 2: /* CURLAUTH_GSSNEGOTIATE */
4081 auth
|= CURLAUTH_GSSNEGOTIATE
;
4084 case 3: /* CURLAUTH_NTLM */
4085 auth
|= CURLAUTH_NTLM
;
4088 case 4: /* CURLAUTH_ANY */
4089 auth
|= CURLAUTH_ANY
;
4092 case 5: /* CURLAUTH_ANYSAFE */
4093 auth
|= CURLAUTH_ANYSAFE
;
4097 failwith("Invalid HTTPAUTH Value");
4101 listIter
= Field(listIter
, 1);
4104 result
= curl_easy_setopt(conn
->connection
,
4108 if (result
!= CURLE_OK
)
4109 raiseError(conn
, result
);
4113 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4114 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4118 static void handleFTPCreateMissingDirs(Connection
*conn
, value option
)
4120 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4122 CURLcode result
= CURLE_OK
;
4124 result
= curl_easy_setopt(conn
->connection
,
4125 CURLOPT_FTP_CREATE_MISSING_DIRS
,
4128 if (result
!= CURLE_OK
)
4129 raiseError(conn
, result
);
4133 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4134 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4138 static void handleProxyAuth(Connection
*conn
, value option
)
4140 #if HAVE_DECL_CURLOPT_PROXYAUTH
4142 CAMLlocal1(listIter
);
4143 CURLcode result
= CURLE_OK
;
4144 long auth
= CURLAUTH_NONE
;
4148 while (!Is_long(listIter
))
4150 switch (Long_val(Field(listIter
, 0)))
4152 case 0: /* CURLAUTH_BASIC */
4153 auth
|= CURLAUTH_BASIC
;
4156 case 1: /* CURLAUTH_DIGEST */
4157 auth
|= CURLAUTH_DIGEST
;
4160 case 2: /* CURLAUTH_GSSNEGOTIATE */
4161 auth
|= CURLAUTH_GSSNEGOTIATE
;
4164 case 3: /* CURLAUTH_NTLM */
4165 auth
|= CURLAUTH_NTLM
;
4168 case 4: /* CURLAUTH_ANY */
4169 auth
|= CURLAUTH_ANY
;
4172 case 5: /* CURLAUTH_ANYSAFE */
4173 auth
|= CURLAUTH_ANYSAFE
;
4177 failwith("Invalid HTTPAUTH Value");
4181 listIter
= Field(listIter
, 1);
4184 result
= curl_easy_setopt(conn
->connection
,
4188 if (result
!= CURLE_OK
)
4189 raiseError(conn
, result
);
4193 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4194 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4198 static void handleFTPResponseTimeout(Connection
*conn
, value option
)
4200 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4202 CURLcode result
= CURLE_OK
;
4204 result
= curl_easy_setopt(conn
->connection
,
4205 CURLOPT_FTP_RESPONSE_TIMEOUT
,
4208 if (result
!= CURLE_OK
)
4209 raiseError(conn
, result
);
4213 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4214 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4218 static void handleIPResolve(Connection
*conn
, value option
)
4220 #if HAVE_DECL_CURLOPT_IPRESOLVE
4222 CURLcode result
= CURLE_OK
;
4224 switch (Long_val(option
))
4226 case 0: /* CURL_IPRESOLVE_WHATEVER */
4227 result
= curl_easy_setopt(conn
->connection
,
4229 CURL_IPRESOLVE_WHATEVER
);
4232 case 1: /* CURL_IPRESOLVE_V4 */
4233 result
= curl_easy_setopt(conn
->connection
,
4238 case 2: /* CURL_IPRESOLVE_V6 */
4239 result
= curl_easy_setopt(conn
->connection
,
4245 failwith("Invalid IPRESOLVE Value");
4249 if (result
!= CURLE_OK
)
4250 raiseError(conn
, result
);
4254 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4255 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4259 static void handleMaxFileSize(Connection
*conn
, value option
)
4261 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4263 CURLcode result
= CURLE_OK
;
4265 result
= curl_easy_setopt(conn
->connection
,
4266 CURLOPT_MAXFILESIZE
,
4269 if (result
!= CURLE_OK
)
4270 raiseError(conn
, result
);
4274 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4275 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4279 static void handleInFileSizeLarge(Connection
*conn
, value option
)
4281 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4283 CURLcode result
= CURLE_OK
;
4285 result
= curl_easy_setopt(conn
->connection
,
4286 CURLOPT_INFILESIZE_LARGE
,
4289 if (result
!= CURLE_OK
)
4290 raiseError(conn
, result
);
4294 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4295 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4299 static void handleResumeFromLarge(Connection
*conn
, value option
)
4301 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4303 CURLcode result
= CURLE_OK
;
4305 result
= curl_easy_setopt(conn
->connection
,
4306 CURLOPT_RESUME_FROM_LARGE
,
4309 if (result
!= CURLE_OK
)
4310 raiseError(conn
, result
);
4314 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4315 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4319 static void handleMaxFileSizeLarge(Connection
*conn
, value option
)
4321 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4323 CURLcode result
= CURLE_OK
;
4325 result
= curl_easy_setopt(conn
->connection
,
4326 CURLOPT_MAXFILESIZE_LARGE
,
4329 if (result
!= CURLE_OK
)
4330 raiseError(conn
, result
);
4334 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4335 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4339 static void handleNETRCFile(Connection
*conn
, value option
)
4341 #if HAVE_DECL_CURLOPT_NETRC_FILE
4343 CURLcode result
= CURLE_OK
;
4345 Store_field(conn
->ocamlValues
, OcamlNETRCFile
, option
);
4347 if (conn
->netrcFile
!= NULL
)
4348 free(conn
->netrcFile
);
4350 conn
->netrcFile
= strdup(String_val(option
));
4352 result
= curl_easy_setopt(conn
->connection
,
4356 if (result
!= CURLE_OK
)
4357 raiseError(conn
, result
);
4361 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4362 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4366 static void handleFTPSSL(Connection
*conn
, value option
)
4368 #if HAVE_DECL_CURLOPT_FTP_SSL
4370 CURLcode result
= CURLE_OK
;
4372 switch (Long_val(option
))
4374 case 0: /* CURLFTPSSL_NONE */
4375 result
= curl_easy_setopt(conn
->connection
,
4380 case 1: /* CURLFTPSSL_TRY */
4381 result
= curl_easy_setopt(conn
->connection
,
4386 case 2: /* CURLFTPSSL_CONTROL */
4387 result
= curl_easy_setopt(conn
->connection
,
4389 CURLFTPSSL_CONTROL
);
4392 case 3: /* CURLFTPSSL_ALL */
4393 result
= curl_easy_setopt(conn
->connection
,
4399 failwith("Invalid FTP_SSL Value");
4403 if (result
!= CURLE_OK
)
4404 raiseError(conn
, result
);
4408 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4409 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4413 static void handlePostFieldSizeLarge(Connection
*conn
, value option
)
4415 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4417 CURLcode result
= CURLE_OK
;
4419 result
= curl_easy_setopt(conn
->connection
,
4420 CURLOPT_POSTFIELDSIZE_LARGE
,
4423 if (result
!= CURLE_OK
)
4424 raiseError(conn
, result
);
4428 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4429 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4433 static void handleTCPNoDelay(Connection
*conn
, value option
)
4435 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4437 CURLcode result
= CURLE_OK
;
4439 result
= curl_easy_setopt(conn
->connection
,
4440 CURLOPT_TCP_NODELAY
,
4443 if (result
!= CURLE_OK
)
4444 raiseError(conn
, result
);
4448 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4449 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4453 static void handleFTPSSLAuth(Connection
*conn
, value option
)
4455 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4457 CURLcode result
= CURLE_OK
;
4459 switch (Long_val(option
))
4461 case 0: /* CURLFTPAUTH_DEFAULT */
4462 result
= curl_easy_setopt(conn
->connection
,
4464 CURLFTPAUTH_DEFAULT
);
4467 case 1: /* CURLFTPAUTH_SSL */
4468 result
= curl_easy_setopt(conn
->connection
,
4473 case 2: /* CURLFTPAUTH_TLS */
4474 result
= curl_easy_setopt(conn
->connection
,
4480 failwith("Invalid FTPSSLAUTH value");
4484 if (result
!= CURLE_OK
)
4485 raiseError(conn
, result
);
4489 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4490 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4494 static void handleIOCTLFunction(Connection
*conn
, value option
)
4496 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4498 CURLcode result
= CURLE_OK
;
4500 if (Tag_val(option
) == Closure_tag
)
4501 Store_field(conn
->ocamlValues
, OcamlIOCTLCallback
, option
);
4503 failwith("Not a proper closure");
4505 result
= curl_easy_setopt(conn
->connection
,
4506 CURLOPT_IOCTLFUNCTION
,
4508 if (result
!= CURLE_OK
)
4509 raiseError(conn
, result
);
4511 result
= curl_easy_setopt(conn
->connection
,
4515 if (result
!= CURLE_OK
)
4516 raiseError(conn
, result
);
4520 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4521 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4525 static void handleFTPAccount(Connection
*conn
, value option
)
4527 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4529 CURLcode result
= CURLE_OK
;
4531 Store_field(conn
->ocamlValues
, OcamlFTPAccount
, option
);
4533 if (conn
->ftpaccount
!= NULL
)
4534 free(conn
->ftpaccount
);
4536 conn
->ftpaccount
= strdup(String_val(option
));
4538 result
= curl_easy_setopt(conn
->connection
,
4539 CURLOPT_FTP_ACCOUNT
,
4542 if (result
!= CURLE_OK
)
4543 raiseError(conn
, result
);
4547 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4548 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4552 static void handleCookieList(Connection
*conn
, value option
)
4554 #if HAVE_DECL_CURLOPT_COOKIELIST
4556 CURLcode result
= CURLE_OK
;
4558 Store_field(conn
->ocamlValues
, OcamlCookieList
, option
);
4560 if (conn
->cookielist
!= NULL
)
4561 free(conn
->cookielist
);
4563 conn
->cookielist
= strdup(String_val(option
));
4565 result
= curl_easy_setopt(conn
->connection
,
4569 if (result
!= CURLE_OK
)
4570 raiseError(conn
, result
);
4574 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4575 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4579 static void handleIgnoreContentLength(Connection
*conn
, value option
)
4581 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4583 CURLcode result
= CURLE_OK
;
4585 result
= curl_easy_setopt(conn
->connection
,
4586 CURLOPT_IGNORE_CONTENT_LENGTH
,
4589 if (result
!= CURLE_OK
)
4590 raiseError(conn
, result
);
4594 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4595 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4599 static void handleFTPSkipPASVIP(Connection
*conn
, value option
)
4601 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4603 CURLcode result
= CURLE_OK
;
4605 result
= curl_easy_setopt(conn
->connection
,
4606 CURLOPT_FTP_SKIP_PASV_IP
,
4609 if (result
!= CURLE_OK
)
4610 raiseError(conn
, result
);
4614 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4615 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4619 static void handleFTPFileMethod(Connection
*conn
, value option
)
4621 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4623 CURLcode result
= CURLE_OK
;
4625 switch (Long_val(option
))
4627 case 0: /* CURLFTPMETHOD_DEFAULT */
4628 result
= curl_easy_setopt(conn
->connection
,
4629 CURLOPT_FTP_FILEMETHOD
,
4630 CURLFTPMETHOD_DEFAULT
);
4633 case 1: /* CURLFTMETHOD_MULTICWD */
4634 result
= curl_easy_setopt(conn
->connection
,
4635 CURLOPT_FTP_FILEMETHOD
,
4636 CURLFTPMETHOD_MULTICWD
);
4639 case 2: /* CURLFTPMETHOD_NOCWD */
4640 result
= curl_easy_setopt(conn
->connection
,
4641 CURLOPT_FTP_FILEMETHOD
,
4642 CURLFTPMETHOD_NOCWD
);
4645 case 3: /* CURLFTPMETHOD_SINGLECWD */
4646 result
= curl_easy_setopt(conn
->connection
,
4647 CURLOPT_FTP_FILEMETHOD
,
4648 CURLFTPMETHOD_SINGLECWD
);
4651 failwith("Invalid FTP_FILEMETHOD value");
4655 if (result
!= CURLE_OK
)
4656 raiseError(conn
, result
);
4660 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4661 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4665 static void handleLocalPort(Connection
*conn
, value option
)
4667 #if HAVE_DECL_CURLOPT_LOCALPORT
4669 CURLcode result
= CURLE_OK
;
4671 result
= curl_easy_setopt(conn
->connection
,
4675 if (result
!= CURLE_OK
)
4676 raiseError(conn
, result
);
4680 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4681 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4685 static void handleLocalPortRange(Connection
*conn
, value option
)
4687 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4689 CURLcode result
= CURLE_OK
;
4691 result
= curl_easy_setopt(conn
->connection
,
4692 CURLOPT_LOCALPORTRANGE
,
4695 if (result
!= CURLE_OK
)
4696 raiseError(conn
, result
);
4700 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4701 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4705 static void handleConnectOnly(Connection
*conn
, value option
)
4707 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4709 CURLcode result
= CURLE_OK
;
4711 result
= curl_easy_setopt(conn
->connection
,
4712 CURLOPT_CONNECT_ONLY
,
4715 if (result
!= CURLE_OK
)
4716 raiseError(conn
, result
);
4720 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4721 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4725 static void handleMaxSendSpeedLarge(Connection
*conn
, value option
)
4727 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4729 CURLcode result
= CURLE_OK
;
4731 result
= curl_easy_setopt(conn
->connection
,
4732 CURLOPT_MAX_SEND_SPEED_LARGE
,
4735 if (result
!= CURLE_OK
)
4736 raiseError(conn
, result
);
4740 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4741 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4745 static void handleMaxRecvSpeedLarge(Connection
*conn
, value option
)
4747 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4749 CURLcode result
= CURLE_OK
;
4751 result
= curl_easy_setopt(conn
->connection
,
4752 CURLOPT_MAX_RECV_SPEED_LARGE
,
4755 if (result
!= CURLE_OK
)
4756 raiseError(conn
, result
);
4760 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4761 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4765 static void handleFTPAlternativeToUser(Connection
*conn
, value option
)
4767 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4769 CURLcode result
= CURLE_OK
;
4771 Store_field(conn
->ocamlValues
, OcamlFTPAlternativeToUser
, option
);
4773 if (conn
->ftpAlternativeToUser
!= NULL
)
4774 free(conn
->ftpAlternativeToUser
);
4776 conn
->ftpAlternativeToUser
= strdup(String_val(option
));
4778 result
= curl_easy_setopt(conn
->connection
,
4779 CURLOPT_FTP_ALTERNATIVE_TO_USER
,
4780 conn
->ftpAlternativeToUser
);
4782 if (result
!= CURLE_OK
)
4783 raiseError(conn
, result
);
4787 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4788 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4792 static void handleSSLSessionIdCache(Connection
*conn
, value option
)
4794 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4796 CURLcode result
= CURLE_OK
;
4798 result
= curl_easy_setopt(conn
->connection
,
4799 CURLOPT_SSL_SESSIONID_CACHE
,
4802 if (result
!= CURLE_OK
)
4803 raiseError(conn
, result
);
4807 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4808 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4812 static void handleSSHAuthTypes(Connection
*conn
, value option
)
4814 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4816 CAMLlocal1(listIter
);
4817 CURLcode result
= CURLE_OK
;
4818 long authTypes
= CURLSSH_AUTH_NONE
;
4822 while (!Is_long(listIter
))
4824 switch (Long_val(Field(listIter
, 0)))
4826 case 0: /* CURLSSH_AUTH_ANY */
4827 authTypes
|= CURLSSH_AUTH_ANY
;
4830 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4831 authTypes
|= CURLSSH_AUTH_PUBLICKEY
;
4834 case 2: /* CURLSSH_AUTH_PASSWORD */
4835 authTypes
|= CURLSSH_AUTH_PASSWORD
;
4838 case 3: /* CURLSSH_AUTH_HOST */
4839 authTypes
|= CURLSSH_AUTH_HOST
;
4842 case 4: /* CURLSSH_AUTH_KEYBOARD */
4843 authTypes
|= CURLSSH_AUTH_KEYBOARD
;
4847 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4851 listIter
= Field(listIter
, 1);
4854 result
= curl_easy_setopt(conn
->connection
,
4855 CURLOPT_SSH_AUTH_TYPES
,
4858 if (result
!= CURLE_OK
)
4859 raiseError(conn
, result
);
4863 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4864 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4868 static void handleSSHPublicKeyFile(Connection
*conn
, value option
)
4870 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4872 CURLcode result
= CURLE_OK
;
4874 Store_field(conn
->ocamlValues
, OcamlSSHPublicKeyFile
, option
);
4876 if (conn
->sshPublicKeyFile
!= NULL
)
4877 free(conn
->sshPublicKeyFile
);
4879 conn
->sshPublicKeyFile
= strdup(String_val(option
));
4881 result
= curl_easy_setopt(conn
->connection
,
4882 CURLOPT_SSH_PUBLIC_KEYFILE
,
4883 conn
->sshPublicKeyFile
);
4885 if (result
!= CURLE_OK
)
4886 raiseError(conn
, result
);
4890 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4891 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4895 static void handleSSHPrivateKeyFile(Connection
*conn
, value option
)
4897 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4899 CURLcode result
= CURLE_OK
;
4901 Store_field(conn
->ocamlValues
, OcamlSSHPrivateKeyFile
, option
);
4903 if (conn
->sshPrivateKeyFile
!= NULL
)
4904 free(conn
->sshPrivateKeyFile
);
4906 conn
->sshPrivateKeyFile
= strdup(String_val(option
));
4908 result
= curl_easy_setopt(conn
->connection
,
4909 CURLOPT_SSH_PRIVATE_KEYFILE
,
4910 conn
->sshPrivateKeyFile
);
4912 if (result
!= CURLE_OK
)
4913 raiseError(conn
, result
);
4917 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4918 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4922 static void handleFTPSSLCCC(Connection
*conn
, value option
)
4924 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4926 CURLcode result
= CURLE_OK
;
4928 switch (Long_val(option
))
4930 case 0: /* CURLFTPSSL_CCC_NONE */
4931 result
= curl_easy_setopt(conn
->connection
,
4932 CURLOPT_FTP_SSL_CCC
,
4933 CURLFTPSSL_CCC_NONE
);
4936 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4937 result
= curl_easy_setopt(conn
->connection
,
4938 CURLOPT_FTP_SSL_CCC
,
4939 CURLFTPSSL_CCC_PASSIVE
);
4942 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4943 result
= curl_easy_setopt(conn
->connection
,
4944 CURLOPT_FTP_SSL_CCC
,
4945 CURLFTPSSL_CCC_ACTIVE
);
4949 failwith("Invalid FTPSSL_CCC value");
4953 if (result
!= CURLE_OK
)
4954 raiseError(conn
, result
);
4958 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4959 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4963 static void handleTimeoutMS(Connection
*conn
, value option
)
4965 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4967 CURLcode result
= CURLE_OK
;
4969 result
= curl_easy_setopt(conn
->connection
,
4973 if (result
!= CURLE_OK
)
4974 raiseError(conn
, result
);
4978 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4979 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4983 static void handleConnectTimeoutMS(Connection
*conn
, value option
)
4985 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4987 CURLcode result
= CURLE_OK
;
4989 result
= curl_easy_setopt(conn
->connection
,
4990 CURLOPT_CONNECTTIMEOUT_MS
,
4993 if (result
!= CURLE_OK
)
4994 raiseError(conn
, result
);
4998 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4999 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
5003 static void handleHTTPTransferDecoding(Connection
*conn
, value option
)
5005 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
5007 CURLcode result
= CURLE_OK
;
5009 result
= curl_easy_setopt(conn
->connection
,
5010 CURLOPT_HTTP_TRANSFER_DECODING
,
5013 if (result
!= CURLE_OK
)
5014 raiseError(conn
, result
);
5018 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
5019 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
5023 static void handleHTTPContentDecoding(Connection
*conn
, value option
)
5025 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
5027 CURLcode result
= CURLE_OK
;
5029 result
= curl_easy_setopt(conn
->connection
,
5030 CURLOPT_HTTP_CONTENT_DECODING
,
5033 if (result
!= CURLE_OK
)
5034 raiseError(conn
, result
);
5038 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5039 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5043 static void handleNewFilePerms(Connection
*conn
, value option
)
5045 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5047 CURLcode result
= CURLE_OK
;
5049 result
= curl_easy_setopt(conn
->connection
,
5050 CURLOPT_NEW_FILE_PERMS
,
5053 if (result
!= CURLE_OK
)
5054 raiseError(conn
, result
);
5058 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5059 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5063 static void handleNewDirectoryPerms(Connection
*conn
, value option
)
5065 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5067 CURLcode result
= CURLE_OK
;
5069 result
= curl_easy_setopt(conn
->connection
,
5070 CURLOPT_NEW_DIRECTORY_PERMS
,
5073 if (result
!= CURLE_OK
)
5074 raiseError(conn
, result
);
5078 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5079 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5083 static void handlePost301(Connection
*conn
, value option
)
5085 #if HAVE_DECL_CURLOPT_POST301
5087 CURLcode result
= CURLE_OK
;
5089 result
= curl_easy_setopt(conn
->connection
,
5093 if (result
!= CURLE_OK
)
5094 raiseError(conn
, result
);
5098 #warning "libcurl does not implement CURLOPT_POST301"
5099 failwith("libcurl does not implement CURLOPT_POST301");
5103 static void handleSSHHostPublicKeyMD5(Connection
*conn
, value option
)
5105 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5107 CURLcode result
= CURLE_OK
;
5109 Store_field(conn
->ocamlValues
, OcamlSSHHostPublicKeyMD5
, option
);
5111 if (conn
->sshHostPublicKeyMD5
!= NULL
)
5112 free(conn
->sshHostPublicKeyMD5
);
5114 conn
->sshHostPublicKeyMD5
= strdup(String_val(option
));
5116 result
= curl_easy_setopt(conn
->connection
,
5117 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
,
5118 conn
->sshHostPublicKeyMD5
);
5120 if (result
!= CURLE_OK
)
5121 raiseError(conn
, result
);
5125 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5126 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5130 static void handleCopyPostFields(Connection
*conn
, value option
)
5132 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5134 CURLcode result
= CURLE_OK
;
5136 Store_field(conn
->ocamlValues
, OcamlCopyPostFields
, option
);
5138 if (conn
->copyPostFields
!= NULL
)
5139 free(conn
->copyPostFields
);
5141 conn
->copyPostFields
= strdup(String_val(option
));
5143 result
= curl_easy_setopt(conn
->connection
,
5144 CURLOPT_COPYPOSTFIELDS
,
5145 conn
->copyPostFields
);
5147 if (result
!= CURLE_OK
)
5148 raiseError(conn
, result
);
5152 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5153 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5157 static void handleProxyTransferMode(Connection
*conn
, value option
)
5159 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5161 CURLcode result
= CURLE_OK
;
5163 result
= curl_easy_setopt(conn
->connection
,
5164 CURLOPT_PROXY_TRANSFER_MODE
,
5167 if (result
!= CURLE_OK
)
5168 raiseError(conn
, result
);
5172 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5173 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5177 static void handleSeekFunction(Connection
*conn
, value option
)
5179 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5181 CURLcode result
= CURLE_OK
;
5183 if (Tag_val(option
) == Closure_tag
)
5184 Store_field(conn
->ocamlValues
, OcamlSeekFunctionCallback
, option
);
5186 failwith("Not a proper closure");
5188 result
= curl_easy_setopt(conn
->connection
,
5189 CURLOPT_SEEKFUNCTION
,
5192 if (result
!= CURLE_OK
)
5193 raiseError(conn
, result
);
5195 result
= curl_easy_setopt(conn
->connection
,
5199 if (result
!= CURLE_OK
)
5200 raiseError(conn
, result
);
5204 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5205 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5210 ** curl_easy_setopt helper function
5213 CAMLprim
void helper_curl_easy_setopt(value conn
, value option
)
5215 CAMLparam2(conn
, option
);
5217 Connection
*connection
= Connection_val(conn
);
5219 checkConnection(connection
);
5221 if (Is_long(option
))
5225 sprintf(error
, "Unimplemented Option: %s",
5226 findOption(unimplementedOptionMap
,
5227 (CURLoption
)(Long_val(option
))));
5232 if (!Is_block(option
))
5233 failwith("Not a block");
5235 if (Wosize_val(option
) < 1)
5236 failwith("Insufficient data in block");
5238 data
= Field(option
, 0);
5240 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5241 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5244 failwith("Invalid CURLOPT Option");
5250 ** curl_easy_perform helper function
5253 CAMLprim
void helper_curl_easy_perform(value conn
)
5256 CURLcode result
= CURLE_OK
;
5257 Connection
*connection
= Connection_val(conn
);
5259 checkConnection(connection
);
5261 enter_blocking_section();
5262 result
= curl_easy_perform(connection
->connection
);
5263 leave_blocking_section();
5265 if (result
!= CURLE_OK
)
5266 raiseError(connection
, result
);
5272 ** curl_easy_cleanup helper function
5275 CAMLprim
void helper_curl_easy_cleanup(value conn
)
5278 Connection
*connection
= Connection_val(conn
);
5280 checkConnection(connection
);
5282 removeConnection(connection
);
5288 ** curl_easy_duphandle helper function
5291 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5295 Connection
*connection
= Connection_val(conn
);
5297 checkConnection(connection
);
5299 result
= alloc(1, Abstract_tag
);
5300 Field(result
, 0) = (value
)duplicateConnection(connection
);
5306 ** curl_easy_getinfo helper function
5309 enum GetInfoResultType
{
5310 StringValue
, LongValue
, DoubleValue
, StringListValue
5313 value
convertStringList(struct curl_slist
*slist
)
5316 CAMLlocal3(result
, current
, next
);
5317 struct curl_slist
*p
= slist
;
5319 result
= Val_int(0);
5320 current
= Val_int(0);
5325 next
= alloc_tuple(2);
5326 Field(next
, 0) = copy_string(p
->data
);
5327 Field(next
, 1) = Val_int(0);
5329 if (result
== Val_int(0))
5332 if (current
!= Val_int(0))
5333 Field(current
, 1) = next
;
5340 curl_slist_free_all(slist
);
5345 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5347 CAMLparam2(conn
, option
);
5349 CURLcode curlResult
;
5350 Connection
*connection
= Connection_val(conn
);
5351 enum GetInfoResultType resultType
;
5352 char *strValue
= NULL
;
5355 struct curl_slist
*stringListValue
= NULL
;
5357 checkConnection(connection
);
5359 switch(Long_val(option
))
5361 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5362 case 0: /* CURLINFO_EFFECTIVE_URL */
5363 resultType
= StringValue
;
5365 curlResult
= curl_easy_getinfo(connection
->connection
,
5366 CURLINFO_EFFECTIVE_URL
,
5370 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5373 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5374 case 1: /* CURLINFO_HTTP_CODE */
5375 case 2: /* CURLINFO_RESPONSE_CODE */
5376 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5377 resultType
= LongValue
;
5379 curlResult
= curl_easy_getinfo(connection
->connection
,
5380 CURLINFO_RESPONSE_CODE
,
5383 resultType
= LongValue
;
5385 curlResult
= curl_easy_getinfo(connection
->connection
,
5392 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5393 case 3: /* CURLINFO_TOTAL_TIME */
5394 resultType
= DoubleValue
;
5396 curlResult
= curl_easy_getinfo(connection
->connection
,
5397 CURLINFO_TOTAL_TIME
,
5402 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5403 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5404 resultType
= DoubleValue
;
5406 curlResult
= curl_easy_getinfo(connection
->connection
,
5407 CURLINFO_NAMELOOKUP_TIME
,
5412 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5413 case 5: /* CURLINFO_CONNECT_TIME */
5414 resultType
= DoubleValue
;
5416 curlResult
= curl_easy_getinfo(connection
->connection
,
5417 CURLINFO_CONNECT_TIME
,
5422 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5423 case 6: /* CURLINFO_PRETRANSFER_TIME */
5424 resultType
= DoubleValue
;
5426 curlResult
= curl_easy_getinfo(connection
->connection
,
5427 CURLINFO_PRETRANSFER_TIME
,
5432 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5433 case 7: /* CURLINFO_SIZE_UPLOAD */
5434 resultType
= DoubleValue
;
5436 curlResult
= curl_easy_getinfo(connection
->connection
,
5437 CURLINFO_SIZE_UPLOAD
,
5442 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5443 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5444 resultType
= DoubleValue
;
5446 curlResult
= curl_easy_getinfo(connection
->connection
,
5447 CURLINFO_SIZE_DOWNLOAD
,
5452 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5453 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5454 resultType
= DoubleValue
;
5456 curlResult
= curl_easy_getinfo(connection
->connection
,
5457 CURLINFO_SPEED_DOWNLOAD
,
5462 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5463 case 10: /* CURLINFO_SPEED_UPLOAD */
5464 resultType
= DoubleValue
;
5466 curlResult
= curl_easy_getinfo(connection
->connection
,
5467 CURLINFO_SPEED_UPLOAD
,
5473 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5474 case 11: /* CURLINFO_HEADER_SIZE */
5475 resultType
= LongValue
;
5477 curlResult
= curl_easy_getinfo(connection
->connection
,
5478 CURLINFO_HEADER_SIZE
,
5483 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5484 case 12: /* CURLINFO_REQUEST_SIZE */
5485 resultType
= LongValue
;
5487 curlResult
= curl_easy_getinfo(connection
->connection
,
5488 CURLINFO_REQUEST_SIZE
,
5493 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5494 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5495 resultType
= LongValue
;
5497 curlResult
= curl_easy_getinfo(connection
->connection
,
5498 CURLINFO_SSL_VERIFYRESULT
,
5503 #if HAVE_DECL_CURLINFO_FILETIME
5504 case 14: /* CURLINFO_FILETIME */
5505 resultType
= DoubleValue
;
5507 curlResult
= curl_easy_getinfo(connection
->connection
,
5513 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5514 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5515 resultType
= DoubleValue
;
5517 curlResult
= curl_easy_getinfo(connection
->connection
,
5518 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5523 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5524 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5525 resultType
= DoubleValue
;
5527 curlResult
= curl_easy_getinfo(connection
->connection
,
5528 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5533 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5534 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5535 resultType
= DoubleValue
;
5537 curlResult
= curl_easy_getinfo(connection
->connection
,
5538 CURLINFO_STARTTRANSFER_TIME
,
5543 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5544 case 18: /* CURLINFO_CONTENT_TYPE */
5545 resultType
= StringValue
;
5547 curlResult
= curl_easy_getinfo(connection
->connection
,
5548 CURLINFO_CONTENT_TYPE
,
5553 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5554 case 19: /* CURLINFO_REDIRECT_TIME */
5555 resultType
= DoubleValue
;
5557 curlResult
= curl_easy_getinfo(connection
->connection
,
5558 CURLINFO_REDIRECT_TIME
,
5563 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5564 case 20: /* CURLINFO_REDIRECT_COUNT */
5565 resultType
= LongValue
;
5567 curlResult
= curl_easy_getinfo(connection
->connection
,
5568 CURLINFO_REDIRECT_COUNT
,
5573 #if HAVE_DECL_CURLINFO_PRIVATE
5574 case 21: /* CURLINFO_PRIVATE */
5575 resultType
= StringValue
;
5577 curlResult
= curl_easy_getinfo(connection
->connection
,
5583 #if HAVE_DECL_CURLINFO_HTTP_CONNECT_CODE
5584 case 22: /* CURLINFO_HTTP_CONNECT_CODE */
5585 resultType
= LongValue
;
5587 curlResult
= curl_easy_getinfo(connection
->connection
,
5588 CURLINFO_HTTP_CONNECT_CODE
,
5593 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5594 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5595 resultType
= LongValue
;
5597 curlResult
= curl_easy_getinfo(connection
->connection
,
5598 CURLINFO_HTTPAUTH_AVAIL
,
5603 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5604 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5605 resultType
= LongValue
;
5607 curlResult
= curl_easy_getinfo(connection
->connection
,
5608 CURLINFO_PROXYAUTH_AVAIL
,
5613 #if HAVE_DECL_CURLINFO_OS_ERRNO
5614 case 25: /* CURLINFO_OS_ERRNO */
5615 resultType
= LongValue
;
5617 curlResult
= curl_easy_getinfo(connection
->connection
,
5623 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5624 case 26: /* CURLINFO_NUM_CONNECTS */
5625 resultType
= LongValue
;
5627 curlResult
= curl_easy_getinfo(connection
->connection
,
5628 CURLINFO_NUM_CONNECTS
,
5633 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5634 case 27: /* CURLINFO_SSL_ENGINES */
5635 resultType
= StringListValue
;
5637 curlResult
= curl_easy_getinfo(connection
->connection
,
5638 CURLINFO_SSL_ENGINES
,
5643 #if HAVE_DECL_CURLINFO_COOKIELIST
5644 case 28: /* CURLINFO_COOKIELIST */
5645 resultType
= StringListValue
;
5647 curlResult
= curl_easy_getinfo(connection
->connection
,
5648 CURLINFO_COOKIELIST
,
5653 #if HAVE_DECL_CURLINFO_LASTSOCKET
5654 case 29: /* CURLINFO_LASTSOCKET */
5655 resultType
= LongValue
;
5657 curlResult
= curl_easy_getinfo(connection
->connection
,
5658 CURLINFO_LASTSOCKET
,
5664 failwith("Invalid CURLINFO Option");
5668 if (curlResult
!= CURLE_OK
)
5669 raiseError(connection
, curlResult
);
5674 result
= alloc(1, StringValue
);
5675 Field(result
, 0) = copy_string(strValue
);
5679 result
= alloc(1, LongValue
);
5680 Field(result
, 0) = Val_long(longValue
);
5684 result
= alloc(1, DoubleValue
);
5685 Field(result
, 0) = copy_double(doubleValue
);
5688 case StringListValue
:
5689 result
= alloc(1, StringListValue
);
5690 Field(result
, 0) = convertStringList(stringListValue
);
5698 ** curl_escape helper function
5701 CAMLprim value
helper_curl_escape(value str
)
5707 curlResult
= curl_escape(String_val(str
), string_length(str
));
5708 result
= copy_string(curlResult
);
5715 ** curl_unescape helper function
5718 CAMLprim value
helper_curl_unescape(value str
)
5724 curlResult
= curl_unescape(String_val(str
), string_length(str
));
5725 result
= copy_string(curlResult
);
5732 ** curl_getdate helper function
5735 CAMLprim value
helper_curl_getdate(value str
, value now
)
5737 CAMLparam2(str
, now
);
5742 curlNow
= (time_t)Double_val(now
);
5743 curlResult
= curl_getdate(String_val(str
), &curlNow
);
5744 result
= copy_double((double)curlResult
);
5750 ** curl_version helper function
5753 CAMLprim value
helper_curl_version(void)
5759 str
= curl_version();
5760 result
= copy_string(str
);
5766 * Curl multi stack support
5768 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5769 * Other exported functions are prefixed with caml_curlm_, some of them
5770 * can/should be decomposed into smaller parts.
5773 #define CURLM_val(v) ((CURLM*)v)
5774 #define Val_CURLM(h) ((value)h)
5776 CAMLprim value
caml_curl_multi_init(value unit
)
5781 h
= curl_multi_init();
5784 failwith("caml_curl_multi_init");
5786 CAMLreturn(Val_CURLM(h
));
5789 CAMLprim value
caml_curl_multi_cleanup(value handle
)
5793 if (CURLM_OK
!= curl_multi_cleanup(CURLM_val(handle
)))
5794 failwith("caml_curl_multi_cleanup");
5796 CAMLreturn(Val_unit
);
5799 static CURL
* curlm_remove_finished(CURLM
* multi_handle
)
5801 int msgs_in_queue
= 0;
5805 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
5806 if (NULL
== msg
) return NULL
;
5807 if (CURLMSG_DONE
== msg
->msg
)
5809 CURL
* easy_handle
= msg
->easy_handle
;
5810 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
5812 //failwith("curlm_remove_finished");
5819 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
5821 CAMLparam1(v_multi
);
5824 CURLM
* multi_handle
;
5826 multi_handle
= CURLM_val(v_multi
);
5828 caml_enter_blocking_section();
5829 handle
= curlm_remove_finished(multi_handle
);
5830 caml_leave_blocking_section();
5834 CAMLreturn(Val_none
);
5839 v_easy
= alloc(1, Abstract_tag
);
5840 Store_field(v_easy
, 0, (value
)findConnection(handle
));
5841 CAMLreturn(Val_some(v_easy
));
5845 static int curlm_wait_data(CURLM
* multi_handle
)
5847 struct timeval timeout
;
5858 /* set a suitable timeout */
5860 timeout
.tv_usec
= 0;
5862 /* get file descriptors from the transfers */
5863 CURLMcode ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
5865 if (ret
== CURLM_OK
&& maxfd
>= 0)
5867 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
5868 if (-1 != rc
) return 0;
5869 //printf("select error\n");
5873 //printf("curl_multi_fdset error\n");
5878 CAMLprim value
caml_curlm_wait_data(value v_multi
)
5880 CAMLparam1(v_multi
);
5884 h
= CURLM_val(v_multi
);
5886 caml_enter_blocking_section();
5887 ret
= curlm_wait_data(h
);
5888 caml_leave_blocking_section();
5890 CAMLreturn(Val_bool(0 == ret
));
5893 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
5895 CAMLparam2(v_multi
,v_easy
);
5897 if (CURLM_OK
!= curl_multi_add_handle(CURLM_val(v_multi
), Connection_val(v_easy
)->connection
))
5898 failwith("caml_curl_multi_add_handle");
5900 CAMLreturn(Val_unit
);
5903 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
5905 CAMLparam1(v_multi
);
5907 int still_running
= 0;
5909 h
= CURLM_val(v_multi
);
5911 caml_enter_blocking_section();
5912 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
5913 caml_leave_blocking_section();
5915 CAMLreturn(Val_int(still_running
));