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
,
2250 case 2: /* CURL_ENCODING_GZIP */
2251 result
= curl_easy_setopt(conn
->connection
,
2256 case 3: /* CURL_ENCODING_ANY */
2257 result
= curl_easy_setopt(conn
->connection
,
2263 failwith("Invalid Encoding Option");
2267 if (result
!= CURLE_OK
)
2268 raiseError(conn
, result
);
2272 #warning "libcurl does not implement CURLOPT_ENCODING"
2273 failwith("libcurl does not implement CURLOPT_ENCODING");
2277 static void handleFollowLocation(Connection
*conn
, value option
)
2280 CURLcode result
= CURLE_OK
;
2282 result
= curl_easy_setopt(conn
->connection
,
2283 CURLOPT_FOLLOWLOCATION
,
2286 if (result
!= CURLE_OK
)
2287 raiseError(conn
, result
);
2292 static void handleTransferText(Connection
*conn
, value option
)
2295 CURLcode result
= CURLE_OK
;
2297 result
= curl_easy_setopt(conn
->connection
,
2298 CURLOPT_TRANSFERTEXT
,
2301 if (result
!= CURLE_OK
)
2302 raiseError(conn
, result
);
2307 static void handlePut(Connection
*conn
, value option
)
2310 CURLcode result
= CURLE_OK
;
2312 result
= curl_easy_setopt(conn
->connection
,
2316 if (result
!= CURLE_OK
)
2317 raiseError(conn
, result
);
2322 static void handleUserPwd(Connection
*conn
, value option
)
2325 CURLcode result
= CURLE_OK
;
2327 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2329 if (conn
->userPwd
!= NULL
)
2330 free(conn
->userPwd
);
2332 conn
->userPwd
= strdup(String_val(option
));
2334 result
= curl_easy_setopt(conn
->connection
,
2338 if (result
!= CURLE_OK
)
2339 raiseError(conn
, result
);
2344 static void handleProxyUserPwd(Connection
*conn
, value option
)
2347 CURLcode result
= CURLE_OK
;
2349 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2351 if (conn
->proxyUserPwd
!= NULL
)
2352 free(conn
->proxyUserPwd
);
2354 conn
->proxyUserPwd
= strdup(String_val(option
));
2356 result
= curl_easy_setopt(conn
->connection
,
2357 CURLOPT_PROXYUSERPWD
,
2358 conn
->proxyUserPwd
);
2360 if (result
!= CURLE_OK
)
2361 raiseError(conn
, result
);
2366 static void handleRange(Connection
*conn
, value option
)
2369 CURLcode result
= CURLE_OK
;
2371 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2373 if (conn
->range
!= NULL
)
2376 conn
->range
= strdup(String_val(option
));
2378 result
= curl_easy_setopt(conn
->connection
,
2382 if (result
!= CURLE_OK
)
2383 raiseError(conn
, result
);
2388 static void handleErrorBuffer(Connection
*conn
, value option
)
2391 CURLcode result
= CURLE_OK
;
2393 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2395 if (conn
->errorBuffer
!= NULL
)
2396 free(conn
->errorBuffer
);
2398 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2400 result
= curl_easy_setopt(conn
->connection
,
2401 CURLOPT_ERRORBUFFER
,
2404 if (result
!= CURLE_OK
)
2405 raiseError(conn
, result
);
2410 static void handleTimeout(Connection
*conn
, value option
)
2413 CURLcode result
= CURLE_OK
;
2415 result
= curl_easy_setopt(conn
->connection
,
2419 if (result
!= CURLE_OK
)
2420 raiseError(conn
, result
);
2425 static void handlePostFields(Connection
*conn
, value option
)
2428 CURLcode result
= CURLE_OK
;
2430 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2432 if (conn
->postFields
!= NULL
)
2433 free(conn
->postFields
);
2435 conn
->postFields
= malloc(string_length(option
)+1);
2436 memcpy(conn
->postFields
, String_val(option
), string_length(option
));
2438 result
= curl_easy_setopt(conn
->connection
,
2442 if (result
!= CURLE_OK
)
2443 raiseError(conn
, result
);
2448 static void handlePostFieldSize(Connection
*conn
, value option
)
2451 CURLcode result
= CURLE_OK
;
2453 result
= curl_easy_setopt(conn
->connection
,
2454 CURLOPT_POSTFIELDSIZE
,
2457 if (result
!= CURLE_OK
)
2458 raiseError(conn
, result
);
2463 static void handleReferer(Connection
*conn
, value option
)
2466 CURLcode result
= CURLE_OK
;
2468 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2470 if (conn
->referer
!= NULL
)
2471 free(conn
->referer
);
2473 conn
->referer
= strdup(String_val(option
));
2475 result
= curl_easy_setopt(conn
->connection
,
2479 if (result
!= CURLE_OK
)
2480 raiseError(conn
, result
);
2485 static void handleUserAgent(Connection
*conn
, value option
)
2488 CURLcode result
= CURLE_OK
;
2490 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2492 if (conn
->userAgent
!= NULL
)
2493 free(conn
->userAgent
);
2495 conn
->userAgent
= strdup(String_val(option
));
2497 result
= curl_easy_setopt(conn
->connection
,
2501 if (result
!= CURLE_OK
)
2502 raiseError(conn
, result
);
2507 static void handleFTPPort(Connection
*conn
, value option
)
2510 CURLcode result
= CURLE_OK
;
2512 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2514 if (conn
->ftpPort
!= NULL
)
2515 free(conn
->ftpPort
);
2517 conn
->ftpPort
= strdup(String_val(option
));
2519 result
= curl_easy_setopt(conn
->connection
,
2523 if (result
!= CURLE_OK
)
2524 raiseError(conn
, result
);
2529 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2532 CURLcode result
= CURLE_OK
;
2534 result
= curl_easy_setopt(conn
->connection
,
2535 CURLOPT_LOW_SPEED_LIMIT
,
2538 if (result
!= CURLE_OK
)
2539 raiseError(conn
, result
);
2544 static void handleLowSpeedTime(Connection
*conn
, value option
)
2547 CURLcode result
= CURLE_OK
;
2549 result
= curl_easy_setopt(conn
->connection
,
2550 CURLOPT_LOW_SPEED_TIME
,
2553 if (result
!= CURLE_OK
)
2554 raiseError(conn
, result
);
2559 static void handleResumeFrom(Connection
*conn
, value option
)
2562 CURLcode result
= CURLE_OK
;
2564 result
= curl_easy_setopt(conn
->connection
,
2565 CURLOPT_RESUME_FROM
,
2568 if (result
!= CURLE_OK
)
2569 raiseError(conn
, result
);
2574 static void handleCookie(Connection
*conn
, value option
)
2577 CURLcode result
= CURLE_OK
;
2579 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2581 if (conn
->cookie
!= NULL
)
2584 conn
->cookie
= strdup(String_val(option
));
2586 result
= curl_easy_setopt(conn
->connection
,
2590 if (result
!= CURLE_OK
)
2591 raiseError(conn
, result
);
2596 static void handleHTTPHeader(Connection
*conn
, value option
)
2599 CAMLlocal1(listIter
);
2600 CURLcode result
= CURLE_OK
;
2603 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2605 if (conn
->httpHeader
!= NULL
)
2606 free_curl_slist(conn
->httpHeader
);
2608 conn
->httpHeader
= NULL
;
2612 while (!Is_long(listIter
))
2614 if (Tag_val(Field(listIter
, 0)) != String_tag
)
2615 failwith("Not a string");
2617 str
= strdup(String_val(Field(listIter
, 0)));
2619 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, str
);
2621 listIter
= Field(listIter
, 1);
2624 result
= curl_easy_setopt(conn
->connection
,
2628 if (result
!= CURLE_OK
)
2629 raiseError(conn
, result
);
2634 static void handleHTTPPost(Connection
*conn
, value option
)
2637 CAMLlocal3(listIter
, formItem
, contentType
);
2638 CURLcode result
= CURLE_OK
;
2639 char *str1
, *str2
, *str3
, *str4
;
2643 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2645 if (conn
->httpPostFirst
!= NULL
)
2646 curl_formfree(conn
->httpPostFirst
);
2648 conn
->httpPostFirst
= NULL
;
2649 conn
->httpPostLast
= NULL
;
2651 if (conn
->httpPostStrings
!= NULL
)
2652 free_curl_slist(conn
->httpPostStrings
);
2654 while (!Is_long(listIter
))
2656 formItem
= Field(listIter
, 0);
2658 switch (Tag_val(formItem
))
2660 case 0: /* CURLFORM_CONTENT */
2661 if (Wosize_val(formItem
) < 3)
2663 failwith("Incorrect CURLFORM_CONTENT parameters");
2666 if (Is_long(Field(formItem
, 2)) &&
2667 Long_val(Field(formItem
, 2)) == 0)
2669 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2671 String_val(Field(formItem
, 0)),
2672 string_length(Field(formItem
, 0)));
2673 str1
[string_length(Field(formItem
, 0))] = 0;
2674 conn
->httpPostStrings
=
2675 curl_slist_append(conn
->httpPostStrings
, str1
);
2677 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2679 String_val(Field(formItem
, 1)),
2680 string_length(Field(formItem
, 1)));
2681 str2
[string_length(Field(formItem
, 1))] = 0;
2682 conn
->httpPostStrings
=
2683 curl_slist_append(conn
->httpPostStrings
, str2
);
2685 curl_formadd(&conn
->httpPostFirst
,
2686 &conn
->httpPostLast
,
2689 CURLFORM_NAMELENGTH
,
2690 string_length(Field(formItem
, 0)),
2691 CURLFORM_PTRCONTENTS
,
2693 CURLFORM_CONTENTSLENGTH
,
2694 string_length(Field(formItem
, 1)),
2697 else if (Is_block(Field(formItem
, 2)))
2699 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2701 String_val(Field(formItem
, 0)),
2702 string_length(Field(formItem
, 0)));
2703 str1
[string_length(Field(formItem
, 0))] = 0;
2704 conn
->httpPostStrings
=
2705 curl_slist_append(conn
->httpPostStrings
, str1
);
2707 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2709 String_val(Field(formItem
, 1)),
2710 string_length(Field(formItem
, 1)));
2711 str2
[string_length(Field(formItem
, 1))] = 0;
2712 conn
->httpPostStrings
=
2713 curl_slist_append(conn
->httpPostStrings
, str2
);
2715 contentType
= Field(formItem
, 2);
2717 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2719 String_val(Field(contentType
, 0)),
2720 string_length(Field(contentType
, 0)));
2721 str3
[string_length(Field(contentType
, 0))] = 0;
2722 conn
->httpPostStrings
=
2723 curl_slist_append(conn
->httpPostStrings
, str3
);
2725 curl_formadd(&conn
->httpPostFirst
,
2726 &conn
->httpPostLast
,
2729 CURLFORM_NAMELENGTH
,
2730 string_length(Field(formItem
, 0)),
2731 CURLFORM_PTRCONTENTS
,
2733 CURLFORM_CONTENTSLENGTH
,
2734 string_length(Field(formItem
, 1)),
2735 CURLFORM_CONTENTTYPE
,
2741 failwith("Incorrect CURLFORM_CONTENT parameters");
2745 case 1: /* CURLFORM_FILECONTENT */
2746 if (Wosize_val(formItem
) < 3)
2748 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2751 if (Is_long(Field(formItem
, 2)) &&
2752 Long_val(Field(formItem
, 2)) == 0)
2754 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2756 String_val(Field(formItem
, 0)),
2757 string_length(Field(formItem
, 0)));
2758 str1
[string_length(Field(formItem
, 0))] = 0;
2759 conn
->httpPostStrings
=
2760 curl_slist_append(conn
->httpPostStrings
, str1
);
2762 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2764 String_val(Field(formItem
, 1)),
2765 string_length(Field(formItem
, 1)));
2766 str2
[string_length(Field(formItem
, 1))] = 0;
2767 conn
->httpPostStrings
=
2768 curl_slist_append(conn
->httpPostStrings
, str2
);
2770 curl_formadd(&conn
->httpPostFirst
,
2771 &conn
->httpPostLast
,
2774 CURLFORM_NAMELENGTH
,
2775 string_length(Field(formItem
, 0)),
2776 CURLFORM_FILECONTENT
,
2780 else if (Is_block(Field(formItem
, 2)))
2782 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2784 String_val(Field(formItem
, 0)),
2785 string_length(Field(formItem
, 0)));
2786 str1
[string_length(Field(formItem
, 0))] = 0;
2787 conn
->httpPostStrings
=
2788 curl_slist_append(conn
->httpPostStrings
, str1
);
2790 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2792 String_val(Field(formItem
, 1)),
2793 string_length(Field(formItem
, 1)));
2794 str2
[string_length(Field(formItem
, 1))] = 0;
2795 conn
->httpPostStrings
=
2796 curl_slist_append(conn
->httpPostStrings
, str2
);
2798 contentType
= Field(formItem
, 2);
2800 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2802 String_val(Field(contentType
, 0)),
2803 string_length(Field(contentType
, 0)));
2804 str3
[string_length(Field(contentType
, 0))] = 0;
2805 conn
->httpPostStrings
=
2806 curl_slist_append(conn
->httpPostStrings
, str3
);
2808 curl_formadd(&conn
->httpPostFirst
,
2809 &conn
->httpPostLast
,
2812 CURLFORM_NAMELENGTH
,
2813 string_length(Field(formItem
, 0)),
2814 CURLFORM_FILECONTENT
,
2816 CURLFORM_CONTENTTYPE
,
2822 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2826 case 2: /* CURLFORM_FILE */
2827 if (Wosize_val(formItem
) < 3)
2829 failwith("Incorrect CURLFORM_FILE parameters");
2832 if (Is_long(Field(formItem
, 2)) &&
2833 Long_val(Field(formItem
, 2)) == 0)
2835 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2837 String_val(Field(formItem
, 0)),
2838 string_length(Field(formItem
, 0)));
2839 str1
[string_length(Field(formItem
, 0))] = 0;
2840 conn
->httpPostStrings
=
2841 curl_slist_append(conn
->httpPostStrings
, str1
);
2843 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2845 String_val(Field(formItem
, 1)),
2846 string_length(Field(formItem
, 1)));
2847 str2
[string_length(Field(formItem
, 1))] = 0;
2848 conn
->httpPostStrings
=
2849 curl_slist_append(conn
->httpPostStrings
, str2
);
2851 curl_formadd(&conn
->httpPostFirst
,
2852 &conn
->httpPostLast
,
2855 CURLFORM_NAMELENGTH
,
2856 string_length(Field(formItem
, 0)),
2861 else if (Is_block(Field(formItem
, 2)))
2863 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2865 String_val(Field(formItem
, 0)),
2866 string_length(Field(formItem
, 0)));
2867 str1
[string_length(Field(formItem
, 0))] = 0;
2868 conn
->httpPostStrings
=
2869 curl_slist_append(conn
->httpPostStrings
, str1
);
2871 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2873 String_val(Field(formItem
, 1)),
2874 string_length(Field(formItem
, 1)));
2875 str2
[string_length(Field(formItem
, 1))] = 0;
2876 conn
->httpPostStrings
=
2877 curl_slist_append(conn
->httpPostStrings
, str2
);
2879 contentType
= Field(formItem
, 2);
2881 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2883 String_val(Field(contentType
, 0)),
2884 string_length(Field(contentType
, 0)));
2885 str3
[string_length(Field(contentType
, 0))] = 0;
2886 conn
->httpPostStrings
=
2887 curl_slist_append(conn
->httpPostStrings
, str3
);
2889 curl_formadd(&conn
->httpPostFirst
,
2890 &conn
->httpPostLast
,
2893 CURLFORM_NAMELENGTH
,
2894 string_length(Field(formItem
, 0)),
2897 CURLFORM_CONTENTTYPE
,
2903 failwith("Incorrect CURLFORM_FILE parameters");
2907 case 3: /* CURLFORM_BUFFER */
2908 if (Wosize_val(formItem
) < 4)
2910 failwith("Incorrect CURLFORM_BUFFER parameters");
2913 if (Is_long(Field(formItem
, 3)) &&
2914 Long_val(Field(formItem
, 3)) == 0)
2916 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2918 String_val(Field(formItem
, 0)),
2919 string_length(Field(formItem
, 0)));
2920 str1
[string_length(Field(formItem
, 0))] = 0;
2921 conn
->httpPostStrings
=
2922 curl_slist_append(conn
->httpPostStrings
, str1
);
2924 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2926 String_val(Field(formItem
, 1)),
2927 string_length(Field(formItem
, 1)));
2928 str2
[string_length(Field(formItem
, 1))] = 0;
2929 conn
->httpPostStrings
=
2930 curl_slist_append(conn
->httpPostStrings
, str2
);
2932 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2934 String_val(Field(formItem
, 2)),
2935 string_length(Field(formItem
, 2)));
2936 str3
[string_length(Field(formItem
, 2))] = 0;
2937 conn
->httpPostStrings
=
2938 curl_slist_append(conn
->httpPostStrings
, str3
);
2940 curl_formadd(&conn
->httpPostFirst
,
2941 &conn
->httpPostLast
,
2944 CURLFORM_NAMELENGTH
,
2945 string_length(Field(formItem
, 0)),
2950 CURLFORM_BUFFERLENGTH
,
2951 string_length(Field(formItem
, 2)),
2954 else if (Is_block(Field(formItem
, 3)))
2956 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2958 String_val(Field(formItem
, 0)),
2959 string_length(Field(formItem
, 0)));
2960 str1
[string_length(Field(formItem
, 0))] = 0;
2961 conn
->httpPostStrings
=
2962 curl_slist_append(conn
->httpPostStrings
, str1
);
2964 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2966 String_val(Field(formItem
, 1)),
2967 string_length(Field(formItem
, 1)));
2968 str2
[string_length(Field(formItem
, 1))] = 0;
2969 conn
->httpPostStrings
=
2970 curl_slist_append(conn
->httpPostStrings
, str2
);
2972 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
2974 String_val(Field(formItem
, 2)),
2975 string_length(Field(formItem
, 2)));
2976 str3
[string_length(Field(formItem
, 2))] = 0;
2977 conn
->httpPostStrings
=
2978 curl_slist_append(conn
->httpPostStrings
, str3
);
2980 contentType
= Field(formItem
, 3);
2982 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2984 String_val(Field(contentType
, 0)),
2985 string_length(Field(contentType
, 0)));
2986 str4
[string_length(Field(contentType
, 0))] = 0;
2987 conn
->httpPostStrings
=
2988 curl_slist_append(conn
->httpPostStrings
, str4
);
2990 curl_formadd(&conn
->httpPostFirst
,
2991 &conn
->httpPostLast
,
2994 CURLFORM_NAMELENGTH
,
2995 string_length(Field(formItem
, 0)),
3000 CURLFORM_BUFFERLENGTH
,
3001 string_length(Field(formItem
, 2)),
3002 CURLFORM_CONTENTTYPE
,
3008 failwith("Incorrect CURLFORM_BUFFER parameters");
3013 listIter
= Field(listIter
, 1);
3016 result
= curl_easy_setopt(conn
->connection
,
3018 conn
->httpPostFirst
);
3020 if (result
!= CURLE_OK
)
3021 raiseError(conn
, result
);
3026 static void handleSSLCert(Connection
*conn
, value option
)
3029 CURLcode result
= CURLE_OK
;
3031 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3033 if (conn
->sslCert
!= NULL
)
3034 free(conn
->sslCert
);
3036 conn
->sslCert
= strdup(String_val(option
));
3038 result
= curl_easy_setopt(conn
->connection
,
3042 if (result
!= CURLE_OK
)
3043 raiseError(conn
, result
);
3048 static void handleSSLCertType(Connection
*conn
, value option
)
3051 CURLcode result
= CURLE_OK
;
3053 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3055 if (conn
->sslCertType
!= NULL
)
3056 free(conn
->sslCertType
);
3058 conn
->sslCertType
= strdup(String_val(option
));
3060 result
= curl_easy_setopt(conn
->connection
,
3061 CURLOPT_SSLCERTTYPE
,
3064 if (result
!= CURLE_OK
)
3065 raiseError(conn
, result
);
3070 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3073 CURLcode result
= CURLE_OK
;
3075 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3077 if (conn
->sslCertPasswd
!= NULL
)
3078 free(conn
->sslCertPasswd
);
3080 conn
->sslCertPasswd
= strdup(String_val(option
));
3082 result
= curl_easy_setopt(conn
->connection
,
3083 CURLOPT_SSLCERTPASSWD
,
3084 conn
->sslCertPasswd
);
3086 if (result
!= CURLE_OK
)
3087 raiseError(conn
, result
);
3092 static void handleSSLKey(Connection
*conn
, value option
)
3095 CURLcode result
= CURLE_OK
;
3097 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3099 if (conn
->sslKey
!= NULL
)
3102 conn
->sslKey
= strdup(String_val(option
));
3104 result
= curl_easy_setopt(conn
->connection
,
3108 if (result
!= CURLE_OK
)
3109 raiseError(conn
, result
);
3114 static void handleSSLKeyType(Connection
*conn
, value option
)
3117 CURLcode result
= CURLE_OK
;
3119 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3121 if (conn
->sslKeyType
!= NULL
)
3122 free(conn
->sslKeyType
);
3124 conn
->sslKeyType
= strdup(String_val(option
));
3126 result
= curl_easy_setopt(conn
->connection
,
3130 if (result
!= CURLE_OK
)
3131 raiseError(conn
, result
);
3136 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3139 CURLcode result
= CURLE_OK
;
3141 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3143 if (conn
->sslKeyPasswd
!= NULL
)
3144 free(conn
->sslKeyPasswd
);
3146 conn
->sslKeyPasswd
= strdup(String_val(option
));
3148 result
= curl_easy_setopt(conn
->connection
,
3149 CURLOPT_SSLKEYPASSWD
,
3150 conn
->sslKeyPasswd
);
3152 if (result
!= CURLE_OK
)
3153 raiseError(conn
, result
);
3158 static void handleSSLEngine(Connection
*conn
, value option
)
3161 CURLcode result
= CURLE_OK
;
3163 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3165 if (conn
->sslEngine
!= NULL
)
3166 free(conn
->sslEngine
);
3168 conn
->sslEngine
= strdup(String_val(option
));
3170 result
= curl_easy_setopt(conn
->connection
,
3174 if (result
!= CURLE_OK
)
3175 raiseError(conn
, result
);
3180 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3183 CURLcode result
= CURLE_OK
;
3185 result
= curl_easy_setopt(conn
->connection
,
3186 CURLOPT_SSLENGINE_DEFAULT
,
3189 if (result
!= CURLE_OK
)
3190 raiseError(conn
, result
);
3195 static void handleCRLF(Connection
*conn
, value option
)
3198 CURLcode result
= CURLE_OK
;
3200 result
= curl_easy_setopt(conn
->connection
,
3204 if (result
!= CURLE_OK
)
3205 raiseError(conn
, result
);
3210 static void handleQuote(Connection
*conn
, value option
)
3213 CAMLlocal1(listIter
);
3214 CURLcode result
= CURLE_OK
;
3217 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3219 if (conn
->quote
!= NULL
)
3220 free_curl_slist(conn
->quote
);
3226 while (!Is_long(listIter
))
3228 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3229 failwith("Not a string");
3231 str
= strdup(String_val(Field(listIter
, 0)));
3233 conn
->quote
= curl_slist_append(conn
->quote
, str
);
3235 listIter
= Field(listIter
, 1);
3238 result
= curl_easy_setopt(conn
->connection
,
3242 if (result
!= CURLE_OK
)
3243 raiseError(conn
, result
);
3248 static void handlePostQuote(Connection
*conn
, value option
)
3251 CAMLlocal1(listIter
);
3252 CURLcode result
= CURLE_OK
;
3255 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3257 if (conn
->postQuote
!= NULL
)
3258 free_curl_slist(conn
->postQuote
);
3260 conn
->postQuote
= NULL
;
3264 while (!Is_long(listIter
))
3266 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3267 failwith("Not a string");
3269 str
= strdup(String_val(Field(listIter
, 0)));
3271 conn
->postQuote
= curl_slist_append(conn
->postQuote
, str
);
3273 listIter
= Field(listIter
, 1);
3276 result
= curl_easy_setopt(conn
->connection
,
3280 if (result
!= CURLE_OK
)
3281 raiseError(conn
, result
);
3286 static void handleHeaderFunction(Connection
*conn
, value option
)
3289 CURLcode result
= CURLE_OK
;
3291 if (Tag_val(option
) == Closure_tag
)
3292 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3294 failwith("Not a proper closure");
3296 result
= curl_easy_setopt(conn
->connection
,
3297 CURLOPT_HEADERFUNCTION
,
3300 if (result
!= CURLE_OK
)
3301 raiseError(conn
, result
);
3303 result
= curl_easy_setopt(conn
->connection
,
3304 CURLOPT_WRITEHEADER
,
3307 if (result
!= CURLE_OK
)
3308 raiseError(conn
, result
);
3313 static void handleCookieFile(Connection
*conn
, value option
)
3316 CURLcode result
= CURLE_OK
;
3318 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3320 if (conn
->cookieFile
!= NULL
)
3321 free(conn
->cookieFile
);
3323 conn
->cookieFile
= strdup(String_val(option
));
3325 result
= curl_easy_setopt(conn
->connection
,
3329 if (result
!= CURLE_OK
)
3330 raiseError(conn
, result
);
3335 static void handleSSLVersion(Connection
*conn
, value option
)
3338 CURLcode result
= CURLE_OK
;
3340 result
= curl_easy_setopt(conn
->connection
,
3344 if (result
!= CURLE_OK
)
3345 raiseError(conn
, result
);
3350 static void handleTimeCondition(Connection
*conn
, value option
)
3353 CURLcode result
= CURLE_OK
;
3355 switch (Long_val(option
))
3357 case 0: /* TIMECOND_IFMODSINCE */
3358 result
= curl_easy_setopt(conn
->connection
,
3359 CURLOPT_TIMECONDITION
,
3360 CURL_TIMECOND_IFMODSINCE
);
3363 case 1: /* TIMECOND_IFUNMODSINCE */
3364 result
= curl_easy_setopt(conn
->connection
,
3365 CURLOPT_TIMECONDITION
,
3366 CURL_TIMECOND_IFUNMODSINCE
);
3370 failwith("Invalid TIMECOND Option");
3374 if (result
!= CURLE_OK
)
3375 raiseError(conn
, result
);
3380 static void handleTimeValue(Connection
*conn
, value option
)
3383 CURLcode result
= CURLE_OK
;
3385 result
= curl_easy_setopt(conn
->connection
,
3389 if (result
!= CURLE_OK
)
3390 raiseError(conn
, result
);
3395 static void handleCustomRequest(Connection
*conn
, value option
)
3398 CURLcode result
= CURLE_OK
;
3400 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3402 if (conn
->customRequest
!= NULL
)
3403 free(conn
->customRequest
);
3405 conn
->customRequest
= strdup(String_val(option
));
3407 result
= curl_easy_setopt(conn
->connection
,
3408 CURLOPT_CUSTOMREQUEST
,
3409 conn
->customRequest
);
3411 if (result
!= CURLE_OK
)
3412 raiseError(conn
, result
);
3417 static void handleInterface(Connection
*conn
, value option
)
3420 CURLcode result
= CURLE_OK
;
3422 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3424 if (conn
->interface
!= NULL
)
3425 free(conn
->interface
);
3427 conn
->interface
= strdup(String_val(option
));
3429 result
= curl_easy_setopt(conn
->connection
,
3433 if (result
!= CURLE_OK
)
3434 raiseError(conn
, result
);
3439 static void handleKRB4Level(Connection
*conn
, value option
)
3442 CURLcode result
= CURLE_OK
;
3444 switch (Long_val(option
))
3446 case 0: /* KRB4_NONE */
3447 result
= curl_easy_setopt(conn
->connection
,
3452 case 1: /* KRB4_CLEAR */
3453 result
= curl_easy_setopt(conn
->connection
,
3458 case 2: /* KRB4_SAFE */
3459 result
= curl_easy_setopt(conn
->connection
,
3464 case 3: /* KRB4_CONFIDENTIAL */
3465 result
= curl_easy_setopt(conn
->connection
,
3470 case 4: /* KRB4_PRIVATE */
3471 result
= curl_easy_setopt(conn
->connection
,
3477 failwith("Invalid KRB4 Option");
3481 if (result
!= CURLE_OK
)
3482 raiseError(conn
, result
);
3487 static void handleProgressFunction(Connection
*conn
, value option
)
3490 CURLcode result
= CURLE_OK
;
3492 if (Tag_val(option
) == Closure_tag
)
3493 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3495 failwith("Not a proper closure");
3497 result
= curl_easy_setopt(conn
->connection
,
3498 CURLOPT_PROGRESSFUNCTION
,
3500 if (result
!= CURLE_OK
)
3501 raiseError(conn
, result
);
3503 result
= curl_easy_setopt(conn
->connection
,
3504 CURLOPT_PROGRESSDATA
,
3507 if (result
!= CURLE_OK
)
3508 raiseError(conn
, result
);
3513 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3516 CURLcode result
= CURLE_OK
;
3518 result
= curl_easy_setopt(conn
->connection
,
3519 CURLOPT_SSL_VERIFYPEER
,
3522 if (result
!= CURLE_OK
)
3523 raiseError(conn
, result
);
3528 static void handleCAInfo(Connection
*conn
, value option
)
3531 CURLcode result
= CURLE_OK
;
3533 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3535 if (conn
->caInfo
!= NULL
)
3538 conn
->caInfo
= strdup(String_val(option
));
3540 result
= curl_easy_setopt(conn
->connection
,
3544 if (result
!= CURLE_OK
)
3545 raiseError(conn
, result
);
3550 static void handleCAPath(Connection
*conn
, value option
)
3553 CURLcode result
= CURLE_OK
;
3555 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3557 if (conn
->caPath
!= NULL
)
3560 conn
->caPath
= strdup(String_val(option
));
3562 result
= curl_easy_setopt(conn
->connection
,
3566 if (result
!= CURLE_OK
)
3567 raiseError(conn
, result
);
3572 static void handleFileTime(Connection
*conn
, value option
)
3575 CURLcode result
= CURLE_OK
;
3577 result
= curl_easy_setopt(conn
->connection
,
3581 if (result
!= CURLE_OK
)
3582 raiseError(conn
, result
);
3587 static void handleMaxRedirs(Connection
*conn
, value option
)
3590 CURLcode result
= CURLE_OK
;
3592 result
= curl_easy_setopt(conn
->connection
,
3596 if (result
!= CURLE_OK
)
3597 raiseError(conn
, result
);
3602 static void handleMaxConnects(Connection
*conn
, value option
)
3605 CURLcode result
= CURLE_OK
;
3607 result
= curl_easy_setopt(conn
->connection
,
3608 CURLOPT_MAXCONNECTS
,
3611 if (result
!= CURLE_OK
)
3612 raiseError(conn
, result
);
3617 static void handleClosePolicy(Connection
*conn
, value option
)
3620 CURLcode result
= CURLE_OK
;
3622 switch (Long_val(option
))
3624 case 0: /* CLOSEPOLICY_OLDEST */
3625 result
= curl_easy_setopt(conn
->connection
,
3626 CURLOPT_CLOSEPOLICY
,
3627 CURLCLOSEPOLICY_OLDEST
);
3630 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3631 result
= curl_easy_setopt(conn
->connection
,
3632 CURLOPT_CLOSEPOLICY
,
3633 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3637 failwith("Invalid CLOSEPOLICY Option");
3641 if (result
!= CURLE_OK
)
3642 raiseError(conn
, result
);
3647 static void handleFreshConnect(Connection
*conn
, value option
)
3650 CURLcode result
= CURLE_OK
;
3652 result
= curl_easy_setopt(conn
->connection
,
3653 CURLOPT_FRESH_CONNECT
,
3656 if (result
!= CURLE_OK
)
3657 raiseError(conn
, result
);
3662 static void handleForbidReuse(Connection
*conn
, value option
)
3665 CURLcode result
= CURLE_OK
;
3667 result
= curl_easy_setopt(conn
->connection
,
3668 CURLOPT_FORBID_REUSE
,
3671 if (result
!= CURLE_OK
)
3672 raiseError(conn
, result
);
3677 static void handleRandomFile(Connection
*conn
, value option
)
3680 CURLcode result
= CURLE_OK
;
3682 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3684 if (conn
->randomFile
!= NULL
)
3685 free(conn
->randomFile
);
3687 conn
->randomFile
= strdup(String_val(option
));
3689 result
= curl_easy_setopt(conn
->connection
,
3690 CURLOPT_RANDOM_FILE
,
3693 if (result
!= CURLE_OK
)
3694 raiseError(conn
, result
);
3699 static void handleEGDSocket(Connection
*conn
, value option
)
3702 CURLcode result
= CURLE_OK
;
3704 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3706 if (conn
->egdSocket
!= NULL
)
3707 free(conn
->egdSocket
);
3709 conn
->egdSocket
= strdup(String_val(option
));
3711 result
= curl_easy_setopt(conn
->connection
,
3715 if (result
!= CURLE_OK
)
3716 raiseError(conn
, result
);
3721 static void handleConnectTimeout(Connection
*conn
, value option
)
3724 CURLcode result
= CURLE_OK
;
3726 result
= curl_easy_setopt(conn
->connection
,
3727 CURLOPT_CONNECTTIMEOUT
,
3730 if (result
!= CURLE_OK
)
3731 raiseError(conn
, result
);
3736 static void handleHTTPGet(Connection
*conn
, value option
)
3739 CURLcode result
= CURLE_OK
;
3741 result
= curl_easy_setopt(conn
->connection
,
3745 if (result
!= CURLE_OK
)
3746 raiseError(conn
, result
);
3751 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3754 CURLcode result
= CURLE_OK
;
3756 switch (Long_val(option
))
3758 case 0: /* SSLVERIFYHOST_EXISTENCE */
3759 result
= curl_easy_setopt(conn
->connection
,
3760 CURLOPT_SSL_VERIFYHOST
,
3764 case 1: /* SSLVERIFYHOST_HOSTNAME */
3765 result
= curl_easy_setopt(conn
->connection
,
3766 CURLOPT_SSL_VERIFYHOST
,
3771 failwith("Invalid SSLVERIFYHOST Option");
3775 if (result
!= CURLE_OK
)
3776 raiseError(conn
, result
);
3781 static void handleCookieJar(Connection
*conn
, value option
)
3784 CURLcode result
= CURLE_OK
;
3786 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3788 if (conn
->cookieJar
!= NULL
)
3789 free(conn
->cookieJar
);
3791 conn
->cookieJar
= strdup(String_val(option
));
3793 result
= curl_easy_setopt(conn
->connection
,
3797 if (result
!= CURLE_OK
)
3798 raiseError(conn
, result
);
3803 static void handleSSLCipherList(Connection
*conn
, value option
)
3806 CURLcode result
= CURLE_OK
;
3808 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3810 if (conn
->sslCipherList
!= NULL
)
3811 free(conn
->sslCipherList
);
3813 conn
->sslCipherList
= strdup(String_val(option
));
3815 result
= curl_easy_setopt(conn
->connection
,
3816 CURLOPT_SSL_CIPHER_LIST
,
3817 conn
->sslCipherList
);
3819 if (result
!= CURLE_OK
)
3820 raiseError(conn
, result
);
3825 static void handleHTTPVersion(Connection
*conn
, value option
)
3828 CURLcode result
= CURLE_OK
;
3830 switch (Long_val(option
))
3832 case 0: /* HTTP_VERSION_NONE */
3833 result
= curl_easy_setopt(conn
->connection
,
3834 CURLOPT_HTTP_VERSION
,
3835 CURL_HTTP_VERSION_NONE
);
3838 case 1: /* HTTP_VERSION_1_0 */
3839 result
= curl_easy_setopt(conn
->connection
,
3840 CURLOPT_HTTP_VERSION
,
3841 CURL_HTTP_VERSION_1_0
);
3844 case 2: /* HTTP_VERSION_1_1 */
3845 result
= curl_easy_setopt(conn
->connection
,
3846 CURLOPT_HTTP_VERSION
,
3847 CURL_HTTP_VERSION_1_1
);
3851 failwith("Invalid HTTP_VERSION Option");
3855 if (result
!= CURLE_OK
)
3856 raiseError(conn
, result
);
3861 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3864 CURLcode result
= CURLE_OK
;
3866 result
= curl_easy_setopt(conn
->connection
,
3867 CURLOPT_FTP_USE_EPSV
,
3870 if (result
!= CURLE_OK
)
3871 raiseError(conn
, result
);
3876 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3879 CURLcode result
= CURLE_OK
;
3881 result
= curl_easy_setopt(conn
->connection
,
3882 CURLOPT_DNS_CACHE_TIMEOUT
,
3885 if (result
!= CURLE_OK
)
3886 raiseError(conn
, result
);
3891 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3894 CURLcode result
= CURLE_OK
;
3896 result
= curl_easy_setopt(conn
->connection
,
3897 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3900 if (result
!= CURLE_OK
)
3901 raiseError(conn
, result
);
3906 static void handleDebugFunction(Connection
*conn
, value option
)
3909 CURLcode result
= CURLE_OK
;
3911 if (Tag_val(option
) == Closure_tag
)
3912 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3914 failwith("Not a proper closure");
3916 result
= curl_easy_setopt(conn
->connection
,
3917 CURLOPT_DEBUGFUNCTION
,
3919 if (result
!= CURLE_OK
)
3920 raiseError(conn
, result
);
3922 result
= curl_easy_setopt(conn
->connection
,
3926 if (result
!= CURLE_OK
)
3927 raiseError(conn
, result
);
3932 static void handlePrivate(Connection
*conn
, value option
)
3934 #if HAVE_DECL_CURLOPT_PRIVATE
3936 CURLcode result
= CURLE_OK
;
3938 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
3940 if (conn
->private != NULL
)
3941 free(conn
->private);
3943 conn
->private = strdup(String_val(option
));
3945 result
= curl_easy_setopt(conn
->connection
,
3949 if (result
!= CURLE_OK
)
3950 raiseError(conn
, result
);
3954 #warning "libcurl does not implement CURLOPT_PRIVATE"
3955 failwith("libcurl does not implement CURLOPT_PRIVATE");
3959 static void handleHTTP200Aliases(Connection
*conn
, value option
)
3961 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3963 CAMLlocal1(listIter
);
3964 CURLcode result
= CURLE_OK
;
3967 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
3969 if (conn
->http200Aliases
!= NULL
)
3970 free_curl_slist(conn
->http200Aliases
);
3972 conn
->http200Aliases
= NULL
;
3976 while (!Is_long(listIter
))
3978 if (Tag_val(Field(listIter
, 0)) != String_tag
)
3979 failwith("Not a string");
3981 str
= strdup(String_val(Field(listIter
, 0)));
3983 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, str
);
3985 listIter
= Field(listIter
, 1);
3988 result
= curl_easy_setopt(conn
->connection
,
3989 CURLOPT_HTTP200ALIASES
,
3990 conn
->http200Aliases
);
3992 if (result
!= CURLE_OK
)
3993 raiseError(conn
, result
);
3997 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
3998 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
4002 static void handleUnrestrictedAuth(Connection
*conn
, value option
)
4004 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
4006 CURLcode result
= CURLE_OK
;
4008 result
= curl_easy_setopt(conn
->connection
,
4009 CURLOPT_UNRESTRICTED_AUTH
,
4012 if (result
!= CURLE_OK
)
4013 raiseError(conn
, result
);
4017 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4018 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4022 static void handleFTPUseEPRT(Connection
*conn
, value option
)
4024 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4026 CURLcode result
= CURLE_OK
;
4028 result
= curl_easy_setopt(conn
->connection
,
4029 CURLOPT_FTP_USE_EPRT
,
4032 if (result
!= CURLE_OK
)
4033 raiseError(conn
, result
);
4037 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4038 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4042 static void handleHTTPAuth(Connection
*conn
, value option
)
4044 #if HAVE_DECL_CURLOPT_HTTPAUTH
4046 CAMLlocal1(listIter
);
4047 CURLcode result
= CURLE_OK
;
4048 long auth
= CURLAUTH_NONE
;
4052 while (!Is_long(listIter
))
4054 switch (Long_val(Field(listIter
, 0)))
4056 case 0: /* CURLAUTH_BASIC */
4057 auth
|= CURLAUTH_BASIC
;
4060 case 1: /* CURLAUTH_DIGEST */
4061 auth
|= CURLAUTH_DIGEST
;
4064 case 2: /* CURLAUTH_GSSNEGOTIATE */
4065 auth
|= CURLAUTH_GSSNEGOTIATE
;
4068 case 3: /* CURLAUTH_NTLM */
4069 auth
|= CURLAUTH_NTLM
;
4072 case 4: /* CURLAUTH_ANY */
4073 auth
|= CURLAUTH_ANY
;
4076 case 5: /* CURLAUTH_ANYSAFE */
4077 auth
|= CURLAUTH_ANYSAFE
;
4081 failwith("Invalid HTTPAUTH Value");
4085 listIter
= Field(listIter
, 1);
4088 result
= curl_easy_setopt(conn
->connection
,
4092 if (result
!= CURLE_OK
)
4093 raiseError(conn
, result
);
4097 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4098 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4102 static void handleFTPCreateMissingDirs(Connection
*conn
, value option
)
4104 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4106 CURLcode result
= CURLE_OK
;
4108 result
= curl_easy_setopt(conn
->connection
,
4109 CURLOPT_FTP_CREATE_MISSING_DIRS
,
4112 if (result
!= CURLE_OK
)
4113 raiseError(conn
, result
);
4117 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4118 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4122 static void handleProxyAuth(Connection
*conn
, value option
)
4124 #if HAVE_DECL_CURLOPT_PROXYAUTH
4126 CAMLlocal1(listIter
);
4127 CURLcode result
= CURLE_OK
;
4128 long auth
= CURLAUTH_NONE
;
4132 while (!Is_long(listIter
))
4134 switch (Long_val(Field(listIter
, 0)))
4136 case 0: /* CURLAUTH_BASIC */
4137 auth
|= CURLAUTH_BASIC
;
4140 case 1: /* CURLAUTH_DIGEST */
4141 auth
|= CURLAUTH_DIGEST
;
4144 case 2: /* CURLAUTH_GSSNEGOTIATE */
4145 auth
|= CURLAUTH_GSSNEGOTIATE
;
4148 case 3: /* CURLAUTH_NTLM */
4149 auth
|= CURLAUTH_NTLM
;
4152 case 4: /* CURLAUTH_ANY */
4153 auth
|= CURLAUTH_ANY
;
4156 case 5: /* CURLAUTH_ANYSAFE */
4157 auth
|= CURLAUTH_ANYSAFE
;
4161 failwith("Invalid HTTPAUTH Value");
4165 listIter
= Field(listIter
, 1);
4168 result
= curl_easy_setopt(conn
->connection
,
4172 if (result
!= CURLE_OK
)
4173 raiseError(conn
, result
);
4177 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4178 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4182 static void handleFTPResponseTimeout(Connection
*conn
, value option
)
4184 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4186 CURLcode result
= CURLE_OK
;
4188 result
= curl_easy_setopt(conn
->connection
,
4189 CURLOPT_FTP_RESPONSE_TIMEOUT
,
4192 if (result
!= CURLE_OK
)
4193 raiseError(conn
, result
);
4197 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4198 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4202 static void handleIPResolve(Connection
*conn
, value option
)
4204 #if HAVE_DECL_CURLOPT_IPRESOLVE
4206 CURLcode result
= CURLE_OK
;
4208 switch (Long_val(option
))
4210 case 0: /* CURL_IPRESOLVE_WHATEVER */
4211 result
= curl_easy_setopt(conn
->connection
,
4213 CURL_IPRESOLVE_WHATEVER
);
4216 case 1: /* CURL_IPRESOLVE_V4 */
4217 result
= curl_easy_setopt(conn
->connection
,
4222 case 2: /* CURL_IPRESOLVE_V6 */
4223 result
= curl_easy_setopt(conn
->connection
,
4229 failwith("Invalid IPRESOLVE Value");
4233 if (result
!= CURLE_OK
)
4234 raiseError(conn
, result
);
4238 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4239 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4243 static void handleMaxFileSize(Connection
*conn
, value option
)
4245 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4247 CURLcode result
= CURLE_OK
;
4249 result
= curl_easy_setopt(conn
->connection
,
4250 CURLOPT_MAXFILESIZE
,
4253 if (result
!= CURLE_OK
)
4254 raiseError(conn
, result
);
4258 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4259 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4263 static void handleInFileSizeLarge(Connection
*conn
, value option
)
4265 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4267 CURLcode result
= CURLE_OK
;
4269 result
= curl_easy_setopt(conn
->connection
,
4270 CURLOPT_INFILESIZE_LARGE
,
4273 if (result
!= CURLE_OK
)
4274 raiseError(conn
, result
);
4278 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4279 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4283 static void handleResumeFromLarge(Connection
*conn
, value option
)
4285 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4287 CURLcode result
= CURLE_OK
;
4289 result
= curl_easy_setopt(conn
->connection
,
4290 CURLOPT_RESUME_FROM_LARGE
,
4293 if (result
!= CURLE_OK
)
4294 raiseError(conn
, result
);
4298 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4299 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4303 static void handleMaxFileSizeLarge(Connection
*conn
, value option
)
4305 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4307 CURLcode result
= CURLE_OK
;
4309 result
= curl_easy_setopt(conn
->connection
,
4310 CURLOPT_MAXFILESIZE_LARGE
,
4313 if (result
!= CURLE_OK
)
4314 raiseError(conn
, result
);
4318 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4319 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4323 static void handleNETRCFile(Connection
*conn
, value option
)
4325 #if HAVE_DECL_CURLOPT_NETRC_FILE
4327 CURLcode result
= CURLE_OK
;
4329 Store_field(conn
->ocamlValues
, OcamlNETRCFile
, option
);
4331 if (conn
->netrcFile
!= NULL
)
4332 free(conn
->netrcFile
);
4334 conn
->netrcFile
= strdup(String_val(option
));
4336 result
= curl_easy_setopt(conn
->connection
,
4340 if (result
!= CURLE_OK
)
4341 raiseError(conn
, result
);
4345 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4346 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4350 static void handleFTPSSL(Connection
*conn
, value option
)
4352 #if HAVE_DECL_CURLOPT_FTP_SSL
4354 CURLcode result
= CURLE_OK
;
4356 switch (Long_val(option
))
4358 case 0: /* CURLFTPSSL_NONE */
4359 result
= curl_easy_setopt(conn
->connection
,
4364 case 1: /* CURLFTPSSL_TRY */
4365 result
= curl_easy_setopt(conn
->connection
,
4370 case 2: /* CURLFTPSSL_CONTROL */
4371 result
= curl_easy_setopt(conn
->connection
,
4373 CURLFTPSSL_CONTROL
);
4376 case 3: /* CURLFTPSSL_ALL */
4377 result
= curl_easy_setopt(conn
->connection
,
4383 failwith("Invalid FTP_SSL Value");
4387 if (result
!= CURLE_OK
)
4388 raiseError(conn
, result
);
4392 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4393 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4397 static void handlePostFieldSizeLarge(Connection
*conn
, value option
)
4399 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4401 CURLcode result
= CURLE_OK
;
4403 result
= curl_easy_setopt(conn
->connection
,
4404 CURLOPT_POSTFIELDSIZE_LARGE
,
4407 if (result
!= CURLE_OK
)
4408 raiseError(conn
, result
);
4412 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4413 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4417 static void handleTCPNoDelay(Connection
*conn
, value option
)
4419 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4421 CURLcode result
= CURLE_OK
;
4423 result
= curl_easy_setopt(conn
->connection
,
4424 CURLOPT_TCP_NODELAY
,
4427 if (result
!= CURLE_OK
)
4428 raiseError(conn
, result
);
4432 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4433 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4437 static void handleFTPSSLAuth(Connection
*conn
, value option
)
4439 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4441 CURLcode result
= CURLE_OK
;
4443 switch (Long_val(option
))
4445 case 0: /* CURLFTPAUTH_DEFAULT */
4446 result
= curl_easy_setopt(conn
->connection
,
4448 CURLFTPAUTH_DEFAULT
);
4451 case 1: /* CURLFTPAUTH_SSL */
4452 result
= curl_easy_setopt(conn
->connection
,
4457 case 2: /* CURLFTPAUTH_TLS */
4458 result
= curl_easy_setopt(conn
->connection
,
4464 failwith("Invalid FTPSSLAUTH value");
4468 if (result
!= CURLE_OK
)
4469 raiseError(conn
, result
);
4473 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4474 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4478 static void handleIOCTLFunction(Connection
*conn
, value option
)
4480 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4482 CURLcode result
= CURLE_OK
;
4484 if (Tag_val(option
) == Closure_tag
)
4485 Store_field(conn
->ocamlValues
, OcamlIOCTLCallback
, option
);
4487 failwith("Not a proper closure");
4489 result
= curl_easy_setopt(conn
->connection
,
4490 CURLOPT_IOCTLFUNCTION
,
4492 if (result
!= CURLE_OK
)
4493 raiseError(conn
, result
);
4495 result
= curl_easy_setopt(conn
->connection
,
4499 if (result
!= CURLE_OK
)
4500 raiseError(conn
, result
);
4504 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4505 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4509 static void handleFTPAccount(Connection
*conn
, value option
)
4511 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4513 CURLcode result
= CURLE_OK
;
4515 Store_field(conn
->ocamlValues
, OcamlFTPAccount
, option
);
4517 if (conn
->ftpaccount
!= NULL
)
4518 free(conn
->ftpaccount
);
4520 conn
->ftpaccount
= strdup(String_val(option
));
4522 result
= curl_easy_setopt(conn
->connection
,
4523 CURLOPT_FTP_ACCOUNT
,
4526 if (result
!= CURLE_OK
)
4527 raiseError(conn
, result
);
4531 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4532 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4536 static void handleCookieList(Connection
*conn
, value option
)
4538 #if HAVE_DECL_CURLOPT_COOKIELIST
4540 CURLcode result
= CURLE_OK
;
4542 Store_field(conn
->ocamlValues
, OcamlCookieList
, option
);
4544 if (conn
->cookielist
!= NULL
)
4545 free(conn
->cookielist
);
4547 conn
->cookielist
= strdup(String_val(option
));
4549 result
= curl_easy_setopt(conn
->connection
,
4553 if (result
!= CURLE_OK
)
4554 raiseError(conn
, result
);
4558 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4559 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4563 static void handleIgnoreContentLength(Connection
*conn
, value option
)
4565 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4567 CURLcode result
= CURLE_OK
;
4569 result
= curl_easy_setopt(conn
->connection
,
4570 CURLOPT_IGNORE_CONTENT_LENGTH
,
4573 if (result
!= CURLE_OK
)
4574 raiseError(conn
, result
);
4578 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4579 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4583 static void handleFTPSkipPASVIP(Connection
*conn
, value option
)
4585 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4587 CURLcode result
= CURLE_OK
;
4589 result
= curl_easy_setopt(conn
->connection
,
4590 CURLOPT_FTP_SKIP_PASV_IP
,
4593 if (result
!= CURLE_OK
)
4594 raiseError(conn
, result
);
4598 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4599 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4603 static void handleFTPFileMethod(Connection
*conn
, value option
)
4605 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4607 CURLcode result
= CURLE_OK
;
4609 switch (Long_val(option
))
4611 case 0: /* CURLFTPMETHOD_DEFAULT */
4612 result
= curl_easy_setopt(conn
->connection
,
4613 CURLOPT_FTP_FILEMETHOD
,
4614 CURLFTPMETHOD_DEFAULT
);
4617 case 1: /* CURLFTMETHOD_MULTICWD */
4618 result
= curl_easy_setopt(conn
->connection
,
4619 CURLOPT_FTP_FILEMETHOD
,
4620 CURLFTPMETHOD_MULTICWD
);
4623 case 2: /* CURLFTPMETHOD_NOCWD */
4624 result
= curl_easy_setopt(conn
->connection
,
4625 CURLOPT_FTP_FILEMETHOD
,
4626 CURLFTPMETHOD_NOCWD
);
4629 case 3: /* CURLFTPMETHOD_SINGLECWD */
4630 result
= curl_easy_setopt(conn
->connection
,
4631 CURLOPT_FTP_FILEMETHOD
,
4632 CURLFTPMETHOD_SINGLECWD
);
4635 failwith("Invalid FTP_FILEMETHOD value");
4639 if (result
!= CURLE_OK
)
4640 raiseError(conn
, result
);
4644 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4645 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4649 static void handleLocalPort(Connection
*conn
, value option
)
4651 #if HAVE_DECL_CURLOPT_LOCALPORT
4653 CURLcode result
= CURLE_OK
;
4655 result
= curl_easy_setopt(conn
->connection
,
4659 if (result
!= CURLE_OK
)
4660 raiseError(conn
, result
);
4664 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4665 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4669 static void handleLocalPortRange(Connection
*conn
, value option
)
4671 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4673 CURLcode result
= CURLE_OK
;
4675 result
= curl_easy_setopt(conn
->connection
,
4676 CURLOPT_LOCALPORTRANGE
,
4679 if (result
!= CURLE_OK
)
4680 raiseError(conn
, result
);
4684 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4685 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4689 static void handleConnectOnly(Connection
*conn
, value option
)
4691 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4693 CURLcode result
= CURLE_OK
;
4695 result
= curl_easy_setopt(conn
->connection
,
4696 CURLOPT_CONNECT_ONLY
,
4699 if (result
!= CURLE_OK
)
4700 raiseError(conn
, result
);
4704 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4705 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4709 static void handleMaxSendSpeedLarge(Connection
*conn
, value option
)
4711 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4713 CURLcode result
= CURLE_OK
;
4715 result
= curl_easy_setopt(conn
->connection
,
4716 CURLOPT_MAX_SEND_SPEED_LARGE
,
4719 if (result
!= CURLE_OK
)
4720 raiseError(conn
, result
);
4724 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4725 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4729 static void handleMaxRecvSpeedLarge(Connection
*conn
, value option
)
4731 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4733 CURLcode result
= CURLE_OK
;
4735 result
= curl_easy_setopt(conn
->connection
,
4736 CURLOPT_MAX_RECV_SPEED_LARGE
,
4739 if (result
!= CURLE_OK
)
4740 raiseError(conn
, result
);
4744 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4745 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4749 static void handleFTPAlternativeToUser(Connection
*conn
, value option
)
4751 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4753 CURLcode result
= CURLE_OK
;
4755 Store_field(conn
->ocamlValues
, OcamlFTPAlternativeToUser
, option
);
4757 if (conn
->ftpAlternativeToUser
!= NULL
)
4758 free(conn
->ftpAlternativeToUser
);
4760 conn
->ftpAlternativeToUser
= strdup(String_val(option
));
4762 result
= curl_easy_setopt(conn
->connection
,
4763 CURLOPT_FTP_ALTERNATIVE_TO_USER
,
4764 conn
->ftpAlternativeToUser
);
4766 if (result
!= CURLE_OK
)
4767 raiseError(conn
, result
);
4771 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4772 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4776 static void handleSSLSessionIdCache(Connection
*conn
, value option
)
4778 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4780 CURLcode result
= CURLE_OK
;
4782 result
= curl_easy_setopt(conn
->connection
,
4783 CURLOPT_SSL_SESSIONID_CACHE
,
4786 if (result
!= CURLE_OK
)
4787 raiseError(conn
, result
);
4791 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4792 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4796 static void handleSSHAuthTypes(Connection
*conn
, value option
)
4798 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4800 CAMLlocal1(listIter
);
4801 CURLcode result
= CURLE_OK
;
4802 long authTypes
= CURLSSH_AUTH_NONE
;
4806 while (!Is_long(listIter
))
4808 switch (Long_val(Field(listIter
, 0)))
4810 case 0: /* CURLSSH_AUTH_ANY */
4811 authTypes
|= CURLSSH_AUTH_ANY
;
4814 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4815 authTypes
|= CURLSSH_AUTH_PUBLICKEY
;
4818 case 2: /* CURLSSH_AUTH_PASSWORD */
4819 authTypes
|= CURLSSH_AUTH_PASSWORD
;
4822 case 3: /* CURLSSH_AUTH_HOST */
4823 authTypes
|= CURLSSH_AUTH_HOST
;
4826 case 4: /* CURLSSH_AUTH_KEYBOARD */
4827 authTypes
|= CURLSSH_AUTH_KEYBOARD
;
4831 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4835 listIter
= Field(listIter
, 1);
4838 result
= curl_easy_setopt(conn
->connection
,
4839 CURLOPT_SSH_AUTH_TYPES
,
4842 if (result
!= CURLE_OK
)
4843 raiseError(conn
, result
);
4847 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4848 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4852 static void handleSSHPublicKeyFile(Connection
*conn
, value option
)
4854 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4856 CURLcode result
= CURLE_OK
;
4858 Store_field(conn
->ocamlValues
, OcamlSSHPublicKeyFile
, option
);
4860 if (conn
->sshPublicKeyFile
!= NULL
)
4861 free(conn
->sshPublicKeyFile
);
4863 conn
->sshPublicKeyFile
= strdup(String_val(option
));
4865 result
= curl_easy_setopt(conn
->connection
,
4866 CURLOPT_SSH_PUBLIC_KEYFILE
,
4867 conn
->sshPublicKeyFile
);
4869 if (result
!= CURLE_OK
)
4870 raiseError(conn
, result
);
4874 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4875 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4879 static void handleSSHPrivateKeyFile(Connection
*conn
, value option
)
4881 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4883 CURLcode result
= CURLE_OK
;
4885 Store_field(conn
->ocamlValues
, OcamlSSHPrivateKeyFile
, option
);
4887 if (conn
->sshPrivateKeyFile
!= NULL
)
4888 free(conn
->sshPrivateKeyFile
);
4890 conn
->sshPrivateKeyFile
= strdup(String_val(option
));
4892 result
= curl_easy_setopt(conn
->connection
,
4893 CURLOPT_SSH_PRIVATE_KEYFILE
,
4894 conn
->sshPrivateKeyFile
);
4896 if (result
!= CURLE_OK
)
4897 raiseError(conn
, result
);
4901 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4902 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4906 static void handleFTPSSLCCC(Connection
*conn
, value option
)
4908 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4910 CURLcode result
= CURLE_OK
;
4912 switch (Long_val(option
))
4914 case 0: /* CURLFTPSSL_CCC_NONE */
4915 result
= curl_easy_setopt(conn
->connection
,
4916 CURLOPT_FTP_SSL_CCC
,
4917 CURLFTPSSL_CCC_NONE
);
4920 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4921 result
= curl_easy_setopt(conn
->connection
,
4922 CURLOPT_FTP_SSL_CCC
,
4923 CURLFTPSSL_CCC_PASSIVE
);
4926 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4927 result
= curl_easy_setopt(conn
->connection
,
4928 CURLOPT_FTP_SSL_CCC
,
4929 CURLFTPSSL_CCC_ACTIVE
);
4933 failwith("Invalid FTPSSL_CCC value");
4937 if (result
!= CURLE_OK
)
4938 raiseError(conn
, result
);
4942 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4943 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4947 static void handleTimeoutMS(Connection
*conn
, value option
)
4949 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4951 CURLcode result
= CURLE_OK
;
4953 result
= curl_easy_setopt(conn
->connection
,
4957 if (result
!= CURLE_OK
)
4958 raiseError(conn
, result
);
4962 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4963 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4967 static void handleConnectTimeoutMS(Connection
*conn
, value option
)
4969 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4971 CURLcode result
= CURLE_OK
;
4973 result
= curl_easy_setopt(conn
->connection
,
4974 CURLOPT_CONNECTTIMEOUT_MS
,
4977 if (result
!= CURLE_OK
)
4978 raiseError(conn
, result
);
4982 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4983 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
4987 static void handleHTTPTransferDecoding(Connection
*conn
, value option
)
4989 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
4991 CURLcode result
= CURLE_OK
;
4993 result
= curl_easy_setopt(conn
->connection
,
4994 CURLOPT_HTTP_TRANSFER_DECODING
,
4997 if (result
!= CURLE_OK
)
4998 raiseError(conn
, result
);
5002 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
5003 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
5007 static void handleHTTPContentDecoding(Connection
*conn
, value option
)
5009 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
5011 CURLcode result
= CURLE_OK
;
5013 result
= curl_easy_setopt(conn
->connection
,
5014 CURLOPT_HTTP_CONTENT_DECODING
,
5017 if (result
!= CURLE_OK
)
5018 raiseError(conn
, result
);
5022 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5023 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5027 static void handleNewFilePerms(Connection
*conn
, value option
)
5029 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5031 CURLcode result
= CURLE_OK
;
5033 result
= curl_easy_setopt(conn
->connection
,
5034 CURLOPT_NEW_FILE_PERMS
,
5037 if (result
!= CURLE_OK
)
5038 raiseError(conn
, result
);
5042 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5043 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5047 static void handleNewDirectoryPerms(Connection
*conn
, value option
)
5049 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5051 CURLcode result
= CURLE_OK
;
5053 result
= curl_easy_setopt(conn
->connection
,
5054 CURLOPT_NEW_DIRECTORY_PERMS
,
5057 if (result
!= CURLE_OK
)
5058 raiseError(conn
, result
);
5062 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5063 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5067 static void handlePost301(Connection
*conn
, value option
)
5069 #if HAVE_DECL_CURLOPT_POST301
5071 CURLcode result
= CURLE_OK
;
5073 result
= curl_easy_setopt(conn
->connection
,
5077 if (result
!= CURLE_OK
)
5078 raiseError(conn
, result
);
5082 #warning "libcurl does not implement CURLOPT_POST301"
5083 failwith("libcurl does not implement CURLOPT_POST301");
5087 static void handleSSHHostPublicKeyMD5(Connection
*conn
, value option
)
5089 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5091 CURLcode result
= CURLE_OK
;
5093 Store_field(conn
->ocamlValues
, OcamlSSHHostPublicKeyMD5
, option
);
5095 if (conn
->sshHostPublicKeyMD5
!= NULL
)
5096 free(conn
->sshHostPublicKeyMD5
);
5098 conn
->sshHostPublicKeyMD5
= strdup(String_val(option
));
5100 result
= curl_easy_setopt(conn
->connection
,
5101 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
,
5102 conn
->sshHostPublicKeyMD5
);
5104 if (result
!= CURLE_OK
)
5105 raiseError(conn
, result
);
5109 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5110 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5114 static void handleCopyPostFields(Connection
*conn
, value option
)
5116 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5118 CURLcode result
= CURLE_OK
;
5120 Store_field(conn
->ocamlValues
, OcamlCopyPostFields
, option
);
5122 if (conn
->copyPostFields
!= NULL
)
5123 free(conn
->copyPostFields
);
5125 conn
->copyPostFields
= strdup(String_val(option
));
5127 result
= curl_easy_setopt(conn
->connection
,
5128 CURLOPT_COPYPOSTFIELDS
,
5129 conn
->copyPostFields
);
5131 if (result
!= CURLE_OK
)
5132 raiseError(conn
, result
);
5136 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5137 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5141 static void handleProxyTransferMode(Connection
*conn
, value option
)
5143 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5145 CURLcode result
= CURLE_OK
;
5147 result
= curl_easy_setopt(conn
->connection
,
5148 CURLOPT_PROXY_TRANSFER_MODE
,
5151 if (result
!= CURLE_OK
)
5152 raiseError(conn
, result
);
5156 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5157 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5161 static void handleSeekFunction(Connection
*conn
, value option
)
5163 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5165 CURLcode result
= CURLE_OK
;
5167 if (Tag_val(option
) == Closure_tag
)
5168 Store_field(conn
->ocamlValues
, OcamlSeekFunctionCallback
, option
);
5170 failwith("Not a proper closure");
5172 result
= curl_easy_setopt(conn
->connection
,
5173 CURLOPT_SEEKFUNCTION
,
5176 if (result
!= CURLE_OK
)
5177 raiseError(conn
, result
);
5179 result
= curl_easy_setopt(conn
->connection
,
5183 if (result
!= CURLE_OK
)
5184 raiseError(conn
, result
);
5188 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5189 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5194 ** curl_easy_setopt helper function
5197 CAMLprim value
helper_curl_easy_setopt(value conn
, value option
)
5199 CAMLparam2(conn
, option
);
5201 Connection
*connection
= Connection_val(conn
);
5203 checkConnection(connection
);
5205 if (Is_long(option
))
5209 sprintf(error
, "Unimplemented Option: %s",
5210 findOption(unimplementedOptionMap
,
5211 (CURLoption
)(Long_val(option
))));
5216 if (!Is_block(option
))
5217 failwith("Not a block");
5219 if (Wosize_val(option
) < 1)
5220 failwith("Insufficient data in block");
5222 data
= Field(option
, 0);
5224 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5225 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5228 failwith("Invalid CURLOPT Option");
5230 CAMLreturn(Val_unit
);
5234 ** curl_easy_perform helper function
5237 CAMLprim value
helper_curl_easy_perform(value conn
)
5240 CURLcode result
= CURLE_OK
;
5241 Connection
*connection
= Connection_val(conn
);
5243 checkConnection(connection
);
5245 enter_blocking_section();
5246 result
= curl_easy_perform(connection
->connection
);
5247 leave_blocking_section();
5249 if (result
!= CURLE_OK
)
5250 raiseError(connection
, result
);
5252 CAMLreturn(Val_unit
);
5256 ** curl_easy_cleanup helper function
5259 CAMLprim value
helper_curl_easy_cleanup(value conn
)
5262 Connection
*connection
= Connection_val(conn
);
5264 checkConnection(connection
);
5266 removeConnection(connection
);
5268 CAMLreturn(Val_unit
);
5272 ** curl_easy_duphandle helper function
5275 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5279 Connection
*connection
= Connection_val(conn
);
5281 checkConnection(connection
);
5283 result
= caml_alloc(1, Abstract_tag
);
5284 Field(result
, 0) = (value
)duplicateConnection(connection
);
5290 ** curl_easy_getinfo helper function
5293 enum GetInfoResultType
{
5294 StringValue
, LongValue
, DoubleValue
, StringListValue
5297 value
convertStringList(struct curl_slist
*slist
)
5300 CAMLlocal3(result
, current
, next
);
5301 struct curl_slist
*p
= slist
;
5303 result
= Val_int(0);
5304 current
= Val_int(0);
5309 next
= alloc_tuple(2);
5310 Store_field(next
, 0, copy_string(p
->data
));
5311 Store_field(next
, 1, Val_int(0));
5313 if (result
== Val_int(0))
5316 if (current
!= Val_int(0))
5317 Store_field(current
, 1, next
);
5324 curl_slist_free_all(slist
);
5329 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5331 CAMLparam2(conn
, option
);
5333 CURLcode curlResult
;
5334 Connection
*connection
= Connection_val(conn
);
5335 enum GetInfoResultType resultType
;
5336 char *strValue
= NULL
;
5339 struct curl_slist
*stringListValue
= NULL
;
5341 checkConnection(connection
);
5343 switch(Long_val(option
))
5345 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5346 case 0: /* CURLINFO_EFFECTIVE_URL */
5347 resultType
= StringValue
;
5349 curlResult
= curl_easy_getinfo(connection
->connection
,
5350 CURLINFO_EFFECTIVE_URL
,
5354 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5357 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5358 case 1: /* CURLINFO_HTTP_CODE */
5359 case 2: /* CURLINFO_RESPONSE_CODE */
5360 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5361 resultType
= LongValue
;
5363 curlResult
= curl_easy_getinfo(connection
->connection
,
5364 CURLINFO_RESPONSE_CODE
,
5367 resultType
= LongValue
;
5369 curlResult
= curl_easy_getinfo(connection
->connection
,
5376 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5377 case 3: /* CURLINFO_TOTAL_TIME */
5378 resultType
= DoubleValue
;
5380 curlResult
= curl_easy_getinfo(connection
->connection
,
5381 CURLINFO_TOTAL_TIME
,
5386 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5387 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5388 resultType
= DoubleValue
;
5390 curlResult
= curl_easy_getinfo(connection
->connection
,
5391 CURLINFO_NAMELOOKUP_TIME
,
5396 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5397 case 5: /* CURLINFO_CONNECT_TIME */
5398 resultType
= DoubleValue
;
5400 curlResult
= curl_easy_getinfo(connection
->connection
,
5401 CURLINFO_CONNECT_TIME
,
5406 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5407 case 6: /* CURLINFO_PRETRANSFER_TIME */
5408 resultType
= DoubleValue
;
5410 curlResult
= curl_easy_getinfo(connection
->connection
,
5411 CURLINFO_PRETRANSFER_TIME
,
5416 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5417 case 7: /* CURLINFO_SIZE_UPLOAD */
5418 resultType
= DoubleValue
;
5420 curlResult
= curl_easy_getinfo(connection
->connection
,
5421 CURLINFO_SIZE_UPLOAD
,
5426 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5427 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5428 resultType
= DoubleValue
;
5430 curlResult
= curl_easy_getinfo(connection
->connection
,
5431 CURLINFO_SIZE_DOWNLOAD
,
5436 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5437 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5438 resultType
= DoubleValue
;
5440 curlResult
= curl_easy_getinfo(connection
->connection
,
5441 CURLINFO_SPEED_DOWNLOAD
,
5446 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5447 case 10: /* CURLINFO_SPEED_UPLOAD */
5448 resultType
= DoubleValue
;
5450 curlResult
= curl_easy_getinfo(connection
->connection
,
5451 CURLINFO_SPEED_UPLOAD
,
5457 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5458 case 11: /* CURLINFO_HEADER_SIZE */
5459 resultType
= LongValue
;
5461 curlResult
= curl_easy_getinfo(connection
->connection
,
5462 CURLINFO_HEADER_SIZE
,
5467 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5468 case 12: /* CURLINFO_REQUEST_SIZE */
5469 resultType
= LongValue
;
5471 curlResult
= curl_easy_getinfo(connection
->connection
,
5472 CURLINFO_REQUEST_SIZE
,
5477 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5478 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5479 resultType
= LongValue
;
5481 curlResult
= curl_easy_getinfo(connection
->connection
,
5482 CURLINFO_SSL_VERIFYRESULT
,
5487 #if HAVE_DECL_CURLINFO_FILETIME
5488 case 14: /* CURLINFO_FILETIME */
5489 resultType
= DoubleValue
;
5491 curlResult
= curl_easy_getinfo(connection
->connection
,
5495 doubleValue
= longValue
;
5499 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5500 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5501 resultType
= DoubleValue
;
5503 curlResult
= curl_easy_getinfo(connection
->connection
,
5504 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5509 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5510 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5511 resultType
= DoubleValue
;
5513 curlResult
= curl_easy_getinfo(connection
->connection
,
5514 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5519 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5520 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5521 resultType
= DoubleValue
;
5523 curlResult
= curl_easy_getinfo(connection
->connection
,
5524 CURLINFO_STARTTRANSFER_TIME
,
5529 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5530 case 18: /* CURLINFO_CONTENT_TYPE */
5531 resultType
= StringValue
;
5533 curlResult
= curl_easy_getinfo(connection
->connection
,
5534 CURLINFO_CONTENT_TYPE
,
5539 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5540 case 19: /* CURLINFO_REDIRECT_TIME */
5541 resultType
= DoubleValue
;
5543 curlResult
= curl_easy_getinfo(connection
->connection
,
5544 CURLINFO_REDIRECT_TIME
,
5549 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5550 case 20: /* CURLINFO_REDIRECT_COUNT */
5551 resultType
= LongValue
;
5553 curlResult
= curl_easy_getinfo(connection
->connection
,
5554 CURLINFO_REDIRECT_COUNT
,
5559 #if HAVE_DECL_CURLINFO_PRIVATE
5560 case 21: /* CURLINFO_PRIVATE */
5561 resultType
= StringValue
;
5563 curlResult
= curl_easy_getinfo(connection
->connection
,
5569 #if HAVE_DECL_CURLINFO_HTTP_CONNECTCODE
5570 case 22: /* CURLINFO_HTTP_CONNECTCODE */
5571 resultType
= LongValue
;
5573 curlResult
= curl_easy_getinfo(connection
->connection
,
5574 CURLINFO_HTTP_CONNECTCODE
,
5579 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5580 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5581 resultType
= LongValue
;
5583 curlResult
= curl_easy_getinfo(connection
->connection
,
5584 CURLINFO_HTTPAUTH_AVAIL
,
5589 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5590 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5591 resultType
= LongValue
;
5593 curlResult
= curl_easy_getinfo(connection
->connection
,
5594 CURLINFO_PROXYAUTH_AVAIL
,
5599 #if HAVE_DECL_CURLINFO_OS_ERRNO
5600 case 25: /* CURLINFO_OS_ERRNO */
5601 resultType
= LongValue
;
5603 curlResult
= curl_easy_getinfo(connection
->connection
,
5609 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5610 case 26: /* CURLINFO_NUM_CONNECTS */
5611 resultType
= LongValue
;
5613 curlResult
= curl_easy_getinfo(connection
->connection
,
5614 CURLINFO_NUM_CONNECTS
,
5619 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5620 case 27: /* CURLINFO_SSL_ENGINES */
5621 resultType
= StringListValue
;
5623 curlResult
= curl_easy_getinfo(connection
->connection
,
5624 CURLINFO_SSL_ENGINES
,
5629 #if HAVE_DECL_CURLINFO_COOKIELIST
5630 case 28: /* CURLINFO_COOKIELIST */
5631 resultType
= StringListValue
;
5633 curlResult
= curl_easy_getinfo(connection
->connection
,
5634 CURLINFO_COOKIELIST
,
5639 #if HAVE_DECL_CURLINFO_LASTSOCKET
5640 case 29: /* CURLINFO_LASTSOCKET */
5641 resultType
= LongValue
;
5643 curlResult
= curl_easy_getinfo(connection
->connection
,
5644 CURLINFO_LASTSOCKET
,
5649 #if HAVE_DECL_CURLINFO_FTP_ENTRY_PATH
5650 case 30: /* CURLINFO_FTP_ENTRY_PATH */
5651 resultType
= StringValue
;
5653 curlResult
= curl_easy_getinfo(connection
->connection
,
5654 CURLINFO_FTP_ENTRY_PATH
,
5660 failwith("Invalid CURLINFO Option");
5664 if (curlResult
!= CURLE_OK
)
5665 raiseError(connection
, curlResult
);
5670 result
= alloc(1, StringValue
);
5671 Store_field(result
, 0, copy_string(strValue
?strValue
:""));
5675 result
= alloc(1, LongValue
);
5676 Store_field(result
, 0, Val_long(longValue
));
5680 result
= alloc(1, DoubleValue
);
5681 Store_field(result
, 0, copy_double(doubleValue
));
5684 case StringListValue
:
5685 result
= alloc(1, StringListValue
);
5686 Store_field(result
, 0, convertStringList(stringListValue
));
5694 ** curl_escape helper function
5697 CAMLprim value
helper_curl_escape(value str
)
5703 curlResult
= curl_escape(String_val(str
), string_length(str
));
5704 result
= copy_string(curlResult
);
5711 ** curl_unescape helper function
5714 CAMLprim value
helper_curl_unescape(value str
)
5720 curlResult
= curl_unescape(String_val(str
), string_length(str
));
5721 result
= copy_string(curlResult
);
5728 ** curl_getdate helper function
5731 CAMLprim value
helper_curl_getdate(value str
, value now
)
5733 CAMLparam2(str
, now
);
5738 curlNow
= (time_t)Double_val(now
);
5739 curlResult
= curl_getdate(String_val(str
), &curlNow
);
5740 result
= copy_double((double)curlResult
);
5746 ** curl_version helper function
5749 CAMLprim value
helper_curl_version(void)
5755 str
= curl_version();
5756 result
= copy_string(str
);
5762 * Curl multi stack support
5764 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5765 * Other exported functions are prefixed with caml_curlm_, some of them
5766 * can/should be decomposed into smaller parts.
5769 struct ml_multi_handle
5772 value values
; /* callbacks */
5777 curlmopt_socket_function
,
5779 /* last, not used */
5783 typedef struct ml_multi_handle ml_multi_handle
;
5785 #define Multi_val(v) (*(ml_multi_handle**)Data_custom_val(v))
5786 #define CURLM_val(v) (Multi_val(v)->handle)
5788 static struct custom_operations curl_multi_ops
= {
5790 custom_finalize_default
,
5791 custom_compare_default
,
5792 custom_hash_default
,
5793 custom_serialize_default
,
5794 custom_deserialize_default
5797 CAMLprim value
caml_curl_multi_init(value unit
)
5801 ml_multi_handle
* multi
= (ml_multi_handle
*)caml_stat_alloc(sizeof(ml_multi_handle
));
5802 CURLM
* h
= curl_multi_init();
5806 caml_stat_free(multi
);
5807 failwith("caml_curl_multi_init");
5811 multi
->values
= caml_alloc(multi_values_total
, 0);
5812 caml_register_generational_global_root(&multi
->values
);
5814 v
= caml_alloc_custom(&curl_multi_ops
, sizeof(ml_multi_handle
*), 0, 1);
5815 Multi_val(v
) = multi
;
5820 CAMLprim value
caml_curl_multi_cleanup(value handle
)
5823 ml_multi_handle
* h
= Multi_val(handle
);
5826 CAMLreturn(Val_unit
);
5828 caml_remove_generational_global_root(&h
->values
);
5830 if (CURLM_OK
!= curl_multi_cleanup(h
->handle
))
5831 failwith("caml_curl_multi_cleanup");
5833 Multi_val(handle
) = (ml_multi_handle
*)NULL
;
5835 CAMLreturn(Val_unit
);
5838 static CURL
* curlm_remove_finished(CURLM
* multi_handle
, CURLcode
* result
)
5840 int msgs_in_queue
= 0;
5844 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
5845 if (NULL
== msg
) return NULL
;
5846 if (CURLMSG_DONE
== msg
->msg
)
5848 CURL
* easy_handle
= msg
->easy_handle
;
5849 if (result
) *result
= msg
->data
.result
;
5850 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
5852 //failwith("curlm_remove_finished");
5859 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
5861 CAMLparam1(v_multi
);
5862 CAMLlocal2(v_easy
, v_tuple
);
5864 CURLM
* multi_handle
;
5867 multi_handle
= CURLM_val(v_multi
);
5869 caml_enter_blocking_section();
5870 handle
= curlm_remove_finished(multi_handle
,&result
);
5871 caml_leave_blocking_section();
5875 CAMLreturn(Val_none
);
5879 /* not good: same handle, but different block */
5880 v_easy
= caml_alloc(1, Abstract_tag
);
5881 Field(v_easy
, 0) = (value
)findConnection(handle
);
5882 v_tuple
= caml_alloc(2, 0);
5883 Store_field(v_tuple
,0,v_easy
);
5884 Store_field(v_tuple
,1,Val_int(result
)); /* CURLcode */
5885 CAMLreturn(Val_some(v_tuple
));
5889 static int curlm_wait_data(CURLM
* multi_handle
)
5891 struct timeval timeout
;
5903 /* set a suitable timeout */
5905 timeout
.tv_usec
= 0;
5907 /* get file descriptors from the transfers */
5908 ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
5910 if (ret
== CURLM_OK
&& maxfd
>= 0)
5912 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
5913 if (-1 != rc
) return 0;
5914 //printf("select error\n");
5918 //printf("curl_multi_fdset error\n");
5923 CAMLprim value
caml_curlm_wait_data(value v_multi
)
5925 CAMLparam1(v_multi
);
5929 h
= CURLM_val(v_multi
);
5931 caml_enter_blocking_section();
5932 ret
= curlm_wait_data(h
);
5933 caml_leave_blocking_section();
5935 CAMLreturn(Val_bool(0 == ret
));
5938 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
5940 CAMLparam2(v_multi
,v_easy
);
5942 if (CURLM_OK
!= curl_multi_add_handle(CURLM_val(v_multi
), Connection_val(v_easy
)->connection
))
5943 failwith("caml_curl_multi_add_handle");
5945 CAMLreturn(Val_unit
);
5948 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
5950 CAMLparam1(v_multi
);
5952 int still_running
= 0;
5954 h
= CURLM_val(v_multi
);
5956 caml_enter_blocking_section();
5957 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
5958 caml_leave_blocking_section();
5960 CAMLreturn(Val_int(still_running
));
5963 CAMLprim value
helper_curl_easy_strerror(value v_code
)
5966 CAMLreturn(caml_copy_string(curl_easy_strerror(Int_val(v_code
))));