4 *** Copyright (c) 2003-2008, Lars Nilsson, <lars@quantumchamaeleon.com>
11 #include <curl/curl.h>
13 #include <caml/alloc.h>
14 #include <caml/memory.h>
15 #include <caml/mlvalues.h>
16 #include <caml/callback.h>
17 #include <caml/fail.h>
18 #include <caml/custom.h>
23 #warning "No config file given."
32 void leave_blocking_section(void);
33 void enter_blocking_section(void);
35 #define Val_none Val_int(0)
42 some
= caml_alloc(1, 0);
43 Store_field( some
, 0, v
);
47 typedef struct Connection Connection
;
48 typedef struct ConnectionList ConnectionList
;
50 #define Connection_val(v) ((Connection *)Field(v, 0))
63 OcamlProgressCallback
,
67 OcamlSeekFunctionCallback
,
99 OcamlFTPAlternativeToUser
,
100 OcamlSSHPublicKeyFile
,
101 OcamlSSHPrivateKeyFile
,
102 OcamlSSHHostPublicKeyMD5
,
105 /* Not used, last for size */
129 struct curl_slist
*httpHeader
;
130 struct curl_httppost
*httpPostFirst
;
131 struct curl_httppost
*httpPostLast
;
132 struct curl_slist
*httpPostStrings
;
140 struct curl_slist
*quote
;
141 struct curl_slist
*postQuote
;
152 struct curl_slist
*http200Aliases
;
156 char *ftpAlternativeToUser
;
157 char *sshPublicKeyFile
;
158 char *sshPrivateKeyFile
;
159 char *sshHostPublicKeyMD5
;
160 char *copyPostFields
;
163 struct ConnectionList
169 static ConnectionList connectionList
= {NULL
, NULL
};
171 typedef struct CURLErrorMapping CURLErrorMapping
;
173 struct CURLErrorMapping
179 CURLErrorMapping errorMap
[] =
181 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
182 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL
},
184 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
186 #if HAVE_DECL_CURLE_FAILED_INIT
187 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT
},
189 {"CURLE_FAILED_INIT", -1},
191 #if HAVE_DECL_CURLE_URL_MALFORMAT
192 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT
},
194 {"CURLE_URL_MALFORMAT", -1},
196 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
197 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER
},
199 {"CURLE_URL_MALFORMAT_USER", -1},
201 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
202 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY
},
204 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
206 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
207 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST
},
209 {"CURLE_COULDNT_RESOLVE_HOST", -1},
211 #if HAVE_DECL_CURLE_COULDNT_CONNECT
212 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT
},
214 {"CURLE_COULDNT_CONNECT", -1},
216 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
217 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY
},
219 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
221 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
222 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED
},
224 {"CURLE_FTP_ACCESS_DENIED", -1},
226 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
227 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT
},
229 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
231 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
232 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY
},
234 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
236 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
237 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY
},
239 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
241 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
242 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY
},
244 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
246 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
247 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT
},
249 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
251 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
252 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST
},
254 {"CURLE_FTP_CANT_GET_HOST", -1},
256 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
257 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT
},
259 {"CURLE_FTP_CANT_RECONNECT", -1},
261 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
262 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY
},
264 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
266 #if HAVE_DECL_CURLE_PARTIAL_FILE
267 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE
},
269 {"CURLE_PARTIAL_FILE", -1},
271 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
272 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE
},
274 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
276 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
277 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR
},
279 {"CURLE_FTP_WRITE_ERROR", -1},
281 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
282 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR
},
284 {"CURLE_FTP_QUOTE_ERROR", -1},
286 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
287 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND
},
289 {"CURLE_HTTP_NOT_FOUND", -1},
291 #if HAVE_DECL_CURLE_WRITE_ERROR
292 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR
},
294 {"CURLE_WRITE_ERROR", -1},
296 #if HAVE_DECL_CURLE_MALFORMAT_USER
297 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER
},
299 {"CURLE_MALFORMAT_USER", -1},
301 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
302 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE
},
304 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
306 #if HAVE_DECL_CURLE_READ_ERROR
307 {"CURLE_READ_ERROR", CURLE_READ_ERROR
},
309 {"CURLE_READ_ERROR", -1},
311 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
312 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY
},
314 {"CURLE_OUT_OF_MEMORY", -1},
316 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
317 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED
},
319 {"CURLE_OPERATION_TIMEOUTED", -1},
321 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
322 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII
},
324 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
326 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
327 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED
},
329 {"CURLE_FTP_PORT_FAILED", -1},
331 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
332 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST
},
334 {"CURLE_FTP_COULDNT_USE_REST", -1},
336 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
337 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE
},
339 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
341 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
342 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR
},
344 {"CURLE_HTTP_RANGE_ERROR", -1},
346 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
347 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR
},
349 {"CURLE_HTTP_POST_ERROR", -1},
351 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
352 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR
},
354 {"CURLE_SSL_CONNECT_ERROR", -1},
356 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
357 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME
},
359 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
361 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
362 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE
},
364 {"CURLE_FILE_COULDNT_READ_FILE", -1},
366 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
367 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND
},
369 {"CURLE_LDAP_CANNOT_BIND", -1},
371 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
372 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED
},
374 {"CURLE_LDAP_SEARCH_FAILED", -1},
376 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
377 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND
},
379 {"CURLE_LIBRARY_NOT_FOUND", -1},
381 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
382 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND
},
384 {"CURLE_FUNCTION_NOT_FOUND", -1},
386 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
387 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK
},
389 {"CURLE_ABORTED_BY_CALLBACK", -1},
391 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
392 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT
},
394 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
396 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
397 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER
},
399 {"CURLE_BAD_CALLING_ORDER", -1},
401 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
402 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED
},
404 {"CURLE_HTTP_PORT_FAILED", -1},
406 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
407 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED
},
409 {"CURLE_BAD_PASSWORD_ENTERED", -1},
411 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
412 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS
},
414 {"CURLE_TOO_MANY_REDIRECTS", -1},
416 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
417 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION
},
419 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
421 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
422 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX
},
424 {"CURLE_TELNET_OPTION_SYNTAX", -1},
426 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
427 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE
},
429 {"CURLE_SSL_PEER_CERTIFICATE", -1},
431 #if HAVE_DECL_CURLE_GOT_NOTHING
432 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING
},
434 {"CURLE_GOT_NOTHING", -1},
436 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
437 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND
},
439 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
441 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
442 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED
},
444 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
446 #if HAVE_DECL_CURLE_SEND_ERROR
447 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR
},
449 {"CURLE_SEND_ERROR", -1},
451 #if HAVE_DECL_CURLE_RECV_ERROR
452 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR
},
454 {"CURLE_RECV_ERROR", -1},
456 #if HAVE_DECL_CURLE_SHARE_IN_USE
457 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE
},
459 {"CURLE_SHARE_IN_USE", -1},
461 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
462 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM
},
464 {"CURLE_SSL_CERTPROBLEN", -1},
466 #if HAVE_DECL_CURLE_SSL_CIPHER
467 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER
},
469 {"CURLE_SSL_CIPHER", -1},
471 #if HAVE_DECL_CURLE_SSL_CACERT
472 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT
},
474 {"CURLE_SSL_CACERT", -1},
476 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
477 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING
},
479 {"CURLE_BAD_CONTENT_ENCODING", -1},
481 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
482 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL
},
484 {"CURLE_LDAP_INVALID_URL", -1},
486 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
487 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED
},
489 {"CURLE_FILESIZE_EXCEEDED", -1},
491 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
492 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED
},
494 {"CURLE_FTP_SSL_FAILED", -1},
496 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
497 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND
},
499 {"CURLE_SEND_FAIL_REWIND", -1},
501 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
502 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED
},
504 {"CURLE_SSL_ENGINE_INITFAILED", -1},
506 #if HAVE_DECL_CURLE_LOGIN_DENIED
507 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED
},
509 {"CURLE_LOGIN_DENIED", -1},
511 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
512 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND
},
514 {"CURLE_TFTP_NOTFOUND", -1},
516 #if HAVE_DECL_CURLE_TFTP_PERM
517 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM
},
519 {"CURLE_TFTP_PERM", -1},
521 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
522 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL
},
524 {"CURLE_REMOTE_DISK_FULL", -1},
526 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
527 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL
},
529 {"CURLE_TFTP_ILLEGAL", -1},
531 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
532 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID
},
534 {"CURLE_TFTP_UNKNOWNID", -1},
536 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
537 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS
},
539 {"CURLE_REMOTE_FILE_EXISTS", -1},
541 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
542 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER
},
544 {"CURLE_TFTP_NOSUCHUSER", -1},
546 #if HAVE_DECL_CURLE_CONV_FAILED
547 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED
},
549 {"CURLE_CONV_FAILED", -1},
551 #if HAVE_DECL_CURLE_CONV_REQUIRED
552 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED
},
554 {"CURLE_CONV_REQUIRED", -1},
556 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
557 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE
},
559 {"CURLE_SSL_CACERT_BADFILE", -1},
561 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
562 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND
},
564 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
566 #if HAVE_DECL_CURLE_SSH
567 {"CURLE_SSH", CURLE_SSH
},
571 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
572 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED
},
574 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
576 #if HAVE_DECL_CURLE_AGAIN
577 {"CURLE_AGAIN", CURLE_AGAIN
},
581 {"CURLE_OK", CURLE_OK
},
585 typedef struct CURLOptionMapping CURLOptionMapping
;
587 struct CURLOptionMapping
589 void (*optionHandler
)(Connection
*, value
);
594 CURLOptionMapping unimplementedOptionMap
[] =
596 {NULL
, "CURLOPT_STDERR", CURLOPT_STDERR
},
600 static void handleWriteFunction(Connection
*, value
);
601 static void handleReadFunction(Connection
*, value
);
602 static void handleInFileSize(Connection
*, value
);
603 static void handleURL(Connection
*, value
);
604 static void handleProxy(Connection
*, value
);
605 static void handleProxyPort(Connection
*, value
);
606 static void handleHTTPProxyTunnel(Connection
*, value
);
607 static void handleVerbose(Connection
*, value
);
608 static void handleHeader(Connection
*, value
);
609 static void handleNoProgress(Connection
*, value
);
610 static void handleNoSignal(Connection
*, value
);
611 static void handleNoBody(Connection
*, value
);
612 static void handleFailOnError(Connection
*, value
);
613 static void handleUpload(Connection
*, value
);
614 static void handlePost(Connection
*, value
);
615 static void handleFTPListOnly(Connection
*, value
);
616 static void handleFTPAppend(Connection
*, value
);
617 static void handleNETRC(Connection
*, value
);
618 static void handleEncoding(Connection
*, value
);
619 static void handleFollowLocation(Connection
*, value
);
620 static void handleTransferText(Connection
*, value
);
621 static void handlePut(Connection
*, value
);
622 static void handleUserPwd(Connection
*, value
);
623 static void handleProxyUserPwd(Connection
*, value
);
624 static void handleRange(Connection
*, value
);
625 static void handleErrorBuffer(Connection
*, value
);
626 static void handleTimeout(Connection
*, value
);
627 static void handlePostFields(Connection
*, value
);
628 static void handlePostFieldSize(Connection
*, value
);
629 static void handleReferer(Connection
*, value
);
630 static void handleUserAgent(Connection
*, value
);
631 static void handleFTPPort(Connection
*, value
);
632 static void handleLowSpeedLimit(Connection
*, value
);
633 static void handleLowSpeedTime(Connection
*, value
);
634 static void handleResumeFrom(Connection
*, value
);
635 static void handleCookie(Connection
*, value
);
636 static void handleHTTPHeader(Connection
*, value
);
637 static void handleHTTPPost(Connection
*, value
);
638 static void handleSSLCert(Connection
*, value
);
639 static void handleSSLCertType(Connection
*, value
);
640 static void handleSSLCertPasswd(Connection
*, value
);
641 static void handleSSLKey(Connection
*, value
);
642 static void handleSSLKeyType(Connection
*, value
);
643 static void handleSSLKeyPasswd(Connection
*, value
);
644 static void handleSSLEngine(Connection
*, value
);
645 static void handleSSLEngineDefault(Connection
*, value
);
646 static void handleCRLF(Connection
*, value
);
647 static void handleQuote(Connection
*, value
);
648 static void handlePostQuote(Connection
*, value
);
649 static void handleHeaderFunction(Connection
*, value
);
650 static void handleCookieFile(Connection
*, value
);
651 static void handleSSLVersion(Connection
*, value
);
652 static void handleTimeCondition(Connection
*, value
);
653 static void handleTimeValue(Connection
*, value
);
654 static void handleCustomRequest(Connection
*, value
);
655 static void handleInterface(Connection
*, value
);
656 static void handleKRB4Level(Connection
*, value
);
657 static void handleProgressFunction(Connection
*, value
);
658 static void handleSSLVerifyPeer(Connection
*, value
);
659 static void handleCAInfo(Connection
*, value
);
660 static void handleCAPath(Connection
*, value
);
661 static void handleFileTime(Connection
*, value
);
662 static void handleMaxRedirs(Connection
*, value
);
663 static void handleMaxConnects(Connection
*, value
);
664 static void handleClosePolicy(Connection
*, value
);
665 static void handleFreshConnect(Connection
*, value
);
666 static void handleForbidReuse(Connection
*, value
);
667 static void handleRandomFile(Connection
*, value
);
668 static void handleEGDSocket(Connection
*, value
);
669 static void handleConnectTimeout(Connection
*, value
);
670 static void handleHTTPGet(Connection
*, value
);
671 static void handleSSLVerifyHost(Connection
*, value
);
672 static void handleCookieJar(Connection
*, value
);
673 static void handleSSLCipherList(Connection
*, value
);
674 static void handleHTTPVersion(Connection
*, value
);
675 static void handleFTPUseEPSV(Connection
*, value
);
676 static void handleDNSCacheTimeout(Connection
*, value
);
677 static void handleDNSUseGlobalCache(Connection
*, value
);
678 static void handleDebugFunction(Connection
*, value
);
679 static void handlePrivate(Connection
*, value
);
680 static void handleHTTP200Aliases(Connection
*, value
);
681 static void handleUnrestrictedAuth(Connection
*, value
);
682 static void handleFTPUseEPRT(Connection
*, value
);
683 static void handleHTTPAuth(Connection
*, value
);
684 static void handleFTPCreateMissingDirs(Connection
*, value
);
685 static void handleProxyAuth(Connection
*, value
);
686 static void handleFTPResponseTimeout(Connection
*, value
);
687 static void handleIPResolve(Connection
*, value
);
688 static void handleMaxFileSize(Connection
*, value
);
689 static void handleInFileSizeLarge(Connection
*, value
);
690 static void handleResumeFromLarge(Connection
*, value
);
691 static void handleMaxFileSizeLarge(Connection
*, value
);
692 static void handleNETRCFile(Connection
*, value
);
693 static void handleFTPSSL(Connection
*, value
);
694 static void handlePostFieldSizeLarge(Connection
*, value
);
695 static void handleTCPNoDelay(Connection
*, value
);
696 static void handleFTPSSLAuth(Connection
*, value
);
697 static void handleIOCTLFunction(Connection
*, value
);
698 static void handleFTPAccount(Connection
*, value
);
699 static void handleCookieList(Connection
*, value
);
700 static void handleIgnoreContentLength(Connection
*, value
);
701 static void handleFTPSkipPASVIP(Connection
*, value
);
702 static void handleFTPFileMethod(Connection
*, value
);
703 static void handleLocalPort(Connection
*, value
);
704 static void handleLocalPortRange(Connection
*, value
);
705 static void handleConnectOnly(Connection
*, value
);
706 static void handleMaxSendSpeedLarge(Connection
*, value
);
707 static void handleMaxRecvSpeedLarge(Connection
*, value
);
708 static void handleFTPAlternativeToUser(Connection
*, value
);
709 static void handleSSLSessionIdCache(Connection
*, value
);
710 static void handleSSHAuthTypes(Connection
*, value
);
711 static void handleSSHPublicKeyFile(Connection
*, value
);
712 static void handleSSHPrivateKeyFile(Connection
*, value
);
713 static void handleFTPSSLCCC(Connection
*, value
);
714 static void handleTimeoutMS(Connection
*, value
);
715 static void handleConnectTimeoutMS(Connection
*, value
);
716 static void handleHTTPTransferDecoding(Connection
*, value
);
717 static void handleHTTPContentDecoding(Connection
*, value
);
718 static void handleNewFilePerms(Connection
*, value
);
719 static void handleNewDirectoryPerms(Connection
*, value
);
720 static void handlePost301(Connection
*, value
);
721 static void handleSSHHostPublicKeyMD5(Connection
*, value
);
722 static void handleCopyPostFields(Connection
*, value
);
723 static void handleProxyTransferMode(Connection
*, value
);
724 static void handleSeekFunction(Connection
*, value
);
726 CURLOptionMapping implementedOptionMap
[] =
728 {handleWriteFunction
, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION
},
729 {handleReadFunction
, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION
},
730 {handleInFileSize
, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE
},
731 {handleURL
, "CURLOPT_URL", CURLOPT_URL
},
732 {handleProxy
, "CURLOPT_PROXY", CURLOPT_PROXY
},
733 {handleProxyPort
, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT
},
734 {handleHTTPProxyTunnel
, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL
},
735 {handleVerbose
, "CURLOPT_VERBOSE", CURLOPT_VERBOSE
},
736 {handleHeader
, "CURLOPT_HEADER", CURLOPT_HEADER
},
737 {handleNoProgress
, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS
},
738 #if HAVE_DECL_CURLOPT_NOSIGNAL
739 {handleNoSignal
, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL
},
741 {handleNoSignal
, "CURLOPT_NOSIGNAL", 0},
743 {handleNoBody
, "CURLOPT_NOBODY", CURLOPT_NOBODY
},
744 {handleFailOnError
, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR
},
745 {handleUpload
, "CURLOPT_UPLOAD", CURLOPT_UPLOAD
},
746 {handlePost
, "CURLOPT_POST", CURLOPT_POST
},
747 {handleFTPListOnly
, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY
},
748 {handleFTPAppend
, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND
},
749 {handleNETRC
, "CURLOPT_NETRC", CURLOPT_NETRC
},
750 #if HAVE_DECL_CURLOPT_ENCODING
751 {handleEncoding
, "CURLOPT_ENCODING", CURLOPT_ENCODING
},
753 {handleEncoding
, "CURLOPT_ENCODING", 0},
755 {handleFollowLocation
, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION
},
756 {handleTransferText
, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT
},
757 {handlePut
, "CURLOPT_PUT", CURLOPT_PUT
},
758 {handleUserPwd
, "CURLOPT_USERPWD", CURLOPT_USERPWD
},
759 {handleProxyUserPwd
, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD
},
760 {handleRange
, "CURLOPT_RANGE", CURLOPT_RANGE
},
761 {handleErrorBuffer
, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER
},
762 {handleTimeout
, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT
},
763 {handlePostFields
, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS
},
764 {handlePostFieldSize
, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE
},
765 {handleReferer
, "CURLOPT_REFERER", CURLOPT_REFERER
},
766 {handleUserAgent
, "CURLOPT_USERAGENT", CURLOPT_USERAGENT
},
767 {handleFTPPort
, "CURLOPT_FTPPORT", CURLOPT_FTPPORT
},
768 {handleLowSpeedLimit
, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT
},
769 {handleLowSpeedTime
, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME
},
770 {handleResumeFrom
, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM
},
771 {handleCookie
, "CURLOPT_COOKIE", CURLOPT_COOKIE
},
772 {handleHTTPHeader
, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER
},
773 {handleHTTPPost
, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST
},
774 {handleSSLCert
, "CURLOPT_SSLCERT", CURLOPT_SSLCERT
},
775 {handleSSLCertType
, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE
},
776 {handleSSLCertPasswd
, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD
},
777 {handleSSLKey
, "CURLOPT_SSLKEY", CURLOPT_SSLKEY
},
778 {handleSSLKeyType
, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE
},
779 {handleSSLKeyPasswd
, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD
},
780 {handleSSLEngine
, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE
},
781 {handleSSLEngineDefault
, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT
},
782 {handleCRLF
, "CURLOPT_CRLF", CURLOPT_CRLF
},
783 {handleQuote
, "CURLOPT_QUOTE", CURLOPT_QUOTE
},
784 {handlePostQuote
, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE
},
785 {handleHeaderFunction
, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION
},
786 {handleCookieFile
, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE
},
787 {handleSSLVersion
, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION
},
788 {handleTimeCondition
, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION
},
789 {handleTimeValue
, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE
},
790 {handleCustomRequest
, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST
},
791 {handleInterface
, "CURLOPT_INTERFACE", CURLOPT_INTERFACE
},
792 {handleKRB4Level
, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL
},
793 {handleProgressFunction
, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION
},
794 {handleSSLVerifyPeer
, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER
},
795 {handleCAInfo
, "CURLOPT_CAINFO", CURLOPT_CAINFO
},
796 {handleCAPath
, "CURLOPT_CAPATH", CURLOPT_CAPATH
},
797 {handleFileTime
, "CURLOPT_FILETIME", CURLOPT_FILETIME
},
798 {handleMaxRedirs
, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS
},
799 {handleMaxConnects
, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS
},
800 {handleClosePolicy
, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY
},
801 {handleFreshConnect
, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT
},
802 {handleForbidReuse
, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE
},
803 {handleRandomFile
, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE
},
804 {handleEGDSocket
, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET
},
805 {handleConnectTimeout
, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT
},
806 {handleHTTPGet
, "CURLOPT_HTTPGET", CURLOPT_HTTPGET
},
807 {handleSSLVerifyHost
, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST
},
808 {handleCookieJar
, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR
},
809 {handleSSLCipherList
, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST
},
810 {handleHTTPVersion
, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION
},
811 {handleFTPUseEPSV
, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV
},
812 {handleDNSCacheTimeout
, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT
},
813 {handleDNSUseGlobalCache
, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE
},
814 {handleDebugFunction
, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION
},
815 #if HAVE_DECL_CURLOPT_PRIVATE
816 {handlePrivate
, "CURLOPT_PRIVATE", CURLOPT_PRIVATE
},
818 {handlePrivate
, "CURLOPT_PRIVATE", 0},
820 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
821 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES
},
823 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", 0},
825 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
826 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH
},
828 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", 0},
830 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
831 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT
},
833 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", 0},
835 #if HAVE_DECL_CURLOPT_HTTPAUTH
836 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH
},
838 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", 0},
840 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
841 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS
},
843 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
845 #if HAVE_DECL_CURLOPT_PROXYAUTH
846 {handleProxyAuth
, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH
},
848 {handleProxyAuth
, "CURLOPT_PROXYAUTH", 0},
850 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
851 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT
},
853 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
855 #if HAVE_DECL_CURLOPT_IPRESOLVE
856 {handleIPResolve
, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE
},
858 {handleIPResolve
, "CURLOPT_IPRESOLVE", 0},
860 #if HAVE_DECL_CURLOPT_MAXFILESIZE
861 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE
},
863 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", 0},
865 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
866 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE
},
868 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", 0},
870 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
871 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE
},
873 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", 0},
875 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
876 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE
},
878 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", 0},
880 #if HAVE_DECL_CURLOPT_NETRC_FILE
881 {handleNETRCFile
, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE
},
883 {handleNETRCFile
, "CURLOPT_NETRC_FILE", 0},
885 #if HAVE_DECL_CURLOPT_FTP_SSL
886 {handleFTPSSL
, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL
},
888 {handleFTPSSL
, "CURLOPT_FTP_SSL", 0},
890 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
891 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE
},
893 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
895 #if HAVE_DECL_CURLOPT_TCP_NODELAY
896 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY
},
898 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", 0},
900 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
901 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH
},
903 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", 0},
905 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
906 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION
},
908 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", 0},
910 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
911 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT
},
913 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", 0},
915 #if HAVE_DECL_CURLOPT_COOKIELIST
916 {handleCookieList
, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST
},
918 {handleCookieList
, "CURLOPT_COOKIELIST", 0},
920 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
921 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH
},
923 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
925 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
926 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP
},
928 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", 0},
930 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
931 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD
},
933 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", 0},
935 #if HAVE_DECL_CURLOPT_LOCALPORT
936 {handleLocalPort
, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT
},
938 {handleLocalPort
, "CURLOPT_LOCALPORT", 0},
940 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
941 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE
},
943 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", 0},
945 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
946 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY
},
948 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", 0},
950 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
951 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE
},
953 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
955 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
956 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE
},
958 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
960 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
961 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER
},
963 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
965 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
966 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE
},
968 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", 0},
970 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
971 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES
},
973 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", 0},
975 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
976 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE
},
978 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
980 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
981 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE
},
983 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
985 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
986 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC
},
988 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", 0},
990 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
991 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS
},
993 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", 0},
995 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
996 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS
},
998 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", 0},
1000 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
1001 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING
},
1003 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
1005 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1006 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING
},
1008 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1010 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1011 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS
},
1013 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", 0},
1015 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1016 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS
},
1018 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1020 #if HAVE_DECL_CURLOPT_POST301
1021 {handlePost301
, "CURLOPT_POST301", CURLOPT_POST301
},
1023 {handlePost301
, "CURLOPT_POST301", 0},
1025 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1026 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
},
1028 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1030 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1031 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS
},
1033 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", 0},
1035 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1036 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE
},
1038 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1040 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1041 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION
},
1043 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", 0},
1047 static char *findOption(CURLOptionMapping optionMap
[],
1050 return optionMap
[option
].name
;
1053 static void free_curl_slist(struct curl_slist
*slist
)
1055 struct curl_slist
*item
;
1062 while (item
!= NULL
)
1069 curl_slist_free_all(slist
);
1072 static void raiseError(Connection
*conn
, CURLcode code
)
1075 CAMLlocal1(exceptionData
);
1077 char *errorString
= "Unknown Error";
1080 for (i
= 0; errorMap
[i
].name
!= NULL
; i
++)
1082 if (errorMap
[i
].error
== code
)
1084 errorString
= errorMap
[i
].name
;
1089 exceptionData
= caml_alloc(3, 0);
1091 Store_field(exceptionData
, 0, Val_int(code
));
1092 Store_field(exceptionData
, 1, Val_int(code
));
1093 Store_field(exceptionData
, 2, copy_string(errorString
));
1095 if (conn
!= NULL
&& conn
->errorBuffer
!= NULL
)
1097 Store_field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0,
1098 copy_string(conn
->errorBuffer
));
1101 exception
= caml_named_value("CurlException");
1103 if (exception
== NULL
)
1104 caml_failwith("CurlException not registered");
1106 raise_with_arg(*exception
, exceptionData
);
1111 static void resetOcamlValues(Connection
* connection
)
1115 for (i
= 0; i
< OcamlValuesSize
; i
++)
1116 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1119 static Connection
*newConnection(void)
1121 Connection
*connection
;
1123 connection
= (Connection
*)malloc(sizeof(Connection
));
1125 enter_blocking_section();
1126 connection
->connection
= curl_easy_init();
1127 leave_blocking_section();
1129 connection
->next
= NULL
;
1130 connection
->prev
= NULL
;
1132 if (connectionList
.tail
== NULL
)
1134 connectionList
.tail
= connection
;
1135 connectionList
.head
= connection
;
1139 connection
->prev
= connectionList
.head
;
1140 connectionList
.head
->next
= connection
;
1141 connectionList
.head
= connection
;
1144 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1145 resetOcamlValues(connection
);
1146 register_global_root(&connection
->ocamlValues
);
1148 connection
->url
= NULL
;
1149 connection
->proxy
= NULL
;
1150 connection
->userPwd
= NULL
;
1151 connection
->proxyUserPwd
= NULL
;
1152 connection
->range
= NULL
;
1153 connection
->errorBuffer
= NULL
;
1154 connection
->postFields
= NULL
;
1155 connection
->postFieldSize
= -1;
1156 connection
->referer
= NULL
;
1157 connection
->userAgent
= NULL
;
1158 connection
->ftpPort
= NULL
;
1159 connection
->cookie
= NULL
;
1160 connection
->httpHeader
= NULL
;
1161 connection
->httpPostFirst
= NULL
;
1162 connection
->httpPostLast
= NULL
;
1163 connection
->httpPostStrings
= NULL
;
1164 connection
->sslCert
= NULL
;
1165 connection
->sslCertType
= NULL
;
1166 connection
->sslCertPasswd
= NULL
;
1167 connection
->sslKey
= NULL
;
1168 connection
->sslKeyType
= NULL
;
1169 connection
->sslKeyPasswd
= NULL
;
1170 connection
->sslEngine
= NULL
;
1171 connection
->quote
= NULL
;
1172 connection
->postQuote
= NULL
;
1173 connection
->cookieFile
= NULL
;
1174 connection
->customRequest
= NULL
;
1175 connection
->interface
= NULL
;
1176 connection
->caInfo
= NULL
;
1177 connection
->caPath
= NULL
;
1178 connection
->randomFile
= NULL
;
1179 connection
->egdSocket
= NULL
;
1180 connection
->cookieJar
= NULL
;
1181 connection
->sslCipherList
= NULL
;
1182 connection
->private = NULL
;
1183 connection
->http200Aliases
= NULL
;
1184 connection
->netrcFile
= NULL
;
1185 connection
->ftpaccount
= NULL
;
1186 connection
->cookielist
= NULL
;
1187 connection
->ftpAlternativeToUser
= NULL
;
1188 connection
->sshPublicKeyFile
= NULL
;
1189 connection
->sshPrivateKeyFile
= NULL
;
1190 connection
->copyPostFields
= NULL
;
1195 static Connection
*duplicateConnection(Connection
*original
)
1197 Connection
*connection
;
1199 connection
= (Connection
*)malloc(sizeof(Connection
));
1201 enter_blocking_section();
1202 connection
->connection
= curl_easy_duphandle(original
->connection
);
1203 leave_blocking_section();
1205 connection
->next
= NULL
;
1206 connection
->prev
= NULL
;
1208 if (connectionList
.tail
== NULL
)
1210 connectionList
.tail
= connection
;
1211 connectionList
.head
= connection
;
1215 connection
->prev
= connectionList
.head
;
1216 connectionList
.head
->next
= connection
;
1217 connectionList
.head
= connection
;
1220 connection
->ocamlValues
= alloc(OcamlValuesSize
, 0);
1221 resetOcamlValues(connection
);
1222 register_global_root(&connection
->ocamlValues
);
1224 Store_field(connection
->ocamlValues
, OcamlWriteCallback
,
1225 Field(original
->ocamlValues
, OcamlWriteCallback
));
1226 Store_field(connection
->ocamlValues
, OcamlReadCallback
,
1227 Field(original
->ocamlValues
, OcamlReadCallback
));
1228 Store_field(connection
->ocamlValues
, OcamlErrorBuffer
,
1229 Field(original
->ocamlValues
, OcamlErrorBuffer
));
1230 Store_field(connection
->ocamlValues
, OcamlPostFields
,
1231 Field(original
->ocamlValues
, OcamlPostFields
));
1232 Store_field(connection
->ocamlValues
, OcamlHTTPHeader
,
1233 Field(original
->ocamlValues
, OcamlHTTPHeader
));
1234 Store_field(connection
->ocamlValues
, OcamlQuote
,
1235 Field(original
->ocamlValues
, OcamlQuote
));
1236 Store_field(connection
->ocamlValues
, OcamlPostQuote
,
1237 Field(original
->ocamlValues
, OcamlPostQuote
));
1238 Store_field(connection
->ocamlValues
, OcamlHeaderCallback
,
1239 Field(original
->ocamlValues
, OcamlHeaderCallback
));
1240 Store_field(connection
->ocamlValues
, OcamlProgressCallback
,
1241 Field(original
->ocamlValues
, OcamlProgressCallback
));
1242 Store_field(connection
->ocamlValues
, OcamlDebugCallback
,
1243 Field(original
->ocamlValues
, OcamlDebugCallback
));
1244 Store_field(connection
->ocamlValues
, OcamlHTTP200Aliases
,
1245 Field(original
->ocamlValues
, OcamlHTTP200Aliases
));
1246 Store_field(connection
->ocamlValues
, OcamlIOCTLCallback
,
1247 Field(original
->ocamlValues
, OcamlIOCTLCallback
));
1248 Store_field(connection
->ocamlValues
, OcamlSeekFunctionCallback
,
1249 Field(original
->ocamlValues
, OcamlSeekFunctionCallback
));
1251 connection
->url
= NULL
;
1252 connection
->proxy
= NULL
;
1253 connection
->userPwd
= NULL
;
1254 connection
->proxyUserPwd
= NULL
;
1255 connection
->range
= NULL
;
1256 connection
->errorBuffer
= NULL
;
1257 connection
->postFields
= NULL
;
1258 connection
->postFieldSize
= -1;
1259 connection
->referer
= NULL
;
1260 connection
->userAgent
= NULL
;
1261 connection
->ftpPort
= NULL
;
1262 connection
->cookie
= NULL
;
1263 connection
->httpHeader
= NULL
;
1264 connection
->httpPostFirst
= NULL
;
1265 connection
->httpPostLast
= NULL
;
1266 connection
->httpPostStrings
= NULL
;
1267 connection
->sslCert
= NULL
;
1268 connection
->sslCertType
= NULL
;
1269 connection
->sslCertPasswd
= NULL
;
1270 connection
->sslKey
= NULL
;
1271 connection
->sslKeyType
= NULL
;
1272 connection
->sslKeyPasswd
= NULL
;
1273 connection
->sslEngine
= NULL
;
1274 connection
->quote
= NULL
;
1275 connection
->postQuote
= NULL
;
1276 connection
->cookieFile
= NULL
;
1277 connection
->customRequest
= NULL
;
1278 connection
->interface
= NULL
;
1279 connection
->caInfo
= NULL
;
1280 connection
->caPath
= NULL
;
1281 connection
->randomFile
= NULL
;
1282 connection
->egdSocket
= NULL
;
1283 connection
->cookieJar
= NULL
;
1284 connection
->sslCipherList
= NULL
;
1285 connection
->private = NULL
;
1286 connection
->http200Aliases
= NULL
;
1287 connection
->netrcFile
= NULL
;
1288 connection
->ftpaccount
= NULL
;
1289 connection
->cookielist
= NULL
;
1290 connection
->sshPublicKeyFile
= NULL
;
1291 connection
->sshPrivateKeyFile
= NULL
;
1292 connection
->copyPostFields
= NULL
;
1294 if (Field(original
->ocamlValues
, OcamlURL
) != Val_unit
)
1295 handleURL(connection
, Field(original
->ocamlValues
,
1297 if (Field(original
->ocamlValues
, OcamlProxy
) != Val_unit
)
1298 handleProxy(connection
, Field(original
->ocamlValues
,
1300 if (Field(original
->ocamlValues
, OcamlUserPWD
) != Val_unit
)
1301 handleUserPwd(connection
, Field(original
->ocamlValues
,
1303 if (Field(original
->ocamlValues
, OcamlProxyUserPWD
) != Val_unit
)
1304 handleProxyUserPwd(connection
, Field(original
->ocamlValues
,
1305 OcamlProxyUserPWD
));
1306 if (Field(original
->ocamlValues
, OcamlRange
) != Val_unit
)
1307 handleRange(connection
, Field(original
->ocamlValues
,
1309 if (Field(original
->ocamlValues
, OcamlErrorBuffer
) != Val_unit
)
1310 handleErrorBuffer(connection
, Field(original
->ocamlValues
,
1312 if (Field(original
->ocamlValues
, OcamlPostFields
) != Val_unit
)
1313 handlePostFields(connection
, Field(original
->ocamlValues
,
1315 if (Field(original
->ocamlValues
, OcamlReferer
) != Val_unit
)
1316 handleReferer(connection
, Field(original
->ocamlValues
,
1318 if (Field(original
->ocamlValues
, OcamlUserAgent
) != Val_unit
)
1319 handleUserAgent(connection
, Field(original
->ocamlValues
,
1321 if (Field(original
->ocamlValues
, OcamlFTPPort
) != Val_unit
)
1322 handleFTPPort(connection
, Field(original
->ocamlValues
,
1324 if (Field(original
->ocamlValues
, OcamlCookie
) != Val_unit
)
1325 handleCookie(connection
, Field(original
->ocamlValues
,
1327 if (Field(original
->ocamlValues
, OcamlHTTPHeader
) != Val_unit
)
1328 handleHTTPHeader(connection
, Field(original
->ocamlValues
,
1330 if (Field(original
->ocamlValues
, OcamlHTTPPost
) != Val_unit
)
1331 handleHTTPPost(connection
, Field(original
->ocamlValues
,
1333 if (Field(original
->ocamlValues
, OcamlSSLCert
) != Val_unit
)
1334 handleSSLCert(connection
, Field(original
->ocamlValues
,
1336 if (Field(original
->ocamlValues
, OcamlSSLCertType
) != Val_unit
)
1337 handleSSLCertType(connection
, Field(original
->ocamlValues
,
1339 if (Field(original
->ocamlValues
, OcamlSSLCertPasswd
) != Val_unit
)
1340 handleSSLCertPasswd(connection
, Field(original
->ocamlValues
,
1341 OcamlSSLCertPasswd
));
1342 if (Field(original
->ocamlValues
, OcamlSSLKey
) != Val_unit
)
1343 handleSSLKey(connection
, Field(original
->ocamlValues
,
1345 if (Field(original
->ocamlValues
, OcamlSSLKeyType
) != Val_unit
)
1346 handleSSLKeyType(connection
, Field(original
->ocamlValues
,
1348 if (Field(original
->ocamlValues
, OcamlSSLKeyPasswd
) != Val_unit
)
1349 handleSSLKeyPasswd(connection
, Field(original
->ocamlValues
,
1350 OcamlSSLKeyPasswd
));
1351 if (Field(original
->ocamlValues
, OcamlSSLEngine
) != Val_unit
)
1352 handleSSLEngine(connection
, Field(original
->ocamlValues
,
1354 if (Field(original
->ocamlValues
, OcamlQuote
) != Val_unit
)
1355 handleQuote(connection
, Field(original
->ocamlValues
,
1357 if (Field(original
->ocamlValues
, OcamlPostQuote
) != Val_unit
)
1358 handlePostQuote(connection
, Field(original
->ocamlValues
,
1360 if (Field(original
->ocamlValues
, OcamlCookieFile
) != Val_unit
)
1361 handleCookieFile(connection
, Field(original
->ocamlValues
,
1363 if (Field(original
->ocamlValues
, OcamlCustomRequest
) != Val_unit
)
1364 handleCustomRequest(connection
, Field(original
->ocamlValues
,
1365 OcamlCustomRequest
));
1366 if (Field(original
->ocamlValues
, OcamlInterface
) != Val_unit
)
1367 handleInterface(connection
, Field(original
->ocamlValues
,
1369 if (Field(original
->ocamlValues
, OcamlCAInfo
) != Val_unit
)
1370 handleCAInfo(connection
, Field(original
->ocamlValues
,
1372 if (Field(original
->ocamlValues
, OcamlCAPath
) != Val_unit
)
1373 handleCAPath(connection
, Field(original
->ocamlValues
,
1375 if (Field(original
->ocamlValues
, OcamlRandomFile
) != Val_unit
)
1376 handleRandomFile(connection
, Field(original
->ocamlValues
,
1378 if (Field(original
->ocamlValues
, OcamlEGDSocket
) != Val_unit
)
1379 handleEGDSocket(connection
, Field(original
->ocamlValues
,
1381 if (Field(original
->ocamlValues
, OcamlCookieJar
) != Val_unit
)
1382 handleCookieJar(connection
, Field(original
->ocamlValues
,
1384 if (Field(original
->ocamlValues
, OcamlSSLCipherList
) != Val_unit
)
1385 handleSSLCipherList(connection
, Field(original
->ocamlValues
,
1386 OcamlSSLCipherList
));
1387 if (Field(original
->ocamlValues
, OcamlPrivate
) != Val_unit
)
1388 handlePrivate(connection
, Field(original
->ocamlValues
,
1390 if (Field(original
->ocamlValues
, OcamlHTTP200Aliases
) != Val_unit
)
1391 handleHTTP200Aliases(connection
, Field(original
->ocamlValues
,
1392 OcamlHTTP200Aliases
));
1393 if (Field(original
->ocamlValues
, OcamlNETRCFile
) != Val_unit
)
1394 handleNETRCFile(connection
, Field(original
->ocamlValues
,
1396 if (Field(original
->ocamlValues
, OcamlFTPAccount
) != Val_unit
)
1397 handleFTPAccount(connection
, Field(original
->ocamlValues
,
1399 if (Field(original
->ocamlValues
, OcamlCookieList
) != Val_unit
)
1400 handleCookieList(connection
, Field(original
->ocamlValues
,
1402 if (Field(original
->ocamlValues
, OcamlFTPAlternativeToUser
) != Val_unit
)
1403 handleFTPAlternativeToUser(connection
,
1404 Field(original
->ocamlValues
,
1405 OcamlFTPAlternativeToUser
));
1406 if (Field(original
->ocamlValues
, OcamlSSHPublicKeyFile
) != Val_unit
)
1407 handleSSHPublicKeyFile(connection
,
1408 Field(original
->ocamlValues
,
1409 OcamlSSHPublicKeyFile
));
1410 if (Field(original
->ocamlValues
, OcamlSSHPrivateKeyFile
) != Val_unit
)
1411 handleSSHPrivateKeyFile(connection
,
1412 Field(original
->ocamlValues
,
1413 OcamlSSHPrivateKeyFile
));
1414 if (Field(original
->ocamlValues
, OcamlCopyPostFields
) != Val_unit
)
1415 handleCopyPostFields(connection
,
1416 Field(original
->ocamlValues
,
1417 OcamlCopyPostFields
));
1422 static void removeConnection(Connection
*connection
)
1424 enter_blocking_section();
1425 curl_easy_cleanup(connection
->connection
);
1426 leave_blocking_section();
1428 if (connectionList
.tail
== connection
)
1429 connectionList
.tail
= connectionList
.tail
->next
;
1430 if (connectionList
.head
== connection
)
1431 connectionList
.head
= connectionList
.head
->prev
;
1433 if (connection
->next
!= NULL
)
1434 connection
->next
->prev
= connection
->prev
;
1435 if (connection
->prev
!= NULL
)
1436 connection
->prev
->next
= connection
->next
;
1438 remove_global_root(&connection
->ocamlValues
);
1440 if (connection
->url
!= NULL
)
1441 free(connection
->url
);
1442 if (connection
->proxy
!= NULL
)
1443 free(connection
->proxy
);
1444 if (connection
->userPwd
!= NULL
)
1445 free(connection
->userPwd
);
1446 if (connection
->proxyUserPwd
!= NULL
)
1447 free(connection
->proxyUserPwd
);
1448 if (connection
->range
!= NULL
)
1449 free(connection
->range
);
1450 if (connection
->errorBuffer
!= NULL
)
1451 free(connection
->range
);
1452 if (connection
->postFields
!= NULL
)
1453 free(connection
->postFields
);
1454 if (connection
->referer
!= NULL
)
1455 free(connection
->referer
);
1456 if (connection
->userAgent
!= NULL
)
1457 free(connection
->userAgent
);
1458 if (connection
->ftpPort
!= NULL
)
1459 free(connection
->ftpPort
);
1460 if (connection
->cookie
!= NULL
)
1461 free(connection
->cookie
);
1462 if (connection
->httpHeader
!= NULL
)
1463 free_curl_slist(connection
->httpHeader
);
1464 if (connection
->httpPostFirst
!= NULL
)
1465 curl_formfree(connection
->httpPostFirst
);
1466 if (connection
->httpPostStrings
!= NULL
)
1467 free_curl_slist(connection
->httpPostStrings
);
1468 if (connection
->sslCert
!= NULL
)
1469 free(connection
->sslCert
);
1470 if (connection
->sslCertType
!= NULL
)
1471 free(connection
->sslCertType
);
1472 if (connection
->sslCertPasswd
!= NULL
)
1473 free(connection
->sslCertPasswd
);
1474 if (connection
->sslKey
!= NULL
)
1475 free(connection
->sslKey
);
1476 if (connection
->sslKeyType
!= NULL
)
1477 free(connection
->sslKeyType
);
1478 if (connection
->sslKeyPasswd
!= NULL
)
1479 free(connection
->sslKeyPasswd
);
1480 if (connection
->sslEngine
!= NULL
)
1481 free(connection
->sslEngine
);
1482 if (connection
->quote
!= NULL
)
1483 free_curl_slist(connection
->quote
);
1484 if (connection
->postQuote
!= NULL
)
1485 free_curl_slist(connection
->postQuote
);
1486 if (connection
->cookieFile
!= NULL
)
1487 free(connection
->cookieFile
);
1488 if (connection
->customRequest
!= NULL
)
1489 free(connection
->customRequest
);
1490 if (connection
->interface
!= NULL
)
1491 free(connection
->interface
);
1492 if (connection
->caInfo
!= NULL
)
1493 free(connection
->caInfo
);
1494 if (connection
->caPath
!= NULL
)
1495 free(connection
->caPath
);
1496 if (connection
->randomFile
!= NULL
)
1497 free(connection
->randomFile
);
1498 if (connection
->egdSocket
!= NULL
)
1499 free(connection
->egdSocket
);
1500 if (connection
->cookieJar
!= NULL
)
1501 free(connection
->cookieJar
);
1502 if (connection
->sslCipherList
!= NULL
)
1503 free(connection
->sslCipherList
);
1504 if (connection
->private != NULL
)
1505 free(connection
->private);
1506 if (connection
->http200Aliases
!= NULL
)
1507 free_curl_slist(connection
->http200Aliases
);
1508 if (connection
->netrcFile
!= NULL
)
1509 free(connection
->netrcFile
);
1510 if (connection
->ftpaccount
!= NULL
)
1511 free(connection
->ftpaccount
);
1512 if (connection
->cookielist
!= NULL
)
1513 free(connection
->cookielist
);
1514 if (connection
->ftpAlternativeToUser
!= NULL
)
1515 free(connection
->ftpAlternativeToUser
);
1516 if (connection
->sshPublicKeyFile
!= NULL
)
1517 free(connection
->sshPublicKeyFile
);
1518 if (connection
->sshPrivateKeyFile
!= NULL
)
1519 free(connection
->sshPrivateKeyFile
);
1520 if (connection
->copyPostFields
!= NULL
)
1521 free(connection
->copyPostFields
);
1526 static void checkConnection(Connection
*connection
)
1528 Connection
*listIter
;
1530 listIter
= connectionList
.tail
;
1532 while (listIter
!= NULL
)
1534 if (listIter
== connection
)
1537 listIter
= listIter
->next
;
1540 failwith("Invalid Connection");
1543 static Connection
* findConnection(CURL
* h
)
1545 Connection
*listIter
;
1547 listIter
= connectionList
.tail
;
1549 while (listIter
!= NULL
)
1551 if (listIter
->connection
== h
)
1554 listIter
= listIter
->next
;
1557 failwith("Unknown handle");
1560 #define WRAP_DATA_CALLBACK(f) \
1561 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1564 leave_blocking_section();\
1565 result = f##_nolock(ptr,size,nmemb,data);\
1566 enter_blocking_section();\
1570 static size_t writeFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1573 CAMLlocal2(result
, str
);
1574 Connection
*conn
= (Connection
*)data
;
1577 checkConnection(conn
);
1579 str
= alloc_string(size
*nmemb
);
1581 for (i
= 0; i
< size
*nmemb
; i
++)
1582 Byte(str
, i
) = ptr
[i
];
1584 result
= callback(Field(conn
->ocamlValues
, OcamlWriteCallback
), str
);
1586 CAMLreturnT(size_t, Int_val(result
));
1589 WRAP_DATA_CALLBACK(writeFunction
)
1591 static size_t readFunction_nolock(void *ptr
, size_t size
, size_t nmemb
, void *data
)
1595 Connection
*conn
= (Connection
*)data
;
1598 checkConnection(conn
);
1600 result
= callback(Field(conn
->ocamlValues
, OcamlReadCallback
),
1601 Val_int(size
*nmemb
));
1603 length
= string_length(result
);
1605 if (length
>= size
*nmemb
)
1606 length
= size
*nmemb
;
1608 memcpy(ptr
, String_val(result
), length
);
1610 CAMLreturnT(size_t,length
);
1613 WRAP_DATA_CALLBACK(readFunction
)
1615 static size_t headerFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1618 CAMLlocal2(result
,str
);
1619 Connection
*conn
= (Connection
*)data
;
1622 checkConnection(conn
);
1624 str
= alloc_string(size
*nmemb
);
1626 for (i
= 0; i
< size
*nmemb
; i
++)
1627 Byte(str
, i
) = ptr
[i
];
1629 result
= callback(Field(conn
->ocamlValues
, OcamlHeaderCallback
), str
);
1631 CAMLreturnT(size_t, Int_val(result
));
1634 WRAP_DATA_CALLBACK(headerFunction
)
1636 static int progressFunction_nolock(void *data
,
1644 CAMLlocalN(callbackData
, 4);
1645 Connection
*conn
= (Connection
*)data
;
1647 checkConnection(conn
);
1649 callbackData
[0] = copy_double(dlTotal
);
1650 callbackData
[1] = copy_double(dlNow
);
1651 callbackData
[2] = copy_double(ulTotal
);
1652 callbackData
[3] = copy_double(ulNow
);
1654 result
= callbackN(Field(conn
->ocamlValues
, OcamlProgressCallback
),
1657 CAMLreturnT(int, Bool_val(result
));
1660 static int progressFunction(void *data
,
1667 leave_blocking_section();
1668 r
= progressFunction_nolock(data
,dlTotal
,dlNow
,ulTotal
,ulNow
);
1669 enter_blocking_section();
1673 static int debugFunction_nolock(CURL
*debugConnection
,
1674 curl_infotype infoType
,
1676 size_t bufferLength
,
1680 CAMLlocal3(camlDebugConnection
, camlInfoType
, camlMessage
);
1682 Connection
*conn
= (Connection
*)data
;
1684 checkConnection(conn
);
1686 camlDebugConnection
= (value
)conn
;
1687 camlInfoType
= Val_long(infoType
);
1688 camlMessage
= alloc_string(bufferLength
);
1690 for (i
= 0; i
< bufferLength
; i
++)
1691 Byte(camlMessage
, i
) = buffer
[i
];
1693 callback3(Field(conn
->ocamlValues
, OcamlDebugCallback
),
1694 camlDebugConnection
,
1698 CAMLreturnT(int, 0);
1701 static int debugFunction(CURL
*debugConnection
,
1702 curl_infotype infoType
,
1704 size_t bufferLength
,
1708 leave_blocking_section();
1709 r
= debugFunction_nolock(debugConnection
, infoType
, buffer
, bufferLength
, data
);
1710 enter_blocking_section();
1714 static curlioerr
ioctlFunction_nolock(CURL
*ioctl
,
1719 CAMLlocal3(camlResult
, camlConnection
, camlCmd
);
1720 Connection
*conn
= (Connection
*)data
;
1721 curlioerr result
= CURLIOE_OK
;
1723 checkConnection(conn
);
1725 if (cmd
== CURLIOCMD_NOP
)
1726 camlCmd
= Val_long(0);
1727 else if (cmd
== CURLIOCMD_RESTARTREAD
)
1728 camlCmd
= Val_long(1);
1730 failwith("Invalid IOCTL Cmd!");
1732 camlConnection
= caml_alloc(1, Abstract_tag
);
1733 Field(camlConnection
, 0) = (value
)conn
;
1735 camlResult
= callback2(Field(conn
->ocamlValues
, OcamlIOCTLCallback
),
1739 switch (Long_val(camlResult
))
1741 case 0: /* CURLIOE_OK */
1742 result
= CURLIOE_OK
;
1745 case 1: /* CURLIOE_UNKNOWNCMD */
1746 result
= CURLIOE_UNKNOWNCMD
;
1749 case 2: /* CURLIOE_FAILRESTART */
1750 result
= CURLIOE_FAILRESTART
;
1753 default: /* Incorrect return value, but let's handle it */
1754 result
= CURLIOE_FAILRESTART
;
1758 CAMLreturnT(curlioerr
, result
);
1761 static curlioerr
ioctlFunction(CURL
*ioctl
,
1766 leave_blocking_section();
1767 r
= ioctlFunction_nolock(ioctl
, cmd
, data
);
1768 enter_blocking_section();
1772 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1773 static int seekFunction_nolock(void *data
,
1778 CAMLlocal3(camlResult
, camlOffset
, camlOrigin
);
1779 Connection
*conn
= (Connection
*)data
;
1782 camlOffset
= copy_int64(offset
);
1784 if (origin
== SEEK_SET
)
1785 camlOrigin
= Val_long(0);
1786 else if (origin
== SEEK_CUR
)
1787 camlOrigin
= Val_long(1);
1788 else if (origin
== SEEK_END
)
1789 camlOrigin
= Val_long(2);
1791 camlOrigin
= Val_long(0);
1793 camlResult
= callback2(Field(conn
->ocamlValues
,
1794 OcamlSeekFunctionCallback
),
1798 result
= Int_val(camlResult
);
1800 CAMLreturnT(int, result
);
1803 static int seekFunction(void *data
,
1808 leave_blocking_section();
1809 r
= seekFunction_nolock(data
,offset
,origin
);
1810 enter_blocking_section();
1817 ** curl_global_init helper function
1820 CAMLprim value
helper_curl_global_init(value initOption
)
1822 CAMLparam1(initOption
);
1824 switch (Long_val(initOption
))
1826 case 0: /* CURLINIT_GLOBALALL */
1827 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL
)));
1830 case 1: /* CURLINIT_GLOBALSSL */
1831 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL
)));
1834 case 2: /* CURLINIT_GLOBALWIN32 */
1835 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32
)));
1838 case 3: /* CURLINIT_GLOBALNOTHING */
1839 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING
)));
1843 failwith("Invalid Initialization Option");
1847 /* Keep compiler happy, we should never get here due to failwith() */
1848 CAMLreturn(Val_unit
);
1852 ** curl_global_cleanup helper function
1855 CAMLprim value
helper_curl_global_cleanup(void)
1859 curl_global_cleanup();
1861 CAMLreturn(Val_unit
);
1865 ** curl_easy_init helper function
1868 CAMLprim value
helper_curl_easy_init(void)
1873 Connection
*conn
= newConnection();
1875 result
= caml_alloc(1, Abstract_tag
);
1876 Field(result
, 0) = (value
)conn
;
1881 CAMLprim value
helper_curl_easy_reset(value conn
)
1884 Connection
*connection
= Connection_val(conn
);
1886 checkConnection(connection
);
1887 curl_easy_reset(connection
->connection
);
1888 resetOcamlValues(connection
);
1890 CAMLreturn(Val_unit
);
1894 ** curl_easy_setopt helper utility functions
1897 static void handleWriteFunction(Connection
*conn
, value option
)
1900 CURLcode result
= CURLE_OK
;
1902 if (Tag_val(option
) == Closure_tag
)
1903 Store_field(conn
->ocamlValues
, OcamlWriteCallback
, option
);
1905 failwith("Not a proper closure");
1907 result
= curl_easy_setopt(conn
->connection
,
1908 CURLOPT_WRITEFUNCTION
,
1911 if (result
!= CURLE_OK
)
1912 raiseError(conn
, result
);
1914 result
= curl_easy_setopt(conn
->connection
,
1918 if (result
!= CURLE_OK
)
1919 raiseError(conn
, result
);
1924 static void handleReadFunction(Connection
*conn
, value option
)
1927 CURLcode result
= CURLE_OK
;
1929 if (Tag_val(option
) == Closure_tag
)
1930 Store_field(conn
->ocamlValues
, OcamlReadCallback
, option
);
1932 failwith("Not a proper closure");
1934 result
= curl_easy_setopt(conn
->connection
,
1935 CURLOPT_READFUNCTION
,
1938 if (result
!= CURLE_OK
)
1939 raiseError(conn
, result
);
1941 result
= curl_easy_setopt(conn
->connection
,
1945 if (result
!= CURLE_OK
)
1946 raiseError(conn
, result
);
1951 static void handleURL(Connection
*conn
, value option
)
1954 CURLcode result
= CURLE_OK
;
1956 Store_field(conn
->ocamlValues
, OcamlURL
, option
);
1958 if (conn
->url
!= NULL
)
1961 conn
->url
= strdup(String_val(option
));
1963 result
= curl_easy_setopt(conn
->connection
,
1967 if (result
!= CURLE_OK
)
1968 raiseError(conn
, result
);
1973 static void handleInFileSize(Connection
*conn
, value option
)
1976 CURLcode result
= CURLE_OK
;
1978 result
= curl_easy_setopt(conn
->connection
,
1982 if (result
!= CURLE_OK
)
1983 raiseError(conn
, result
);
1988 static void handleProxy(Connection
*conn
, value option
)
1991 CURLcode result
= CURLE_OK
;
1993 Store_field(conn
->ocamlValues
, OcamlProxy
, option
);
1995 if (conn
->proxy
!= NULL
)
1998 conn
->proxy
= strdup(String_val(option
));
2000 result
= curl_easy_setopt(conn
->connection
,
2004 if (result
!= CURLE_OK
)
2005 raiseError(conn
, result
);
2010 static void handleProxyPort(Connection
*conn
, value option
)
2013 CURLcode result
= CURLE_OK
;
2015 result
= curl_easy_setopt(conn
->connection
,
2019 if (result
!= CURLE_OK
)
2020 raiseError(conn
, result
);
2025 static void handleHTTPProxyTunnel(Connection
*conn
, value option
)
2028 CURLcode result
= CURLE_OK
;
2030 result
= curl_easy_setopt(conn
->connection
,
2031 CURLOPT_HTTPPROXYTUNNEL
,
2034 if (result
!= CURLE_OK
)
2035 raiseError(conn
, result
);
2040 static void handleVerbose(Connection
*conn
, value option
)
2043 CURLcode result
= CURLE_OK
;
2045 result
= curl_easy_setopt(conn
->connection
,
2049 if (result
!= CURLE_OK
)
2050 raiseError(conn
, result
);
2055 static void handleHeader(Connection
*conn
, value option
)
2058 CURLcode result
= CURLE_OK
;
2060 result
= curl_easy_setopt(conn
->connection
,
2064 if (result
!= CURLE_OK
)
2065 raiseError(conn
, result
);
2070 static void handleNoProgress(Connection
*conn
, value option
)
2073 CURLcode result
= CURLE_OK
;
2075 result
= curl_easy_setopt(conn
->connection
,
2079 if (result
!= CURLE_OK
)
2080 raiseError(conn
, result
);
2085 static void handleNoSignal(Connection
*conn
, value option
)
2087 #if HAVE_DECL_CURLOPT_NOSIGNAL
2089 CURLcode result
= CURLE_OK
;
2091 result
= curl_easy_setopt(conn
->connection
,
2095 if (result
!= CURLE_OK
)
2096 raiseError(conn
, result
);
2100 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2101 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2105 static void handleNoBody(Connection
*conn
, value option
)
2108 CURLcode result
= CURLE_OK
;
2110 result
= curl_easy_setopt(conn
->connection
,
2114 if (result
!= CURLE_OK
)
2115 raiseError(conn
, result
);
2120 static void handleFailOnError(Connection
*conn
, value option
)
2123 CURLcode result
= CURLE_OK
;
2125 result
= curl_easy_setopt(conn
->connection
,
2126 CURLOPT_FAILONERROR
,
2129 if (result
!= CURLE_OK
)
2130 raiseError(conn
, result
);
2135 static void handleUpload(Connection
*conn
, value option
)
2138 CURLcode result
= CURLE_OK
;
2140 result
= curl_easy_setopt(conn
->connection
,
2144 if (result
!= CURLE_OK
)
2145 raiseError(conn
, result
);
2150 static void handlePost(Connection
*conn
, value option
)
2153 CURLcode result
= CURLE_OK
;
2155 result
= curl_easy_setopt(conn
->connection
,
2159 if (result
!= CURLE_OK
)
2160 raiseError(conn
, result
);
2165 static void handleFTPListOnly(Connection
*conn
, value option
)
2168 CURLcode result
= CURLE_OK
;
2170 result
= curl_easy_setopt(conn
->connection
,
2171 CURLOPT_FTPLISTONLY
,
2174 if (result
!= CURLE_OK
)
2175 raiseError(conn
, result
);
2180 static void handleFTPAppend(Connection
*conn
, value option
)
2183 CURLcode result
= CURLE_OK
;
2185 result
= curl_easy_setopt(conn
->connection
,
2189 if (result
!= CURLE_OK
)
2190 raiseError(conn
, result
);
2195 static void handleNETRC(Connection
*conn
, value option
)
2198 CURLcode result
= CURLE_OK
;
2201 switch (Long_val(option
))
2203 case 0: /* CURL_NETRC_OPTIONAL */
2204 netrc
= CURL_NETRC_OPTIONAL
;
2207 case 1:/* CURL_NETRC_IGNORED */
2208 netrc
= CURL_NETRC_IGNORED
;
2211 case 2: /* CURL_NETRC_REQUIRED */
2212 netrc
= CURL_NETRC_REQUIRED
;
2216 failwith("Invalid NETRC Option");
2220 result
= curl_easy_setopt(conn
->connection
,
2224 if (result
!= CURLE_OK
)
2225 raiseError(conn
, result
);
2230 static void handleEncoding(Connection
*conn
, value option
)
2232 #if HAVE_DECL_CURLOPT_ENCODING
2234 CURLcode result
= CURLE_OK
;
2236 switch (Long_val(option
))
2238 case 0: /* CURL_ENCODING_NONE */
2239 result
= curl_easy_setopt(conn
->connection
,
2244 case 1: /* CURL_ENCODING_DEFLATE */
2245 result
= curl_easy_setopt(conn
->connection
,
2251 failwith("Invalid Encoding Option");
2255 if (result
!= CURLE_OK
)
2256 raiseError(conn
, result
);
2260 #warning "libcurl does not implement CURLOPT_ENCODING"
2261 failwith("libcurl does not implement CURLOPT_ENCODING");
2265 static void handleFollowLocation(Connection
*conn
, value option
)
2268 CURLcode result
= CURLE_OK
;
2270 result
= curl_easy_setopt(conn
->connection
,
2271 CURLOPT_FOLLOWLOCATION
,
2274 if (result
!= CURLE_OK
)
2275 raiseError(conn
, result
);
2280 static void handleTransferText(Connection
*conn
, value option
)
2283 CURLcode result
= CURLE_OK
;
2285 result
= curl_easy_setopt(conn
->connection
,
2286 CURLOPT_TRANSFERTEXT
,
2289 if (result
!= CURLE_OK
)
2290 raiseError(conn
, result
);
2295 static void handlePut(Connection
*conn
, value option
)
2298 CURLcode result
= CURLE_OK
;
2300 result
= curl_easy_setopt(conn
->connection
,
2304 if (result
!= CURLE_OK
)
2305 raiseError(conn
, result
);
2310 static void handleUserPwd(Connection
*conn
, value option
)
2313 CURLcode result
= CURLE_OK
;
2315 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2317 if (conn
->userPwd
!= NULL
)
2318 free(conn
->userPwd
);
2320 conn
->userPwd
= strdup(String_val(option
));
2322 result
= curl_easy_setopt(conn
->connection
,
2326 if (result
!= CURLE_OK
)
2327 raiseError(conn
, result
);
2332 static void handleProxyUserPwd(Connection
*conn
, value option
)
2335 CURLcode result
= CURLE_OK
;
2337 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2339 if (conn
->proxyUserPwd
!= NULL
)
2340 free(conn
->proxyUserPwd
);
2342 conn
->proxyUserPwd
= strdup(String_val(option
));
2344 result
= curl_easy_setopt(conn
->connection
,
2345 CURLOPT_PROXYUSERPWD
,
2346 conn
->proxyUserPwd
);
2348 if (result
!= CURLE_OK
)
2349 raiseError(conn
, result
);
2354 static void handleRange(Connection
*conn
, value option
)
2357 CURLcode result
= CURLE_OK
;
2359 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2361 if (conn
->range
!= NULL
)
2364 conn
->range
= strdup(String_val(option
));
2366 result
= curl_easy_setopt(conn
->connection
,
2370 if (result
!= CURLE_OK
)
2371 raiseError(conn
, result
);
2376 static void handleErrorBuffer(Connection
*conn
, value option
)
2379 CURLcode result
= CURLE_OK
;
2381 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2383 if (conn
->errorBuffer
!= NULL
)
2384 free(conn
->errorBuffer
);
2386 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2388 result
= curl_easy_setopt(conn
->connection
,
2389 CURLOPT_ERRORBUFFER
,
2392 if (result
!= CURLE_OK
)
2393 raiseError(conn
, result
);
2398 static void handleTimeout(Connection
*conn
, value option
)
2401 CURLcode result
= CURLE_OK
;
2403 result
= curl_easy_setopt(conn
->connection
,
2407 if (result
!= CURLE_OK
)
2408 raiseError(conn
, result
);
2413 static void handlePostFields(Connection
*conn
, value option
)
2416 CURLcode result
= CURLE_OK
;
2418 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2420 if (conn
->postFields
!= NULL
)
2421 free(conn
->postFields
);
2423 conn
->postFields
= malloc(string_length(option
)+1);
2424 memcpy(conn
->postFields
, String_val(option
), string_length(option
));
2426 result
= curl_easy_setopt(conn
->connection
,
2430 if (result
!= CURLE_OK
)
2431 raiseError(conn
, result
);
2436 static void handlePostFieldSize(Connection
*conn
, value option
)
2439 CURLcode result
= CURLE_OK
;
2441 result
= curl_easy_setopt(conn
->connection
,
2442 CURLOPT_POSTFIELDSIZE
,
2445 if (result
!= CURLE_OK
)
2446 raiseError(conn
, result
);
2451 static void handleReferer(Connection
*conn
, value option
)
2454 CURLcode result
= CURLE_OK
;
2456 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2458 if (conn
->referer
!= NULL
)
2459 free(conn
->referer
);
2461 conn
->referer
= strdup(String_val(option
));
2463 result
= curl_easy_setopt(conn
->connection
,
2467 if (result
!= CURLE_OK
)
2468 raiseError(conn
, result
);
2473 static void handleUserAgent(Connection
*conn
, value option
)
2476 CURLcode result
= CURLE_OK
;
2478 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2480 if (conn
->userAgent
!= NULL
)
2481 free(conn
->userAgent
);
2483 conn
->userAgent
= strdup(String_val(option
));
2485 result
= curl_easy_setopt(conn
->connection
,
2489 if (result
!= CURLE_OK
)
2490 raiseError(conn
, result
);
2495 static void handleFTPPort(Connection
*conn
, value option
)
2498 CURLcode result
= CURLE_OK
;
2500 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2502 if (conn
->ftpPort
!= NULL
)
2503 free(conn
->ftpPort
);
2505 conn
->ftpPort
= strdup(String_val(option
));
2507 result
= curl_easy_setopt(conn
->connection
,
2511 if (result
!= CURLE_OK
)
2512 raiseError(conn
, result
);
2517 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2520 CURLcode result
= CURLE_OK
;
2522 result
= curl_easy_setopt(conn
->connection
,
2523 CURLOPT_LOW_SPEED_LIMIT
,
2526 if (result
!= CURLE_OK
)
2527 raiseError(conn
, result
);
2532 static void handleLowSpeedTime(Connection
*conn
, value option
)
2535 CURLcode result
= CURLE_OK
;
2537 result
= curl_easy_setopt(conn
->connection
,
2538 CURLOPT_LOW_SPEED_TIME
,
2541 if (result
!= CURLE_OK
)
2542 raiseError(conn
, result
);
2547 static void handleResumeFrom(Connection
*conn
, value option
)
2550 CURLcode result
= CURLE_OK
;
2552 result
= curl_easy_setopt(conn
->connection
,
2553 CURLOPT_RESUME_FROM
,
2556 if (result
!= CURLE_OK
)
2557 raiseError(conn
, result
);
2562 static void handleCookie(Connection
*conn
, value option
)
2565 CURLcode result
= CURLE_OK
;
2567 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2569 if (conn
->cookie
!= NULL
)
2572 conn
->cookie
= strdup(String_val(option
));
2574 result
= curl_easy_setopt(conn
->connection
,
2578 if (result
!= CURLE_OK
)
2579 raiseError(conn
, result
);
2584 static void handleHTTPHeader(Connection
*conn
, value option
)
2587 CAMLlocal1(listIter
);
2588 CURLcode result
= CURLE_OK
;
2591 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2593 if (conn
->httpHeader
!= NULL
)
2594 free_curl_slist(conn
->httpHeader
);
2596 conn
->httpHeader
= NULL
;
2600 while (!Is_long(listIter
))
2602 if (Tag_val(Field(listIter
, 0)) != String_tag
)
2603 failwith("Not a string");
2605 str
= strdup(String_val(Field(listIter
, 0)));
2607 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, str
);
2609 listIter
= Field(listIter
, 1);
2612 result
= curl_easy_setopt(conn
->connection
,
2616 if (result
!= CURLE_OK
)
2617 raiseError(conn
, result
);
2622 static void handleHTTPPost(Connection
*conn
, value option
)
2625 CAMLlocal3(listIter
, formItem
, contentType
);
2626 CURLcode result
= CURLE_OK
;
2627 char *str1
, *str2
, *str3
, *str4
;
2631 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2633 if (conn
->httpPostFirst
!= NULL
)
2634 curl_formfree(conn
->httpPostFirst
);
2636 conn
->httpPostFirst
= NULL
;
2637 conn
->httpPostLast
= NULL
;
2639 if (conn
->httpPostStrings
!= NULL
)
2640 free_curl_slist(conn
->httpPostStrings
);
2642 while (!Is_long(listIter
))
2644 formItem
= Field(listIter
, 0);
2646 switch (Tag_val(formItem
))
2648 case 0: /* CURLFORM_CONTENT */
2649 if (Wosize_val(formItem
) < 3)
2651 failwith("Incorrect CURLFORM_CONTENT parameters");
2654 if (Is_long(Field(formItem
, 2)) &&
2655 Long_val(Field(formItem
, 2)) == 0)
2657 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2659 String_val(Field(formItem
, 0)),
2660 string_length(Field(formItem
, 0)));
2661 str1
[string_length(Field(formItem
, 0))] = 0;
2662 conn
->httpPostStrings
=
2663 curl_slist_append(conn
->httpPostStrings
, str1
);
2665 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2667 String_val(Field(formItem
, 1)),
2668 string_length(Field(formItem
, 1)));
2669 str2
[string_length(Field(formItem
, 1))] = 0;
2670 conn
->httpPostStrings
=
2671 curl_slist_append(conn
->httpPostStrings
, str2
);
2673 curl_formadd(&conn
->httpPostFirst
,
2674 &conn
->httpPostLast
,
2677 CURLFORM_NAMELENGTH
,
2678 string_length(Field(formItem
, 0)),
2679 CURLFORM_PTRCONTENTS
,
2681 CURLFORM_CONTENTSLENGTH
,
2682 string_length(Field(formItem
, 1)),
2685 else if (Is_block(Field(formItem
, 2)))
2687 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2689 String_val(Field(formItem
, 0)),
2690 string_length(Field(formItem
, 0)));
2691 str1
[string_length(Field(formItem
, 0))] = 0;
2692 conn
->httpPostStrings
=
2693 curl_slist_append(conn
->httpPostStrings
, str1
);
2695 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2697 String_val(Field(formItem
, 1)),
2698 string_length(Field(formItem
, 1)));
2699 str2
[string_length(Field(formItem
, 1))] = 0;
2700 conn
->httpPostStrings
=
2701 curl_slist_append(conn
->httpPostStrings
, str2
);
2703 contentType
= Field(formItem
, 2);
2705 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2707 String_val(Field(contentType
, 0)),
2708 string_length(Field(contentType
, 0)));
2709 str3
[string_length(Field(contentType
, 0))] = 0;
2710 conn
->httpPostStrings
=
2711 curl_slist_append(conn
->httpPostStrings
, str3
);
2713 curl_formadd(&conn
->httpPostFirst
,
2714 &conn
->httpPostLast
,
2717 CURLFORM_NAMELENGTH
,
2718 string_length(Field(formItem
, 0)),
2719 CURLFORM_PTRCONTENTS
,
2721 CURLFORM_CONTENTSLENGTH
,
2722 string_length(Field(formItem
, 1)),
2723 CURLFORM_CONTENTTYPE
,
2729 failwith("Incorrect CURLFORM_CONTENT parameters");
2733 case 1: /* CURLFORM_FILECONTENT */
2734 if (Wosize_val(formItem
) < 3)
2736 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2739 if (Is_long(Field(formItem
, 2)) &&
2740 Long_val(Field(formItem
, 2)) == 0)
2742 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2744 String_val(Field(formItem
, 0)),
2745 string_length(Field(formItem
, 0)));
2746 str1
[string_length(Field(formItem
, 0))] = 0;
2747 conn
->httpPostStrings
=
2748 curl_slist_append(conn
->httpPostStrings
, str1
);
2750 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2752 String_val(Field(formItem
, 1)),
2753 string_length(Field(formItem
, 1)));
2754 str2
[string_length(Field(formItem
, 1))] = 0;
2755 conn
->httpPostStrings
=
2756 curl_slist_append(conn
->httpPostStrings
, str2
);
2758 curl_formadd(&conn
->httpPostFirst
,
2759 &conn
->httpPostLast
,
2762 CURLFORM_NAMELENGTH
,
2763 string_length(Field(formItem
, 0)),
2764 CURLFORM_FILECONTENT
,
2768 else if (Is_block(Field(formItem
, 2)))
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 contentType
= Field(formItem
, 2);
2788 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2790 String_val(Field(contentType
, 0)),
2791 string_length(Field(contentType
, 0)));
2792 str3
[string_length(Field(contentType
, 0))] = 0;
2793 conn
->httpPostStrings
=
2794 curl_slist_append(conn
->httpPostStrings
, str3
);
2796 curl_formadd(&conn
->httpPostFirst
,
2797 &conn
->httpPostLast
,
2800 CURLFORM_NAMELENGTH
,
2801 string_length(Field(formItem
, 0)),
2802 CURLFORM_FILECONTENT
,
2804 CURLFORM_CONTENTTYPE
,
2810 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2814 case 2: /* CURLFORM_FILE */
2815 if (Wosize_val(formItem
) < 3)
2817 failwith("Incorrect CURLFORM_FILE parameters");
2820 if (Is_long(Field(formItem
, 2)) &&
2821 Long_val(Field(formItem
, 2)) == 0)
2823 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2825 String_val(Field(formItem
, 0)),
2826 string_length(Field(formItem
, 0)));
2827 str1
[string_length(Field(formItem
, 0))] = 0;
2828 conn
->httpPostStrings
=
2829 curl_slist_append(conn
->httpPostStrings
, str1
);
2831 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2833 String_val(Field(formItem
, 1)),
2834 string_length(Field(formItem
, 1)));
2835 str2
[string_length(Field(formItem
, 1))] = 0;
2836 conn
->httpPostStrings
=
2837 curl_slist_append(conn
->httpPostStrings
, str2
);
2839 curl_formadd(&conn
->httpPostFirst
,
2840 &conn
->httpPostLast
,
2843 CURLFORM_NAMELENGTH
,
2844 string_length(Field(formItem
, 0)),
2849 else if (Is_block(Field(formItem
, 2)))
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 contentType
= Field(formItem
, 2);
2869 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2871 String_val(Field(contentType
, 0)),
2872 string_length(Field(contentType
, 0)));
2873 str3
[string_length(Field(contentType
, 0))] = 0;
2874 conn
->httpPostStrings
=
2875 curl_slist_append(conn
->httpPostStrings
, str3
);
2877 curl_formadd(&conn
->httpPostFirst
,
2878 &conn
->httpPostLast
,
2881 CURLFORM_NAMELENGTH
,
2882 string_length(Field(formItem
, 0)),
2885 CURLFORM_CONTENTTYPE
,
2891 failwith("Incorrect CURLFORM_FILE parameters");
2895 case 3: /* CURLFORM_BUFFER */
2896 if (Wosize_val(formItem
) < 4)
2898 failwith("Incorrect CURLFORM_BUFFER parameters");
2901 if (Is_long(Field(formItem
, 3)) &&
2902 Long_val(Field(formItem
, 3)) == 0)
2904 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2906 String_val(Field(formItem
, 0)),
2907 string_length(Field(formItem
, 0)));
2908 str1
[string_length(Field(formItem
, 0))] = 0;
2909 conn
->httpPostStrings
=
2910 curl_slist_append(conn
->httpPostStrings
, str1
);
2912 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2914 String_val(Field(formItem
, 1)),
2915 string_length(Field(formItem
, 1)));
2916 str2
[string_length(Field(formItem
, 1))] = 0;
2917 conn
->httpPostStrings
=
2918 curl_slist_append(conn
->httpPostStrings
, str2
);
2920 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2922 String_val(Field(formItem
, 2)),
2923 string_length(Field(formItem
, 2)));
2924 str3
[string_length(Field(formItem
, 2))] = 0;
2925 conn
->httpPostStrings
=
2926 curl_slist_append(conn
->httpPostStrings
, str3
);
2928 curl_formadd(&conn
->httpPostFirst
,
2929 &conn
->httpPostLast
,
2932 CURLFORM_NAMELENGTH
,
2933 string_length(Field(formItem
, 0)),
2938 CURLFORM_BUFFERLENGTH
,
2939 string_length(Field(formItem
, 2)),
2942 else if (Is_block(Field(formItem
, 3)))
2944 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2946 String_val(Field(formItem
, 0)),
2947 string_length(Field(formItem
, 0)));
2948 str1
[string_length(Field(formItem
, 0))] = 0;
2949 conn
->httpPostStrings
=
2950 curl_slist_append(conn
->httpPostStrings
, str1
);
2952 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2954 String_val(Field(formItem
, 1)),
2955 string_length(Field(formItem
, 1)));
2956 str2
[string_length(Field(formItem
, 1))] = 0;
2957 conn
->httpPostStrings
=
2958 curl_slist_append(conn
->httpPostStrings
, str2
);
2960 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2962 String_val(Field(formItem
, 2)),
2963 string_length(Field(formItem
, 2)));
2964 str3
[string_length(Field(formItem
, 2))] = 0;
2965 conn
->httpPostStrings
=
2966 curl_slist_append(conn
->httpPostStrings
, str3
);
2968 contentType
= Field(formItem
, 3);
2970 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2972 String_val(Field(contentType
, 0)),
2973 string_length(Field(contentType
, 0)));
2974 str4
[string_length(Field(contentType
, 0))] = 0;
2975 conn
->httpPostStrings
=
2976 curl_slist_append(conn
->httpPostStrings
, str4
);
2978 curl_formadd(&conn
->httpPostFirst
,
2979 &conn
->httpPostLast
,
2982 CURLFORM_NAMELENGTH
,
2983 string_length(Field(formItem
, 0)),
2988 CURLFORM_BUFFERLENGTH
,
2989 string_length(Field(formItem
, 2)),
2990 CURLFORM_CONTENTTYPE
,
2996 failwith("Incorrect CURLFORM_BUFFER parameters");
3001 listIter
= Field(listIter
, 1);
3004 result
= curl_easy_setopt(conn
->connection
,
3006 conn
->httpPostFirst
);
3008 if (result
!= CURLE_OK
)
3009 raiseError(conn
, result
);
3014 static void handleSSLCert(Connection
*conn
, value option
)
3017 CURLcode result
= CURLE_OK
;
3019 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3021 if (conn
->sslCert
!= NULL
)
3022 free(conn
->sslCert
);
3024 conn
->sslCert
= strdup(String_val(option
));
3026 result
= curl_easy_setopt(conn
->connection
,
3030 if (result
!= CURLE_OK
)
3031 raiseError(conn
, result
);
3036 static void handleSSLCertType(Connection
*conn
, value option
)
3039 CURLcode result
= CURLE_OK
;
3041 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3043 if (conn
->sslCertType
!= NULL
)
3044 free(conn
->sslCertType
);
3046 conn
->sslCertType
= strdup(String_val(option
));
3048 result
= curl_easy_setopt(conn
->connection
,
3049 CURLOPT_SSLCERTTYPE
,
3052 if (result
!= CURLE_OK
)
3053 raiseError(conn
, result
);
3058 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3061 CURLcode result
= CURLE_OK
;
3063 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3065 if (conn
->sslCertPasswd
!= NULL
)
3066 free(conn
->sslCertPasswd
);
3068 conn
->sslCertPasswd
= strdup(String_val(option
));
3070 result
= curl_easy_setopt(conn
->connection
,
3071 CURLOPT_SSLCERTPASSWD
,
3072 conn
->sslCertPasswd
);
3074 if (result
!= CURLE_OK
)
3075 raiseError(conn
, result
);
3080 static void handleSSLKey(Connection
*conn
, value option
)
3083 CURLcode result
= CURLE_OK
;
3085 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3087 if (conn
->sslKey
!= NULL
)
3090 conn
->sslKey
= strdup(String_val(option
));
3092 result
= curl_easy_setopt(conn
->connection
,
3096 if (result
!= CURLE_OK
)
3097 raiseError(conn
, result
);
3102 static void handleSSLKeyType(Connection
*conn
, value option
)
3105 CURLcode result
= CURLE_OK
;
3107 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3109 if (conn
->sslKeyType
!= NULL
)
3110 free(conn
->sslKeyType
);
3112 conn
->sslKeyType
= strdup(String_val(option
));
3114 result
= curl_easy_setopt(conn
->connection
,
3118 if (result
!= CURLE_OK
)
3119 raiseError(conn
, result
);
3124 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3127 CURLcode result
= CURLE_OK
;
3129 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3131 if (conn
->sslKeyPasswd
!= NULL
)
3132 free(conn
->sslKeyPasswd
);
3134 conn
->sslKeyPasswd
= strdup(String_val(option
));
3136 result
= curl_easy_setopt(conn
->connection
,
3137 CURLOPT_SSLKEYPASSWD
,
3138 conn
->sslKeyPasswd
);
3140 if (result
!= CURLE_OK
)
3141 raiseError(conn
, result
);
3146 static void handleSSLEngine(Connection
*conn
, value option
)
3149 CURLcode result
= CURLE_OK
;
3151 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3153 if (conn
->sslEngine
!= NULL
)
3154 free(conn
->sslEngine
);
3156 conn
->sslEngine
= strdup(String_val(option
));
3158 result
= curl_easy_setopt(conn
->connection
,
3162 if (result
!= CURLE_OK
)
3163 raiseError(conn
, result
);
3168 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3171 CURLcode result
= CURLE_OK
;
3173 result
= curl_easy_setopt(conn
->connection
,
3174 CURLOPT_SSLENGINE_DEFAULT
,
3177 if (result
!= CURLE_OK
)
3178 raiseError(conn
, result
);
3183 static void handleCRLF(Connection
*conn
, value option
)
3186 CURLcode result
= CURLE_OK
;
3188 result
= curl_easy_setopt(conn
->connection
,
3192 if (result
!= CURLE_OK
)
3193 raiseError(conn
, result
);
3198 static void handleQuote(Connection
*conn
, value option
)
3201 CAMLlocal1(listIter
);
3202 CURLcode result
= CURLE_OK
;
3205 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3207 if (conn
->quote
!= NULL
)
3208 free_curl_slist(conn
->quote
);
3214 while (!Is_long(listIter
))
3216 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3217 failwith("Not a string");
3219 str
= strdup(String_val(Field(listIter
, 0)));
3221 conn
->quote
= curl_slist_append(conn
->quote
, str
);
3223 listIter
= Field(listIter
, 1);
3226 result
= curl_easy_setopt(conn
->connection
,
3230 if (result
!= CURLE_OK
)
3231 raiseError(conn
, result
);
3236 static void handlePostQuote(Connection
*conn
, value option
)
3239 CAMLlocal1(listIter
);
3240 CURLcode result
= CURLE_OK
;
3243 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3245 if (conn
->postQuote
!= NULL
)
3246 free_curl_slist(conn
->postQuote
);
3248 conn
->postQuote
= NULL
;
3252 while (!Is_long(listIter
))
3254 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3255 failwith("Not a string");
3257 str
= strdup(String_val(Field(listIter
, 0)));
3259 conn
->postQuote
= curl_slist_append(conn
->postQuote
, str
);
3261 listIter
= Field(listIter
, 1);
3264 result
= curl_easy_setopt(conn
->connection
,
3268 if (result
!= CURLE_OK
)
3269 raiseError(conn
, result
);
3274 static void handleHeaderFunction(Connection
*conn
, value option
)
3277 CURLcode result
= CURLE_OK
;
3279 if (Tag_val(option
) == Closure_tag
)
3280 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3282 failwith("Not a proper closure");
3284 result
= curl_easy_setopt(conn
->connection
,
3285 CURLOPT_HEADERFUNCTION
,
3288 if (result
!= CURLE_OK
)
3289 raiseError(conn
, result
);
3291 result
= curl_easy_setopt(conn
->connection
,
3292 CURLOPT_WRITEHEADER
,
3295 if (result
!= CURLE_OK
)
3296 raiseError(conn
, result
);
3301 static void handleCookieFile(Connection
*conn
, value option
)
3304 CURLcode result
= CURLE_OK
;
3306 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3308 if (conn
->cookieFile
!= NULL
)
3309 free(conn
->cookieFile
);
3311 conn
->cookieFile
= strdup(String_val(option
));
3313 result
= curl_easy_setopt(conn
->connection
,
3317 if (result
!= CURLE_OK
)
3318 raiseError(conn
, result
);
3323 static void handleSSLVersion(Connection
*conn
, value option
)
3326 CURLcode result
= CURLE_OK
;
3328 result
= curl_easy_setopt(conn
->connection
,
3332 if (result
!= CURLE_OK
)
3333 raiseError(conn
, result
);
3338 static void handleTimeCondition(Connection
*conn
, value option
)
3341 CURLcode result
= CURLE_OK
;
3343 switch (Long_val(option
))
3345 case 0: /* TIMECOND_IFMODSINCE */
3346 result
= curl_easy_setopt(conn
->connection
,
3347 CURLOPT_TIMECONDITION
,
3348 CURL_TIMECOND_IFMODSINCE
);
3351 case 1: /* TIMECOND_IFUNMODSINCE */
3352 result
= curl_easy_setopt(conn
->connection
,
3353 CURLOPT_TIMECONDITION
,
3354 CURL_TIMECOND_IFUNMODSINCE
);
3358 failwith("Invalid TIMECOND Option");
3362 if (result
!= CURLE_OK
)
3363 raiseError(conn
, result
);
3368 static void handleTimeValue(Connection
*conn
, value option
)
3371 CURLcode result
= CURLE_OK
;
3373 result
= curl_easy_setopt(conn
->connection
,
3377 if (result
!= CURLE_OK
)
3378 raiseError(conn
, result
);
3383 static void handleCustomRequest(Connection
*conn
, value option
)
3386 CURLcode result
= CURLE_OK
;
3388 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3390 if (conn
->customRequest
!= NULL
)
3391 free(conn
->customRequest
);
3393 conn
->customRequest
= strdup(String_val(option
));
3395 result
= curl_easy_setopt(conn
->connection
,
3396 CURLOPT_CUSTOMREQUEST
,
3397 conn
->customRequest
);
3399 if (result
!= CURLE_OK
)
3400 raiseError(conn
, result
);
3405 static void handleInterface(Connection
*conn
, value option
)
3408 CURLcode result
= CURLE_OK
;
3410 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3412 if (conn
->interface
!= NULL
)
3413 free(conn
->interface
);
3415 conn
->interface
= strdup(String_val(option
));
3417 result
= curl_easy_setopt(conn
->connection
,
3421 if (result
!= CURLE_OK
)
3422 raiseError(conn
, result
);
3427 static void handleKRB4Level(Connection
*conn
, value option
)
3430 CURLcode result
= CURLE_OK
;
3432 switch (Long_val(option
))
3434 case 0: /* KRB4_NONE */
3435 result
= curl_easy_setopt(conn
->connection
,
3440 case 1: /* KRB4_CLEAR */
3441 result
= curl_easy_setopt(conn
->connection
,
3446 case 2: /* KRB4_SAFE */
3447 result
= curl_easy_setopt(conn
->connection
,
3452 case 3: /* KRB4_CONFIDENTIAL */
3453 result
= curl_easy_setopt(conn
->connection
,
3458 case 4: /* KRB4_PRIVATE */
3459 result
= curl_easy_setopt(conn
->connection
,
3465 failwith("Invalid KRB4 Option");
3469 if (result
!= CURLE_OK
)
3470 raiseError(conn
, result
);
3475 static void handleProgressFunction(Connection
*conn
, value option
)
3478 CURLcode result
= CURLE_OK
;
3480 if (Tag_val(option
) == Closure_tag
)
3481 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3483 failwith("Not a proper closure");
3485 result
= curl_easy_setopt(conn
->connection
,
3486 CURLOPT_PROGRESSFUNCTION
,
3488 if (result
!= CURLE_OK
)
3489 raiseError(conn
, result
);
3491 result
= curl_easy_setopt(conn
->connection
,
3492 CURLOPT_PROGRESSDATA
,
3495 if (result
!= CURLE_OK
)
3496 raiseError(conn
, result
);
3501 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3504 CURLcode result
= CURLE_OK
;
3506 result
= curl_easy_setopt(conn
->connection
,
3507 CURLOPT_SSL_VERIFYPEER
,
3510 if (result
!= CURLE_OK
)
3511 raiseError(conn
, result
);
3516 static void handleCAInfo(Connection
*conn
, value option
)
3519 CURLcode result
= CURLE_OK
;
3521 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3523 if (conn
->caInfo
!= NULL
)
3526 conn
->caInfo
= strdup(String_val(option
));
3528 result
= curl_easy_setopt(conn
->connection
,
3532 if (result
!= CURLE_OK
)
3533 raiseError(conn
, result
);
3538 static void handleCAPath(Connection
*conn
, value option
)
3541 CURLcode result
= CURLE_OK
;
3543 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3545 if (conn
->caPath
!= NULL
)
3548 conn
->caPath
= strdup(String_val(option
));
3550 result
= curl_easy_setopt(conn
->connection
,
3554 if (result
!= CURLE_OK
)
3555 raiseError(conn
, result
);
3560 static void handleFileTime(Connection
*conn
, value option
)
3563 CURLcode result
= CURLE_OK
;
3565 result
= curl_easy_setopt(conn
->connection
,
3569 if (result
!= CURLE_OK
)
3570 raiseError(conn
, result
);
3575 static void handleMaxRedirs(Connection
*conn
, value option
)
3578 CURLcode result
= CURLE_OK
;
3580 result
= curl_easy_setopt(conn
->connection
,
3584 if (result
!= CURLE_OK
)
3585 raiseError(conn
, result
);
3590 static void handleMaxConnects(Connection
*conn
, value option
)
3593 CURLcode result
= CURLE_OK
;
3595 result
= curl_easy_setopt(conn
->connection
,
3596 CURLOPT_MAXCONNECTS
,
3599 if (result
!= CURLE_OK
)
3600 raiseError(conn
, result
);
3605 static void handleClosePolicy(Connection
*conn
, value option
)
3608 CURLcode result
= CURLE_OK
;
3610 switch (Long_val(option
))
3612 case 0: /* CLOSEPOLICY_OLDEST */
3613 result
= curl_easy_setopt(conn
->connection
,
3614 CURLOPT_CLOSEPOLICY
,
3615 CURLCLOSEPOLICY_OLDEST
);
3618 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3619 result
= curl_easy_setopt(conn
->connection
,
3620 CURLOPT_CLOSEPOLICY
,
3621 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3625 failwith("Invalid CLOSEPOLICY Option");
3629 if (result
!= CURLE_OK
)
3630 raiseError(conn
, result
);
3635 static void handleFreshConnect(Connection
*conn
, value option
)
3638 CURLcode result
= CURLE_OK
;
3640 result
= curl_easy_setopt(conn
->connection
,
3641 CURLOPT_FRESH_CONNECT
,
3644 if (result
!= CURLE_OK
)
3645 raiseError(conn
, result
);
3650 static void handleForbidReuse(Connection
*conn
, value option
)
3653 CURLcode result
= CURLE_OK
;
3655 result
= curl_easy_setopt(conn
->connection
,
3656 CURLOPT_FORBID_REUSE
,
3659 if (result
!= CURLE_OK
)
3660 raiseError(conn
, result
);
3665 static void handleRandomFile(Connection
*conn
, value option
)
3668 CURLcode result
= CURLE_OK
;
3670 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3672 if (conn
->randomFile
!= NULL
)
3673 free(conn
->randomFile
);
3675 conn
->randomFile
= strdup(String_val(option
));
3677 result
= curl_easy_setopt(conn
->connection
,
3678 CURLOPT_RANDOM_FILE
,
3681 if (result
!= CURLE_OK
)
3682 raiseError(conn
, result
);
3687 static void handleEGDSocket(Connection
*conn
, value option
)
3690 CURLcode result
= CURLE_OK
;
3692 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3694 if (conn
->egdSocket
!= NULL
)
3695 free(conn
->egdSocket
);
3697 conn
->egdSocket
= strdup(String_val(option
));
3699 result
= curl_easy_setopt(conn
->connection
,
3703 if (result
!= CURLE_OK
)
3704 raiseError(conn
, result
);
3709 static void handleConnectTimeout(Connection
*conn
, value option
)
3712 CURLcode result
= CURLE_OK
;
3714 result
= curl_easy_setopt(conn
->connection
,
3715 CURLOPT_CONNECTTIMEOUT
,
3718 if (result
!= CURLE_OK
)
3719 raiseError(conn
, result
);
3724 static void handleHTTPGet(Connection
*conn
, value option
)
3727 CURLcode result
= CURLE_OK
;
3729 result
= curl_easy_setopt(conn
->connection
,
3733 if (result
!= CURLE_OK
)
3734 raiseError(conn
, result
);
3739 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3742 CURLcode result
= CURLE_OK
;
3744 switch (Long_val(option
))
3746 case 0: /* SSLVERIFYHOST_EXISTENCE */
3747 result
= curl_easy_setopt(conn
->connection
,
3748 CURLOPT_SSL_VERIFYHOST
,
3752 case 1: /* SSLVERIFYHOST_HOSTNAME */
3753 result
= curl_easy_setopt(conn
->connection
,
3754 CURLOPT_SSL_VERIFYHOST
,
3759 failwith("Invalid SSLVERIFYHOST Option");
3763 if (result
!= CURLE_OK
)
3764 raiseError(conn
, result
);
3769 static void handleCookieJar(Connection
*conn
, value option
)
3772 CURLcode result
= CURLE_OK
;
3774 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3776 if (conn
->cookieJar
!= NULL
)
3777 free(conn
->cookieJar
);
3779 conn
->cookieJar
= strdup(String_val(option
));
3781 result
= curl_easy_setopt(conn
->connection
,
3785 if (result
!= CURLE_OK
)
3786 raiseError(conn
, result
);
3791 static void handleSSLCipherList(Connection
*conn
, value option
)
3794 CURLcode result
= CURLE_OK
;
3796 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3798 if (conn
->sslCipherList
!= NULL
)
3799 free(conn
->sslCipherList
);
3801 conn
->sslCipherList
= strdup(String_val(option
));
3803 result
= curl_easy_setopt(conn
->connection
,
3804 CURLOPT_SSL_CIPHER_LIST
,
3805 conn
->sslCipherList
);
3807 if (result
!= CURLE_OK
)
3808 raiseError(conn
, result
);
3813 static void handleHTTPVersion(Connection
*conn
, value option
)
3816 CURLcode result
= CURLE_OK
;
3818 switch (Long_val(option
))
3820 case 0: /* HTTP_VERSION_NONE */
3821 result
= curl_easy_setopt(conn
->connection
,
3822 CURLOPT_HTTP_VERSION
,
3823 CURL_HTTP_VERSION_NONE
);
3826 case 1: /* HTTP_VERSION_1_0 */
3827 result
= curl_easy_setopt(conn
->connection
,
3828 CURLOPT_HTTP_VERSION
,
3829 CURL_HTTP_VERSION_1_0
);
3832 case 2: /* HTTP_VERSION_1_1 */
3833 result
= curl_easy_setopt(conn
->connection
,
3834 CURLOPT_HTTP_VERSION
,
3835 CURL_HTTP_VERSION_1_1
);
3839 failwith("Invalid HTTP_VERSION Option");
3843 if (result
!= CURLE_OK
)
3844 raiseError(conn
, result
);
3849 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3852 CURLcode result
= CURLE_OK
;
3854 result
= curl_easy_setopt(conn
->connection
,
3855 CURLOPT_FTP_USE_EPSV
,
3858 if (result
!= CURLE_OK
)
3859 raiseError(conn
, result
);
3864 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3867 CURLcode result
= CURLE_OK
;
3869 result
= curl_easy_setopt(conn
->connection
,
3870 CURLOPT_DNS_CACHE_TIMEOUT
,
3873 if (result
!= CURLE_OK
)
3874 raiseError(conn
, result
);
3879 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3882 CURLcode result
= CURLE_OK
;
3884 result
= curl_easy_setopt(conn
->connection
,
3885 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3888 if (result
!= CURLE_OK
)
3889 raiseError(conn
, result
);
3894 static void handleDebugFunction(Connection
*conn
, value option
)
3897 CURLcode result
= CURLE_OK
;
3899 if (Tag_val(option
) == Closure_tag
)
3900 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3902 failwith("Not a proper closure");
3904 result
= curl_easy_setopt(conn
->connection
,
3905 CURLOPT_DEBUGFUNCTION
,
3907 if (result
!= CURLE_OK
)
3908 raiseError(conn
, result
);
3910 result
= curl_easy_setopt(conn
->connection
,
3914 if (result
!= CURLE_OK
)
3915 raiseError(conn
, result
);
3920 static void handlePrivate(Connection
*conn
, value option
)
3922 #if HAVE_DECL_CURLOPT_PRIVATE
3924 CURLcode result
= CURLE_OK
;
3926 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
3928 if (conn
->private != NULL
)
3929 free(conn
->private);
3931 conn
->private = strdup(String_val(option
));
3933 result
= curl_easy_setopt(conn
->connection
,
3937 if (result
!= CURLE_OK
)
3938 raiseError(conn
, result
);
3942 #warning "libcurl does not implement CURLOPT_PRIVATE"
3943 failwith("libcurl does not implement CURLOPT_PRIVATE");
3947 static void handleHTTP200Aliases(Connection
*conn
, value option
)
3949 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3951 CAMLlocal1(listIter
);
3952 CURLcode result
= CURLE_OK
;
3955 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
3957 if (conn
->http200Aliases
!= NULL
)
3958 free_curl_slist(conn
->http200Aliases
);
3960 conn
->http200Aliases
= NULL
;
3964 while (!Is_long(listIter
))
3966 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3967 failwith("Not a string");
3969 str
= strdup(String_val(Field(listIter
, 0)));
3971 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, str
);
3973 listIter
= Field(listIter
, 1);
3976 result
= curl_easy_setopt(conn
->connection
,
3977 CURLOPT_HTTP200ALIASES
,
3978 conn
->http200Aliases
);
3980 if (result
!= CURLE_OK
)
3981 raiseError(conn
, result
);
3985 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
3986 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
3990 static void handleUnrestrictedAuth(Connection
*conn
, value option
)
3992 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
3994 CURLcode result
= CURLE_OK
;
3996 result
= curl_easy_setopt(conn
->connection
,
3997 CURLOPT_UNRESTRICTED_AUTH
,
4000 if (result
!= CURLE_OK
)
4001 raiseError(conn
, result
);
4005 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4006 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4010 static void handleFTPUseEPRT(Connection
*conn
, value option
)
4012 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4014 CURLcode result
= CURLE_OK
;
4016 result
= curl_easy_setopt(conn
->connection
,
4017 CURLOPT_FTP_USE_EPRT
,
4020 if (result
!= CURLE_OK
)
4021 raiseError(conn
, result
);
4025 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4026 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4030 static void handleHTTPAuth(Connection
*conn
, value option
)
4032 #if HAVE_DECL_CURLOPT_HTTPAUTH
4034 CAMLlocal1(listIter
);
4035 CURLcode result
= CURLE_OK
;
4036 long auth
= CURLAUTH_NONE
;
4040 while (!Is_long(listIter
))
4042 switch (Long_val(Field(listIter
, 0)))
4044 case 0: /* CURLAUTH_BASIC */
4045 auth
|= CURLAUTH_BASIC
;
4048 case 1: /* CURLAUTH_DIGEST */
4049 auth
|= CURLAUTH_DIGEST
;
4052 case 2: /* CURLAUTH_GSSNEGOTIATE */
4053 auth
|= CURLAUTH_GSSNEGOTIATE
;
4056 case 3: /* CURLAUTH_NTLM */
4057 auth
|= CURLAUTH_NTLM
;
4060 case 4: /* CURLAUTH_ANY */
4061 auth
|= CURLAUTH_ANY
;
4064 case 5: /* CURLAUTH_ANYSAFE */
4065 auth
|= CURLAUTH_ANYSAFE
;
4069 failwith("Invalid HTTPAUTH Value");
4073 listIter
= Field(listIter
, 1);
4076 result
= curl_easy_setopt(conn
->connection
,
4080 if (result
!= CURLE_OK
)
4081 raiseError(conn
, result
);
4085 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4086 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4090 static void handleFTPCreateMissingDirs(Connection
*conn
, value option
)
4092 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4094 CURLcode result
= CURLE_OK
;
4096 result
= curl_easy_setopt(conn
->connection
,
4097 CURLOPT_FTP_CREATE_MISSING_DIRS
,
4100 if (result
!= CURLE_OK
)
4101 raiseError(conn
, result
);
4105 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4106 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4110 static void handleProxyAuth(Connection
*conn
, value option
)
4112 #if HAVE_DECL_CURLOPT_PROXYAUTH
4114 CAMLlocal1(listIter
);
4115 CURLcode result
= CURLE_OK
;
4116 long auth
= CURLAUTH_NONE
;
4120 while (!Is_long(listIter
))
4122 switch (Long_val(Field(listIter
, 0)))
4124 case 0: /* CURLAUTH_BASIC */
4125 auth
|= CURLAUTH_BASIC
;
4128 case 1: /* CURLAUTH_DIGEST */
4129 auth
|= CURLAUTH_DIGEST
;
4132 case 2: /* CURLAUTH_GSSNEGOTIATE */
4133 auth
|= CURLAUTH_GSSNEGOTIATE
;
4136 case 3: /* CURLAUTH_NTLM */
4137 auth
|= CURLAUTH_NTLM
;
4140 case 4: /* CURLAUTH_ANY */
4141 auth
|= CURLAUTH_ANY
;
4144 case 5: /* CURLAUTH_ANYSAFE */
4145 auth
|= CURLAUTH_ANYSAFE
;
4149 failwith("Invalid HTTPAUTH Value");
4153 listIter
= Field(listIter
, 1);
4156 result
= curl_easy_setopt(conn
->connection
,
4160 if (result
!= CURLE_OK
)
4161 raiseError(conn
, result
);
4165 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4166 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4170 static void handleFTPResponseTimeout(Connection
*conn
, value option
)
4172 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4174 CURLcode result
= CURLE_OK
;
4176 result
= curl_easy_setopt(conn
->connection
,
4177 CURLOPT_FTP_RESPONSE_TIMEOUT
,
4180 if (result
!= CURLE_OK
)
4181 raiseError(conn
, result
);
4185 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4186 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4190 static void handleIPResolve(Connection
*conn
, value option
)
4192 #if HAVE_DECL_CURLOPT_IPRESOLVE
4194 CURLcode result
= CURLE_OK
;
4196 switch (Long_val(option
))
4198 case 0: /* CURL_IPRESOLVE_WHATEVER */
4199 result
= curl_easy_setopt(conn
->connection
,
4201 CURL_IPRESOLVE_WHATEVER
);
4204 case 1: /* CURL_IPRESOLVE_V4 */
4205 result
= curl_easy_setopt(conn
->connection
,
4210 case 2: /* CURL_IPRESOLVE_V6 */
4211 result
= curl_easy_setopt(conn
->connection
,
4217 failwith("Invalid IPRESOLVE Value");
4221 if (result
!= CURLE_OK
)
4222 raiseError(conn
, result
);
4226 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4227 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4231 static void handleMaxFileSize(Connection
*conn
, value option
)
4233 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4235 CURLcode result
= CURLE_OK
;
4237 result
= curl_easy_setopt(conn
->connection
,
4238 CURLOPT_MAXFILESIZE
,
4241 if (result
!= CURLE_OK
)
4242 raiseError(conn
, result
);
4246 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4247 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4251 static void handleInFileSizeLarge(Connection
*conn
, value option
)
4253 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4255 CURLcode result
= CURLE_OK
;
4257 result
= curl_easy_setopt(conn
->connection
,
4258 CURLOPT_INFILESIZE_LARGE
,
4261 if (result
!= CURLE_OK
)
4262 raiseError(conn
, result
);
4266 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4267 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4271 static void handleResumeFromLarge(Connection
*conn
, value option
)
4273 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4275 CURLcode result
= CURLE_OK
;
4277 result
= curl_easy_setopt(conn
->connection
,
4278 CURLOPT_RESUME_FROM_LARGE
,
4281 if (result
!= CURLE_OK
)
4282 raiseError(conn
, result
);
4286 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4287 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4291 static void handleMaxFileSizeLarge(Connection
*conn
, value option
)
4293 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4295 CURLcode result
= CURLE_OK
;
4297 result
= curl_easy_setopt(conn
->connection
,
4298 CURLOPT_MAXFILESIZE_LARGE
,
4301 if (result
!= CURLE_OK
)
4302 raiseError(conn
, result
);
4306 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4307 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4311 static void handleNETRCFile(Connection
*conn
, value option
)
4313 #if HAVE_DECL_CURLOPT_NETRC_FILE
4315 CURLcode result
= CURLE_OK
;
4317 Store_field(conn
->ocamlValues
, OcamlNETRCFile
, option
);
4319 if (conn
->netrcFile
!= NULL
)
4320 free(conn
->netrcFile
);
4322 conn
->netrcFile
= strdup(String_val(option
));
4324 result
= curl_easy_setopt(conn
->connection
,
4328 if (result
!= CURLE_OK
)
4329 raiseError(conn
, result
);
4333 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4334 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4338 static void handleFTPSSL(Connection
*conn
, value option
)
4340 #if HAVE_DECL_CURLOPT_FTP_SSL
4342 CURLcode result
= CURLE_OK
;
4344 switch (Long_val(option
))
4346 case 0: /* CURLFTPSSL_NONE */
4347 result
= curl_easy_setopt(conn
->connection
,
4352 case 1: /* CURLFTPSSL_TRY */
4353 result
= curl_easy_setopt(conn
->connection
,
4358 case 2: /* CURLFTPSSL_CONTROL */
4359 result
= curl_easy_setopt(conn
->connection
,
4361 CURLFTPSSL_CONTROL
);
4364 case 3: /* CURLFTPSSL_ALL */
4365 result
= curl_easy_setopt(conn
->connection
,
4371 failwith("Invalid FTP_SSL Value");
4375 if (result
!= CURLE_OK
)
4376 raiseError(conn
, result
);
4380 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4381 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4385 static void handlePostFieldSizeLarge(Connection
*conn
, value option
)
4387 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4389 CURLcode result
= CURLE_OK
;
4391 result
= curl_easy_setopt(conn
->connection
,
4392 CURLOPT_POSTFIELDSIZE_LARGE
,
4395 if (result
!= CURLE_OK
)
4396 raiseError(conn
, result
);
4400 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4401 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4405 static void handleTCPNoDelay(Connection
*conn
, value option
)
4407 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4409 CURLcode result
= CURLE_OK
;
4411 result
= curl_easy_setopt(conn
->connection
,
4412 CURLOPT_TCP_NODELAY
,
4415 if (result
!= CURLE_OK
)
4416 raiseError(conn
, result
);
4420 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4421 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4425 static void handleFTPSSLAuth(Connection
*conn
, value option
)
4427 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4429 CURLcode result
= CURLE_OK
;
4431 switch (Long_val(option
))
4433 case 0: /* CURLFTPAUTH_DEFAULT */
4434 result
= curl_easy_setopt(conn
->connection
,
4436 CURLFTPAUTH_DEFAULT
);
4439 case 1: /* CURLFTPAUTH_SSL */
4440 result
= curl_easy_setopt(conn
->connection
,
4445 case 2: /* CURLFTPAUTH_TLS */
4446 result
= curl_easy_setopt(conn
->connection
,
4452 failwith("Invalid FTPSSLAUTH value");
4456 if (result
!= CURLE_OK
)
4457 raiseError(conn
, result
);
4461 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4462 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4466 static void handleIOCTLFunction(Connection
*conn
, value option
)
4468 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4470 CURLcode result
= CURLE_OK
;
4472 if (Tag_val(option
) == Closure_tag
)
4473 Store_field(conn
->ocamlValues
, OcamlIOCTLCallback
, option
);
4475 failwith("Not a proper closure");
4477 result
= curl_easy_setopt(conn
->connection
,
4478 CURLOPT_IOCTLFUNCTION
,
4480 if (result
!= CURLE_OK
)
4481 raiseError(conn
, result
);
4483 result
= curl_easy_setopt(conn
->connection
,
4487 if (result
!= CURLE_OK
)
4488 raiseError(conn
, result
);
4492 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4493 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4497 static void handleFTPAccount(Connection
*conn
, value option
)
4499 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4501 CURLcode result
= CURLE_OK
;
4503 Store_field(conn
->ocamlValues
, OcamlFTPAccount
, option
);
4505 if (conn
->ftpaccount
!= NULL
)
4506 free(conn
->ftpaccount
);
4508 conn
->ftpaccount
= strdup(String_val(option
));
4510 result
= curl_easy_setopt(conn
->connection
,
4511 CURLOPT_FTP_ACCOUNT
,
4514 if (result
!= CURLE_OK
)
4515 raiseError(conn
, result
);
4519 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4520 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4524 static void handleCookieList(Connection
*conn
, value option
)
4526 #if HAVE_DECL_CURLOPT_COOKIELIST
4528 CURLcode result
= CURLE_OK
;
4530 Store_field(conn
->ocamlValues
, OcamlCookieList
, option
);
4532 if (conn
->cookielist
!= NULL
)
4533 free(conn
->cookielist
);
4535 conn
->cookielist
= strdup(String_val(option
));
4537 result
= curl_easy_setopt(conn
->connection
,
4541 if (result
!= CURLE_OK
)
4542 raiseError(conn
, result
);
4546 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4547 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4551 static void handleIgnoreContentLength(Connection
*conn
, value option
)
4553 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4555 CURLcode result
= CURLE_OK
;
4557 result
= curl_easy_setopt(conn
->connection
,
4558 CURLOPT_IGNORE_CONTENT_LENGTH
,
4561 if (result
!= CURLE_OK
)
4562 raiseError(conn
, result
);
4566 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4567 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4571 static void handleFTPSkipPASVIP(Connection
*conn
, value option
)
4573 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4575 CURLcode result
= CURLE_OK
;
4577 result
= curl_easy_setopt(conn
->connection
,
4578 CURLOPT_FTP_SKIP_PASV_IP
,
4581 if (result
!= CURLE_OK
)
4582 raiseError(conn
, result
);
4586 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4587 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4591 static void handleFTPFileMethod(Connection
*conn
, value option
)
4593 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4595 CURLcode result
= CURLE_OK
;
4597 switch (Long_val(option
))
4599 case 0: /* CURLFTPMETHOD_DEFAULT */
4600 result
= curl_easy_setopt(conn
->connection
,
4601 CURLOPT_FTP_FILEMETHOD
,
4602 CURLFTPMETHOD_DEFAULT
);
4605 case 1: /* CURLFTMETHOD_MULTICWD */
4606 result
= curl_easy_setopt(conn
->connection
,
4607 CURLOPT_FTP_FILEMETHOD
,
4608 CURLFTPMETHOD_MULTICWD
);
4611 case 2: /* CURLFTPMETHOD_NOCWD */
4612 result
= curl_easy_setopt(conn
->connection
,
4613 CURLOPT_FTP_FILEMETHOD
,
4614 CURLFTPMETHOD_NOCWD
);
4617 case 3: /* CURLFTPMETHOD_SINGLECWD */
4618 result
= curl_easy_setopt(conn
->connection
,
4619 CURLOPT_FTP_FILEMETHOD
,
4620 CURLFTPMETHOD_SINGLECWD
);
4623 failwith("Invalid FTP_FILEMETHOD value");
4627 if (result
!= CURLE_OK
)
4628 raiseError(conn
, result
);
4632 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4633 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4637 static void handleLocalPort(Connection
*conn
, value option
)
4639 #if HAVE_DECL_CURLOPT_LOCALPORT
4641 CURLcode result
= CURLE_OK
;
4643 result
= curl_easy_setopt(conn
->connection
,
4647 if (result
!= CURLE_OK
)
4648 raiseError(conn
, result
);
4652 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4653 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4657 static void handleLocalPortRange(Connection
*conn
, value option
)
4659 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4661 CURLcode result
= CURLE_OK
;
4663 result
= curl_easy_setopt(conn
->connection
,
4664 CURLOPT_LOCALPORTRANGE
,
4667 if (result
!= CURLE_OK
)
4668 raiseError(conn
, result
);
4672 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4673 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4677 static void handleConnectOnly(Connection
*conn
, value option
)
4679 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4681 CURLcode result
= CURLE_OK
;
4683 result
= curl_easy_setopt(conn
->connection
,
4684 CURLOPT_CONNECT_ONLY
,
4687 if (result
!= CURLE_OK
)
4688 raiseError(conn
, result
);
4692 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4693 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4697 static void handleMaxSendSpeedLarge(Connection
*conn
, value option
)
4699 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4701 CURLcode result
= CURLE_OK
;
4703 result
= curl_easy_setopt(conn
->connection
,
4704 CURLOPT_MAX_SEND_SPEED_LARGE
,
4707 if (result
!= CURLE_OK
)
4708 raiseError(conn
, result
);
4712 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4713 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4717 static void handleMaxRecvSpeedLarge(Connection
*conn
, value option
)
4719 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4721 CURLcode result
= CURLE_OK
;
4723 result
= curl_easy_setopt(conn
->connection
,
4724 CURLOPT_MAX_RECV_SPEED_LARGE
,
4727 if (result
!= CURLE_OK
)
4728 raiseError(conn
, result
);
4732 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4733 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4737 static void handleFTPAlternativeToUser(Connection
*conn
, value option
)
4739 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4741 CURLcode result
= CURLE_OK
;
4743 Store_field(conn
->ocamlValues
, OcamlFTPAlternativeToUser
, option
);
4745 if (conn
->ftpAlternativeToUser
!= NULL
)
4746 free(conn
->ftpAlternativeToUser
);
4748 conn
->ftpAlternativeToUser
= strdup(String_val(option
));
4750 result
= curl_easy_setopt(conn
->connection
,
4751 CURLOPT_FTP_ALTERNATIVE_TO_USER
,
4752 conn
->ftpAlternativeToUser
);
4754 if (result
!= CURLE_OK
)
4755 raiseError(conn
, result
);
4759 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4760 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4764 static void handleSSLSessionIdCache(Connection
*conn
, value option
)
4766 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4768 CURLcode result
= CURLE_OK
;
4770 result
= curl_easy_setopt(conn
->connection
,
4771 CURLOPT_SSL_SESSIONID_CACHE
,
4774 if (result
!= CURLE_OK
)
4775 raiseError(conn
, result
);
4779 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4780 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4784 static void handleSSHAuthTypes(Connection
*conn
, value option
)
4786 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4788 CAMLlocal1(listIter
);
4789 CURLcode result
= CURLE_OK
;
4790 long authTypes
= CURLSSH_AUTH_NONE
;
4794 while (!Is_long(listIter
))
4796 switch (Long_val(Field(listIter
, 0)))
4798 case 0: /* CURLSSH_AUTH_ANY */
4799 authTypes
|= CURLSSH_AUTH_ANY
;
4802 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4803 authTypes
|= CURLSSH_AUTH_PUBLICKEY
;
4806 case 2: /* CURLSSH_AUTH_PASSWORD */
4807 authTypes
|= CURLSSH_AUTH_PASSWORD
;
4810 case 3: /* CURLSSH_AUTH_HOST */
4811 authTypes
|= CURLSSH_AUTH_HOST
;
4814 case 4: /* CURLSSH_AUTH_KEYBOARD */
4815 authTypes
|= CURLSSH_AUTH_KEYBOARD
;
4819 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4823 listIter
= Field(listIter
, 1);
4826 result
= curl_easy_setopt(conn
->connection
,
4827 CURLOPT_SSH_AUTH_TYPES
,
4830 if (result
!= CURLE_OK
)
4831 raiseError(conn
, result
);
4835 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4836 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4840 static void handleSSHPublicKeyFile(Connection
*conn
, value option
)
4842 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4844 CURLcode result
= CURLE_OK
;
4846 Store_field(conn
->ocamlValues
, OcamlSSHPublicKeyFile
, option
);
4848 if (conn
->sshPublicKeyFile
!= NULL
)
4849 free(conn
->sshPublicKeyFile
);
4851 conn
->sshPublicKeyFile
= strdup(String_val(option
));
4853 result
= curl_easy_setopt(conn
->connection
,
4854 CURLOPT_SSH_PUBLIC_KEYFILE
,
4855 conn
->sshPublicKeyFile
);
4857 if (result
!= CURLE_OK
)
4858 raiseError(conn
, result
);
4862 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4863 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4867 static void handleSSHPrivateKeyFile(Connection
*conn
, value option
)
4869 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4871 CURLcode result
= CURLE_OK
;
4873 Store_field(conn
->ocamlValues
, OcamlSSHPrivateKeyFile
, option
);
4875 if (conn
->sshPrivateKeyFile
!= NULL
)
4876 free(conn
->sshPrivateKeyFile
);
4878 conn
->sshPrivateKeyFile
= strdup(String_val(option
));
4880 result
= curl_easy_setopt(conn
->connection
,
4881 CURLOPT_SSH_PRIVATE_KEYFILE
,
4882 conn
->sshPrivateKeyFile
);
4884 if (result
!= CURLE_OK
)
4885 raiseError(conn
, result
);
4889 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4890 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4894 static void handleFTPSSLCCC(Connection
*conn
, value option
)
4896 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4898 CURLcode result
= CURLE_OK
;
4900 switch (Long_val(option
))
4902 case 0: /* CURLFTPSSL_CCC_NONE */
4903 result
= curl_easy_setopt(conn
->connection
,
4904 CURLOPT_FTP_SSL_CCC
,
4905 CURLFTPSSL_CCC_NONE
);
4908 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4909 result
= curl_easy_setopt(conn
->connection
,
4910 CURLOPT_FTP_SSL_CCC
,
4911 CURLFTPSSL_CCC_PASSIVE
);
4914 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4915 result
= curl_easy_setopt(conn
->connection
,
4916 CURLOPT_FTP_SSL_CCC
,
4917 CURLFTPSSL_CCC_ACTIVE
);
4921 failwith("Invalid FTPSSL_CCC value");
4925 if (result
!= CURLE_OK
)
4926 raiseError(conn
, result
);
4930 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4931 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4935 static void handleTimeoutMS(Connection
*conn
, value option
)
4937 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4939 CURLcode result
= CURLE_OK
;
4941 result
= curl_easy_setopt(conn
->connection
,
4945 if (result
!= CURLE_OK
)
4946 raiseError(conn
, result
);
4950 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4951 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4955 static void handleConnectTimeoutMS(Connection
*conn
, value option
)
4957 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4959 CURLcode result
= CURLE_OK
;
4961 result
= curl_easy_setopt(conn
->connection
,
4962 CURLOPT_CONNECTTIMEOUT_MS
,
4965 if (result
!= CURLE_OK
)
4966 raiseError(conn
, result
);
4970 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4971 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
4975 static void handleHTTPTransferDecoding(Connection
*conn
, value option
)
4977 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
4979 CURLcode result
= CURLE_OK
;
4981 result
= curl_easy_setopt(conn
->connection
,
4982 CURLOPT_HTTP_TRANSFER_DECODING
,
4985 if (result
!= CURLE_OK
)
4986 raiseError(conn
, result
);
4990 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
4991 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
4995 static void handleHTTPContentDecoding(Connection
*conn
, value option
)
4997 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
4999 CURLcode result
= CURLE_OK
;
5001 result
= curl_easy_setopt(conn
->connection
,
5002 CURLOPT_HTTP_CONTENT_DECODING
,
5005 if (result
!= CURLE_OK
)
5006 raiseError(conn
, result
);
5010 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5011 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5015 static void handleNewFilePerms(Connection
*conn
, value option
)
5017 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5019 CURLcode result
= CURLE_OK
;
5021 result
= curl_easy_setopt(conn
->connection
,
5022 CURLOPT_NEW_FILE_PERMS
,
5025 if (result
!= CURLE_OK
)
5026 raiseError(conn
, result
);
5030 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5031 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5035 static void handleNewDirectoryPerms(Connection
*conn
, value option
)
5037 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5039 CURLcode result
= CURLE_OK
;
5041 result
= curl_easy_setopt(conn
->connection
,
5042 CURLOPT_NEW_DIRECTORY_PERMS
,
5045 if (result
!= CURLE_OK
)
5046 raiseError(conn
, result
);
5050 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5051 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5055 static void handlePost301(Connection
*conn
, value option
)
5057 #if HAVE_DECL_CURLOPT_POST301
5059 CURLcode result
= CURLE_OK
;
5061 result
= curl_easy_setopt(conn
->connection
,
5065 if (result
!= CURLE_OK
)
5066 raiseError(conn
, result
);
5070 #warning "libcurl does not implement CURLOPT_POST301"
5071 failwith("libcurl does not implement CURLOPT_POST301");
5075 static void handleSSHHostPublicKeyMD5(Connection
*conn
, value option
)
5077 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5079 CURLcode result
= CURLE_OK
;
5081 Store_field(conn
->ocamlValues
, OcamlSSHHostPublicKeyMD5
, option
);
5083 if (conn
->sshHostPublicKeyMD5
!= NULL
)
5084 free(conn
->sshHostPublicKeyMD5
);
5086 conn
->sshHostPublicKeyMD5
= strdup(String_val(option
));
5088 result
= curl_easy_setopt(conn
->connection
,
5089 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
,
5090 conn
->sshHostPublicKeyMD5
);
5092 if (result
!= CURLE_OK
)
5093 raiseError(conn
, result
);
5097 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5098 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5102 static void handleCopyPostFields(Connection
*conn
, value option
)
5104 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5106 CURLcode result
= CURLE_OK
;
5108 Store_field(conn
->ocamlValues
, OcamlCopyPostFields
, option
);
5110 if (conn
->copyPostFields
!= NULL
)
5111 free(conn
->copyPostFields
);
5113 conn
->copyPostFields
= strdup(String_val(option
));
5115 result
= curl_easy_setopt(conn
->connection
,
5116 CURLOPT_COPYPOSTFIELDS
,
5117 conn
->copyPostFields
);
5119 if (result
!= CURLE_OK
)
5120 raiseError(conn
, result
);
5124 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5125 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5129 static void handleProxyTransferMode(Connection
*conn
, value option
)
5131 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5133 CURLcode result
= CURLE_OK
;
5135 result
= curl_easy_setopt(conn
->connection
,
5136 CURLOPT_PROXY_TRANSFER_MODE
,
5139 if (result
!= CURLE_OK
)
5140 raiseError(conn
, result
);
5144 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5145 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5149 static void handleSeekFunction(Connection
*conn
, value option
)
5151 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5153 CURLcode result
= CURLE_OK
;
5155 if (Tag_val(option
) == Closure_tag
)
5156 Store_field(conn
->ocamlValues
, OcamlSeekFunctionCallback
, option
);
5158 failwith("Not a proper closure");
5160 result
= curl_easy_setopt(conn
->connection
,
5161 CURLOPT_SEEKFUNCTION
,
5164 if (result
!= CURLE_OK
)
5165 raiseError(conn
, result
);
5167 result
= curl_easy_setopt(conn
->connection
,
5171 if (result
!= CURLE_OK
)
5172 raiseError(conn
, result
);
5176 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5177 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5182 ** curl_easy_setopt helper function
5185 CAMLprim value
helper_curl_easy_setopt(value conn
, value option
)
5187 CAMLparam2(conn
, option
);
5189 Connection
*connection
= Connection_val(conn
);
5191 checkConnection(connection
);
5193 if (Is_long(option
))
5197 sprintf(error
, "Unimplemented Option: %s",
5198 findOption(unimplementedOptionMap
,
5199 (CURLoption
)(Long_val(option
))));
5204 if (!Is_block(option
))
5205 failwith("Not a block");
5207 if (Wosize_val(option
) < 1)
5208 failwith("Insufficient data in block");
5210 data
= Field(option
, 0);
5212 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5213 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5216 failwith("Invalid CURLOPT Option");
5218 CAMLreturn(Val_unit
);
5222 ** curl_easy_perform helper function
5225 CAMLprim value
helper_curl_easy_perform(value conn
)
5228 CURLcode result
= CURLE_OK
;
5229 Connection
*connection
= Connection_val(conn
);
5231 checkConnection(connection
);
5233 enter_blocking_section();
5234 result
= curl_easy_perform(connection
->connection
);
5235 leave_blocking_section();
5237 if (result
!= CURLE_OK
)
5238 raiseError(connection
, result
);
5240 CAMLreturn(Val_unit
);
5244 ** curl_easy_cleanup helper function
5247 CAMLprim value
helper_curl_easy_cleanup(value conn
)
5250 Connection
*connection
= Connection_val(conn
);
5252 checkConnection(connection
);
5254 removeConnection(connection
);
5256 CAMLreturn(Val_unit
);
5260 ** curl_easy_duphandle helper function
5263 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5267 Connection
*connection
= Connection_val(conn
);
5269 checkConnection(connection
);
5271 result
= caml_alloc(1, Abstract_tag
);
5272 Field(result
, 0) = (value
)duplicateConnection(connection
);
5278 ** curl_easy_getinfo helper function
5281 enum GetInfoResultType
{
5282 StringValue
, LongValue
, DoubleValue
, StringListValue
5285 value
convertStringList(struct curl_slist
*slist
)
5288 CAMLlocal3(result
, current
, next
);
5289 struct curl_slist
*p
= slist
;
5291 result
= Val_int(0);
5292 current
= Val_int(0);
5297 next
= alloc_tuple(2);
5298 Store_field(next
, 0, copy_string(p
->data
));
5299 Store_field(next
, 1, Val_int(0));
5301 if (result
== Val_int(0))
5304 if (current
!= Val_int(0))
5305 Store_field(current
, 1, next
);
5312 curl_slist_free_all(slist
);
5317 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5319 CAMLparam2(conn
, option
);
5321 CURLcode curlResult
;
5322 Connection
*connection
= Connection_val(conn
);
5323 enum GetInfoResultType resultType
;
5324 char *strValue
= NULL
;
5327 struct curl_slist
*stringListValue
= NULL
;
5329 checkConnection(connection
);
5331 switch(Long_val(option
))
5333 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5334 case 0: /* CURLINFO_EFFECTIVE_URL */
5335 resultType
= StringValue
;
5337 curlResult
= curl_easy_getinfo(connection
->connection
,
5338 CURLINFO_EFFECTIVE_URL
,
5342 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5345 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5346 case 1: /* CURLINFO_HTTP_CODE */
5347 case 2: /* CURLINFO_RESPONSE_CODE */
5348 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5349 resultType
= LongValue
;
5351 curlResult
= curl_easy_getinfo(connection
->connection
,
5352 CURLINFO_RESPONSE_CODE
,
5355 resultType
= LongValue
;
5357 curlResult
= curl_easy_getinfo(connection
->connection
,
5364 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5365 case 3: /* CURLINFO_TOTAL_TIME */
5366 resultType
= DoubleValue
;
5368 curlResult
= curl_easy_getinfo(connection
->connection
,
5369 CURLINFO_TOTAL_TIME
,
5374 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5375 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5376 resultType
= DoubleValue
;
5378 curlResult
= curl_easy_getinfo(connection
->connection
,
5379 CURLINFO_NAMELOOKUP_TIME
,
5384 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5385 case 5: /* CURLINFO_CONNECT_TIME */
5386 resultType
= DoubleValue
;
5388 curlResult
= curl_easy_getinfo(connection
->connection
,
5389 CURLINFO_CONNECT_TIME
,
5394 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5395 case 6: /* CURLINFO_PRETRANSFER_TIME */
5396 resultType
= DoubleValue
;
5398 curlResult
= curl_easy_getinfo(connection
->connection
,
5399 CURLINFO_PRETRANSFER_TIME
,
5404 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5405 case 7: /* CURLINFO_SIZE_UPLOAD */
5406 resultType
= DoubleValue
;
5408 curlResult
= curl_easy_getinfo(connection
->connection
,
5409 CURLINFO_SIZE_UPLOAD
,
5414 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5415 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5416 resultType
= DoubleValue
;
5418 curlResult
= curl_easy_getinfo(connection
->connection
,
5419 CURLINFO_SIZE_DOWNLOAD
,
5424 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5425 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5426 resultType
= DoubleValue
;
5428 curlResult
= curl_easy_getinfo(connection
->connection
,
5429 CURLINFO_SPEED_DOWNLOAD
,
5434 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5435 case 10: /* CURLINFO_SPEED_UPLOAD */
5436 resultType
= DoubleValue
;
5438 curlResult
= curl_easy_getinfo(connection
->connection
,
5439 CURLINFO_SPEED_UPLOAD
,
5445 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5446 case 11: /* CURLINFO_HEADER_SIZE */
5447 resultType
= LongValue
;
5449 curlResult
= curl_easy_getinfo(connection
->connection
,
5450 CURLINFO_HEADER_SIZE
,
5455 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5456 case 12: /* CURLINFO_REQUEST_SIZE */
5457 resultType
= LongValue
;
5459 curlResult
= curl_easy_getinfo(connection
->connection
,
5460 CURLINFO_REQUEST_SIZE
,
5465 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5466 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5467 resultType
= LongValue
;
5469 curlResult
= curl_easy_getinfo(connection
->connection
,
5470 CURLINFO_SSL_VERIFYRESULT
,
5475 #if HAVE_DECL_CURLINFO_FILETIME
5476 case 14: /* CURLINFO_FILETIME */
5477 resultType
= DoubleValue
;
5479 curlResult
= curl_easy_getinfo(connection
->connection
,
5485 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5486 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5487 resultType
= DoubleValue
;
5489 curlResult
= curl_easy_getinfo(connection
->connection
,
5490 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5495 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5496 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5497 resultType
= DoubleValue
;
5499 curlResult
= curl_easy_getinfo(connection
->connection
,
5500 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5505 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5506 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5507 resultType
= DoubleValue
;
5509 curlResult
= curl_easy_getinfo(connection
->connection
,
5510 CURLINFO_STARTTRANSFER_TIME
,
5515 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5516 case 18: /* CURLINFO_CONTENT_TYPE */
5517 resultType
= StringValue
;
5519 curlResult
= curl_easy_getinfo(connection
->connection
,
5520 CURLINFO_CONTENT_TYPE
,
5525 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5526 case 19: /* CURLINFO_REDIRECT_TIME */
5527 resultType
= DoubleValue
;
5529 curlResult
= curl_easy_getinfo(connection
->connection
,
5530 CURLINFO_REDIRECT_TIME
,
5535 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5536 case 20: /* CURLINFO_REDIRECT_COUNT */
5537 resultType
= LongValue
;
5539 curlResult
= curl_easy_getinfo(connection
->connection
,
5540 CURLINFO_REDIRECT_COUNT
,
5545 #if HAVE_DECL_CURLINFO_PRIVATE
5546 case 21: /* CURLINFO_PRIVATE */
5547 resultType
= StringValue
;
5549 curlResult
= curl_easy_getinfo(connection
->connection
,
5555 #if HAVE_DECL_CURLINFO_HTTP_CONNECTCODE
5556 case 22: /* CURLINFO_HTTP_CONNECTCODE */
5557 resultType
= LongValue
;
5559 curlResult
= curl_easy_getinfo(connection
->connection
,
5560 CURLINFO_HTTP_CONNECTCODE
,
5565 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5566 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5567 resultType
= LongValue
;
5569 curlResult
= curl_easy_getinfo(connection
->connection
,
5570 CURLINFO_HTTPAUTH_AVAIL
,
5575 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5576 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5577 resultType
= LongValue
;
5579 curlResult
= curl_easy_getinfo(connection
->connection
,
5580 CURLINFO_PROXYAUTH_AVAIL
,
5585 #if HAVE_DECL_CURLINFO_OS_ERRNO
5586 case 25: /* CURLINFO_OS_ERRNO */
5587 resultType
= LongValue
;
5589 curlResult
= curl_easy_getinfo(connection
->connection
,
5595 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5596 case 26: /* CURLINFO_NUM_CONNECTS */
5597 resultType
= LongValue
;
5599 curlResult
= curl_easy_getinfo(connection
->connection
,
5600 CURLINFO_NUM_CONNECTS
,
5605 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5606 case 27: /* CURLINFO_SSL_ENGINES */
5607 resultType
= StringListValue
;
5609 curlResult
= curl_easy_getinfo(connection
->connection
,
5610 CURLINFO_SSL_ENGINES
,
5615 #if HAVE_DECL_CURLINFO_COOKIELIST
5616 case 28: /* CURLINFO_COOKIELIST */
5617 resultType
= StringListValue
;
5619 curlResult
= curl_easy_getinfo(connection
->connection
,
5620 CURLINFO_COOKIELIST
,
5625 #if HAVE_DECL_CURLINFO_LASTSOCKET
5626 case 29: /* CURLINFO_LASTSOCKET */
5627 resultType
= LongValue
;
5629 curlResult
= curl_easy_getinfo(connection
->connection
,
5630 CURLINFO_LASTSOCKET
,
5635 #if HAVE_DECL_CURLINFO_FTP_ENTRY_PATH
5636 case 30: /* CURLINFO_FTP_ENTRY_PATH */
5637 resultType
= StringValue
;
5639 curlResult
= curl_easy_getinfo(connection
->connection
,
5640 CURLINFO_FTP_ENTRY_PATH
,
5646 failwith("Invalid CURLINFO Option");
5650 if (curlResult
!= CURLE_OK
)
5651 raiseError(connection
, curlResult
);
5656 result
= alloc(1, StringValue
);
5657 Store_field(result
, 0, copy_string(strValue
?strValue
:""));
5661 result
= alloc(1, LongValue
);
5662 Store_field(result
, 0, Val_long(longValue
));
5666 result
= alloc(1, DoubleValue
);
5667 Store_field(result
, 0, copy_double(doubleValue
));
5670 case StringListValue
:
5671 result
= alloc(1, StringListValue
);
5672 Store_field(result
, 0, convertStringList(stringListValue
));
5680 ** curl_escape helper function
5683 CAMLprim value
helper_curl_escape(value str
)
5689 curlResult
= curl_escape(String_val(str
), string_length(str
));
5690 result
= copy_string(curlResult
);
5697 ** curl_unescape helper function
5700 CAMLprim value
helper_curl_unescape(value str
)
5706 curlResult
= curl_unescape(String_val(str
), string_length(str
));
5707 result
= copy_string(curlResult
);
5714 ** curl_getdate helper function
5717 CAMLprim value
helper_curl_getdate(value str
, value now
)
5719 CAMLparam2(str
, now
);
5724 curlNow
= (time_t)Double_val(now
);
5725 curlResult
= curl_getdate(String_val(str
), &curlNow
);
5726 result
= copy_double((double)curlResult
);
5732 ** curl_version helper function
5735 CAMLprim value
helper_curl_version(void)
5741 str
= curl_version();
5742 result
= copy_string(str
);
5748 * Curl multi stack support
5750 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5751 * Other exported functions are prefixed with caml_curlm_, some of them
5752 * can/should be decomposed into smaller parts.
5755 struct ml_multi_handle
5758 value values
; /* callbacks */
5763 curlmopt_socket_function
,
5765 /* last, not used */
5769 typedef struct ml_multi_handle ml_multi_handle
;
5771 #define Multi_val(v) (*(ml_multi_handle**)Data_custom_val(v))
5772 #define CURLM_val(v) (Multi_val(v)->handle)
5774 static struct custom_operations curl_multi_ops
= {
5776 custom_finalize_default
,
5777 custom_compare_default
,
5778 custom_hash_default
,
5779 custom_serialize_default
,
5780 custom_deserialize_default
5783 CAMLprim value
caml_curl_multi_init(value unit
)
5787 ml_multi_handle
* multi
= (ml_multi_handle
*)caml_stat_alloc(sizeof(ml_multi_handle
));
5788 CURLM
* h
= curl_multi_init();
5792 caml_stat_free(multi
);
5793 failwith("caml_curl_multi_init");
5797 multi
->values
= caml_alloc(multi_values_total
, 0);
5798 caml_register_generational_global_root(&multi
->values
);
5800 v
= caml_alloc_custom(&curl_multi_ops
, sizeof(ml_multi_handle
*), 0, 1);
5801 Multi_val(v
) = multi
;
5806 CAMLprim value
caml_curl_multi_cleanup(value handle
)
5809 ml_multi_handle
* h
= Multi_val(handle
);
5812 CAMLreturn(Val_unit
);
5814 caml_remove_generational_global_root(&h
->values
);
5816 if (CURLM_OK
!= curl_multi_cleanup(h
->handle
))
5817 failwith("caml_curl_multi_cleanup");
5819 Multi_val(handle
) = (ml_multi_handle
*)NULL
;
5821 CAMLreturn(Val_unit
);
5824 static CURL
* curlm_remove_finished(CURLM
* multi_handle
)
5826 int msgs_in_queue
= 0;
5830 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
5831 if (NULL
== msg
) return NULL
;
5832 if (CURLMSG_DONE
== msg
->msg
)
5834 CURL
* easy_handle
= msg
->easy_handle
;
5835 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
5837 //failwith("curlm_remove_finished");
5844 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
5846 CAMLparam1(v_multi
);
5849 CURLM
* multi_handle
;
5851 multi_handle
= CURLM_val(v_multi
);
5853 caml_enter_blocking_section();
5854 handle
= curlm_remove_finished(multi_handle
);
5855 caml_leave_blocking_section();
5859 CAMLreturn(Val_none
);
5863 /* not good: same handle, but different block */
5864 v_easy
= caml_alloc(1, Abstract_tag
);
5865 Field(v_easy
, 0) = (value
)findConnection(handle
);
5866 CAMLreturn(Val_some(v_easy
));
5870 static int curlm_wait_data(CURLM
* multi_handle
)
5872 struct timeval timeout
;
5884 /* set a suitable timeout */
5886 timeout
.tv_usec
= 0;
5888 /* get file descriptors from the transfers */
5889 ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
5891 if (ret
== CURLM_OK
&& maxfd
>= 0)
5893 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
5894 if (-1 != rc
) return 0;
5895 //printf("select error\n");
5899 //printf("curl_multi_fdset error\n");
5904 CAMLprim value
caml_curlm_wait_data(value v_multi
)
5906 CAMLparam1(v_multi
);
5910 h
= CURLM_val(v_multi
);
5912 caml_enter_blocking_section();
5913 ret
= curlm_wait_data(h
);
5914 caml_leave_blocking_section();
5916 CAMLreturn(Val_bool(0 == ret
));
5919 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
5921 CAMLparam2(v_multi
,v_easy
);
5923 if (CURLM_OK
!= curl_multi_add_handle(CURLM_val(v_multi
), Connection_val(v_easy
)->connection
))
5924 failwith("caml_curl_multi_add_handle");
5926 CAMLreturn(Val_unit
);
5929 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
5931 CAMLparam1(v_multi
);
5933 int still_running
= 0;
5935 h
= CURLM_val(v_multi
);
5937 caml_enter_blocking_section();
5938 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
5939 caml_leave_blocking_section();
5941 CAMLreturn(Val_int(still_running
));