4 *** Copyright (c) 2003-2008, Lars Nilsson, <lars@quantumchamaeleon.com>
5 *** Copyright (c) 2009, ygrek, <ygrek@autistici.org>
13 /* suppress false gcc warning on seekFunction */
14 #define CURL_DISABLE_TYPECHECK
15 #include <curl/curl.h>
17 #include <caml/alloc.h>
18 #include <caml/memory.h>
19 #include <caml/mlvalues.h>
20 #include <caml/callback.h>
21 #include <caml/fail.h>
22 #include <caml/unixsupport.h>
23 #include <caml/custom.h>
28 #pragma message("No config file given.")
31 void leave_blocking_section(void);
32 void enter_blocking_section(void);
34 #define Val_none Val_int(0)
41 some
= caml_alloc(1, 0);
42 Store_field( some
, 0, v
);
46 static value
Val_pair(value v1
, value v2
)
50 pair
= caml_alloc_small(2,0);
56 static value
Val_cons(value list
, value v
) { return Val_pair(v
,list
); }
58 typedef struct Connection Connection
;
59 typedef struct ConnectionList ConnectionList
;
61 #define Connection_val(v) (*(Connection**)Data_custom_val(v))
74 OcamlProgressCallback
,
78 OcamlSeekFunctionCallback
,
79 OcamlOpenSocketFunctionCallback
,
111 OcamlFTPAlternativeToUser
,
112 OcamlSSHPublicKeyFile
,
113 OcamlSSHPrivateKeyFile
,
114 OcamlSSHHostPublicKeyMD5
,
119 /* Not used, last for size */
131 size_t refcount
; /* number of references to this structure */
145 struct curl_slist
*httpHeader
;
146 struct curl_httppost
*httpPostFirst
;
147 struct curl_httppost
*httpPostLast
;
148 struct curl_slist
*httpPostStrings
;
149 struct curl_slist
*resolve
;
157 struct curl_slist
*quote
;
158 struct curl_slist
*postQuote
;
161 char *interface_
; /* `interface` gives problems on windows */
169 struct curl_slist
*http200Aliases
;
173 char *ftpAlternativeToUser
;
174 char *sshPublicKeyFile
;
175 char *sshPrivateKeyFile
;
176 char *sshHostPublicKeyMD5
;
177 char *copyPostFields
;
181 struct ConnectionList
187 static ConnectionList connectionList
= {NULL
, NULL
};
189 typedef struct CURLErrorMapping CURLErrorMapping
;
191 struct CURLErrorMapping
197 CURLErrorMapping errorMap
[] =
199 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
200 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL
},
202 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
204 #if HAVE_DECL_CURLE_FAILED_INIT
205 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT
},
207 {"CURLE_FAILED_INIT", -1},
209 #if HAVE_DECL_CURLE_URL_MALFORMAT
210 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT
},
212 {"CURLE_URL_MALFORMAT", -1},
214 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
215 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER
},
217 {"CURLE_URL_MALFORMAT_USER", -1},
219 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
220 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY
},
222 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
224 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
225 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST
},
227 {"CURLE_COULDNT_RESOLVE_HOST", -1},
229 #if HAVE_DECL_CURLE_COULDNT_CONNECT
230 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT
},
232 {"CURLE_COULDNT_CONNECT", -1},
234 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
235 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY
},
237 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
239 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
240 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED
},
242 {"CURLE_FTP_ACCESS_DENIED", -1},
244 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
245 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT
},
247 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
249 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
250 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY
},
252 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
254 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
255 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY
},
257 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
259 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
260 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY
},
262 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
264 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
265 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT
},
267 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
269 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
270 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST
},
272 {"CURLE_FTP_CANT_GET_HOST", -1},
274 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
275 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT
},
277 {"CURLE_FTP_CANT_RECONNECT", -1},
279 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
280 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY
},
282 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
284 #if HAVE_DECL_CURLE_PARTIAL_FILE
285 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE
},
287 {"CURLE_PARTIAL_FILE", -1},
289 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
290 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE
},
292 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
294 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
295 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR
},
297 {"CURLE_FTP_WRITE_ERROR", -1},
299 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
300 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR
},
302 {"CURLE_FTP_QUOTE_ERROR", -1},
304 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
305 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND
},
307 {"CURLE_HTTP_NOT_FOUND", -1},
309 #if HAVE_DECL_CURLE_WRITE_ERROR
310 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR
},
312 {"CURLE_WRITE_ERROR", -1},
314 #if HAVE_DECL_CURLE_MALFORMAT_USER
315 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER
},
317 {"CURLE_MALFORMAT_USER", -1},
319 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
320 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE
},
322 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
324 #if HAVE_DECL_CURLE_READ_ERROR
325 {"CURLE_READ_ERROR", CURLE_READ_ERROR
},
327 {"CURLE_READ_ERROR", -1},
329 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
330 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY
},
332 {"CURLE_OUT_OF_MEMORY", -1},
334 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
335 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED
},
337 {"CURLE_OPERATION_TIMEOUTED", -1},
339 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
340 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII
},
342 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
344 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
345 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED
},
347 {"CURLE_FTP_PORT_FAILED", -1},
349 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
350 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST
},
352 {"CURLE_FTP_COULDNT_USE_REST", -1},
354 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
355 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE
},
357 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
359 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
360 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR
},
362 {"CURLE_HTTP_RANGE_ERROR", -1},
364 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
365 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR
},
367 {"CURLE_HTTP_POST_ERROR", -1},
369 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
370 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR
},
372 {"CURLE_SSL_CONNECT_ERROR", -1},
374 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
375 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME
},
377 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
379 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
380 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE
},
382 {"CURLE_FILE_COULDNT_READ_FILE", -1},
384 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
385 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND
},
387 {"CURLE_LDAP_CANNOT_BIND", -1},
389 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
390 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED
},
392 {"CURLE_LDAP_SEARCH_FAILED", -1},
394 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
395 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND
},
397 {"CURLE_LIBRARY_NOT_FOUND", -1},
399 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
400 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND
},
402 {"CURLE_FUNCTION_NOT_FOUND", -1},
404 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
405 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK
},
407 {"CURLE_ABORTED_BY_CALLBACK", -1},
409 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
410 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT
},
412 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
414 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
415 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER
},
417 {"CURLE_BAD_CALLING_ORDER", -1},
419 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
420 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED
},
422 {"CURLE_HTTP_PORT_FAILED", -1},
424 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
425 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED
},
427 {"CURLE_BAD_PASSWORD_ENTERED", -1},
429 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
430 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS
},
432 {"CURLE_TOO_MANY_REDIRECTS", -1},
434 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
435 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION
},
437 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
439 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
440 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX
},
442 {"CURLE_TELNET_OPTION_SYNTAX", -1},
444 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
445 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE
},
447 {"CURLE_SSL_PEER_CERTIFICATE", -1},
449 #if HAVE_DECL_CURLE_GOT_NOTHING
450 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING
},
452 {"CURLE_GOT_NOTHING", -1},
454 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
455 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND
},
457 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
459 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
460 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED
},
462 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
464 #if HAVE_DECL_CURLE_SEND_ERROR
465 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR
},
467 {"CURLE_SEND_ERROR", -1},
469 #if HAVE_DECL_CURLE_RECV_ERROR
470 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR
},
472 {"CURLE_RECV_ERROR", -1},
474 #if HAVE_DECL_CURLE_SHARE_IN_USE
475 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE
},
477 {"CURLE_SHARE_IN_USE", -1},
479 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
480 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM
},
482 {"CURLE_SSL_CERTPROBLEN", -1},
484 #if HAVE_DECL_CURLE_SSL_CIPHER
485 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER
},
487 {"CURLE_SSL_CIPHER", -1},
489 #if HAVE_DECL_CURLE_SSL_CACERT
490 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT
},
492 {"CURLE_SSL_CACERT", -1},
494 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
495 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING
},
497 {"CURLE_BAD_CONTENT_ENCODING", -1},
499 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
500 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL
},
502 {"CURLE_LDAP_INVALID_URL", -1},
504 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
505 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED
},
507 {"CURLE_FILESIZE_EXCEEDED", -1},
509 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
510 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED
},
512 {"CURLE_FTP_SSL_FAILED", -1},
514 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
515 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND
},
517 {"CURLE_SEND_FAIL_REWIND", -1},
519 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
520 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED
},
522 {"CURLE_SSL_ENGINE_INITFAILED", -1},
524 #if HAVE_DECL_CURLE_LOGIN_DENIED
525 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED
},
527 {"CURLE_LOGIN_DENIED", -1},
529 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
530 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND
},
532 {"CURLE_TFTP_NOTFOUND", -1},
534 #if HAVE_DECL_CURLE_TFTP_PERM
535 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM
},
537 {"CURLE_TFTP_PERM", -1},
539 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
540 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL
},
542 {"CURLE_REMOTE_DISK_FULL", -1},
544 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
545 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL
},
547 {"CURLE_TFTP_ILLEGAL", -1},
549 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
550 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID
},
552 {"CURLE_TFTP_UNKNOWNID", -1},
554 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
555 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS
},
557 {"CURLE_REMOTE_FILE_EXISTS", -1},
559 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
560 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER
},
562 {"CURLE_TFTP_NOSUCHUSER", -1},
564 #if HAVE_DECL_CURLE_CONV_FAILED
565 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED
},
567 {"CURLE_CONV_FAILED", -1},
569 #if HAVE_DECL_CURLE_CONV_REQUIRED
570 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED
},
572 {"CURLE_CONV_REQUIRED", -1},
574 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
575 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE
},
577 {"CURLE_SSL_CACERT_BADFILE", -1},
579 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
580 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND
},
582 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
584 #if HAVE_DECL_CURLE_SSH
585 {"CURLE_SSH", CURLE_SSH
},
589 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
590 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED
},
592 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
594 #if HAVE_DECL_CURLE_AGAIN
595 {"CURLE_AGAIN", CURLE_AGAIN
},
599 {"CURLE_OK", CURLE_OK
},
603 typedef struct CURLOptionMapping CURLOptionMapping
;
605 struct CURLOptionMapping
607 void (*optionHandler
)(Connection
*, value
);
612 CURLOptionMapping unimplementedOptionMap
[] =
614 {NULL
, "CURLOPT_STDERR", CURLOPT_STDERR
},
618 static void handleWriteFunction(Connection
*, value
);
619 static void handleReadFunction(Connection
*, value
);
620 static void handleInFileSize(Connection
*, value
);
621 static void handleURL(Connection
*, value
);
622 static void handleProxy(Connection
*, value
);
623 static void handleProxyPort(Connection
*, value
);
624 static void handleHTTPProxyTunnel(Connection
*, value
);
625 static void handleVerbose(Connection
*, value
);
626 static void handleHeader(Connection
*, value
);
627 static void handleNoProgress(Connection
*, value
);
628 static void handleNoSignal(Connection
*, value
);
629 static void handleNoBody(Connection
*, value
);
630 static void handleFailOnError(Connection
*, value
);
631 static void handleUpload(Connection
*, value
);
632 static void handlePost(Connection
*, value
);
633 static void handleFTPListOnly(Connection
*, value
);
634 static void handleFTPAppend(Connection
*, value
);
635 static void handleNETRC(Connection
*, value
);
636 static void handleEncoding(Connection
*, value
);
637 static void handleFollowLocation(Connection
*, value
);
638 static void handleTransferText(Connection
*, value
);
639 static void handlePut(Connection
*, value
);
640 static void handleUserPwd(Connection
*, value
);
641 static void handleProxyUserPwd(Connection
*, value
);
642 static void handleRange(Connection
*, value
);
643 static void handleErrorBuffer(Connection
*, value
);
644 static void handleTimeout(Connection
*, value
);
645 static void handlePostFields(Connection
*, value
);
646 static void handlePostFieldSize(Connection
*, value
);
647 static void handleReferer(Connection
*, value
);
648 static void handleUserAgent(Connection
*, value
);
649 static void handleFTPPort(Connection
*, value
);
650 static void handleLowSpeedLimit(Connection
*, value
);
651 static void handleLowSpeedTime(Connection
*, value
);
652 static void handleResumeFrom(Connection
*, value
);
653 static void handleCookie(Connection
*, value
);
654 static void handleHTTPHeader(Connection
*, value
);
655 static void handleHTTPPost(Connection
*, value
);
656 static void handleSSLCert(Connection
*, value
);
657 static void handleSSLCertType(Connection
*, value
);
658 static void handleSSLCertPasswd(Connection
*, value
);
659 static void handleSSLKey(Connection
*, value
);
660 static void handleSSLKeyType(Connection
*, value
);
661 static void handleSSLKeyPasswd(Connection
*, value
);
662 static void handleSSLEngine(Connection
*, value
);
663 static void handleSSLEngineDefault(Connection
*, value
);
664 static void handleCRLF(Connection
*, value
);
665 static void handleQuote(Connection
*, value
);
666 static void handlePostQuote(Connection
*, value
);
667 static void handleHeaderFunction(Connection
*, value
);
668 static void handleCookieFile(Connection
*, value
);
669 static void handleSSLVersion(Connection
*, value
);
670 static void handleTimeCondition(Connection
*, value
);
671 static void handleTimeValue(Connection
*, value
);
672 static void handleCustomRequest(Connection
*, value
);
673 static void handleInterface(Connection
*, value
);
674 static void handleKRB4Level(Connection
*, value
);
675 static void handleProgressFunction(Connection
*, value
);
676 static void handleSSLVerifyPeer(Connection
*, value
);
677 static void handleCAInfo(Connection
*, value
);
678 static void handleCAPath(Connection
*, value
);
679 static void handleFileTime(Connection
*, value
);
680 static void handleMaxRedirs(Connection
*, value
);
681 static void handleMaxConnects(Connection
*, value
);
682 static void handleClosePolicy(Connection
*, value
);
683 static void handleFreshConnect(Connection
*, value
);
684 static void handleForbidReuse(Connection
*, value
);
685 static void handleRandomFile(Connection
*, value
);
686 static void handleEGDSocket(Connection
*, value
);
687 static void handleConnectTimeout(Connection
*, value
);
688 static void handleHTTPGet(Connection
*, value
);
689 static void handleSSLVerifyHost(Connection
*, value
);
690 static void handleCookieJar(Connection
*, value
);
691 static void handleSSLCipherList(Connection
*, value
);
692 static void handleHTTPVersion(Connection
*, value
);
693 static void handleFTPUseEPSV(Connection
*, value
);
694 static void handleDNSCacheTimeout(Connection
*, value
);
695 static void handleDNSUseGlobalCache(Connection
*, value
);
696 static void handleDebugFunction(Connection
*, value
);
697 static void handlePrivate(Connection
*, value
);
698 static void handleHTTP200Aliases(Connection
*, value
);
699 static void handleUnrestrictedAuth(Connection
*, value
);
700 static void handleFTPUseEPRT(Connection
*, value
);
701 static void handleHTTPAuth(Connection
*, value
);
702 static void handleFTPCreateMissingDirs(Connection
*, value
);
703 static void handleProxyAuth(Connection
*, value
);
704 static void handleFTPResponseTimeout(Connection
*, value
);
705 static void handleIPResolve(Connection
*, value
);
706 static void handleMaxFileSize(Connection
*, value
);
707 static void handleInFileSizeLarge(Connection
*, value
);
708 static void handleResumeFromLarge(Connection
*, value
);
709 static void handleMaxFileSizeLarge(Connection
*, value
);
710 static void handleNETRCFile(Connection
*, value
);
711 static void handleFTPSSL(Connection
*, value
);
712 static void handlePostFieldSizeLarge(Connection
*, value
);
713 static void handleTCPNoDelay(Connection
*, value
);
714 static void handleFTPSSLAuth(Connection
*, value
);
715 static void handleIOCTLFunction(Connection
*, value
);
716 static void handleFTPAccount(Connection
*, value
);
717 static void handleCookieList(Connection
*, value
);
718 static void handleIgnoreContentLength(Connection
*, value
);
719 static void handleFTPSkipPASVIP(Connection
*, value
);
720 static void handleFTPFileMethod(Connection
*, value
);
721 static void handleLocalPort(Connection
*, value
);
722 static void handleLocalPortRange(Connection
*, value
);
723 static void handleConnectOnly(Connection
*, value
);
724 static void handleMaxSendSpeedLarge(Connection
*, value
);
725 static void handleMaxRecvSpeedLarge(Connection
*, value
);
726 static void handleFTPAlternativeToUser(Connection
*, value
);
727 static void handleSSLSessionIdCache(Connection
*, value
);
728 static void handleSSHAuthTypes(Connection
*, value
);
729 static void handleSSHPublicKeyFile(Connection
*, value
);
730 static void handleSSHPrivateKeyFile(Connection
*, value
);
731 static void handleFTPSSLCCC(Connection
*, value
);
732 static void handleTimeoutMS(Connection
*, value
);
733 static void handleConnectTimeoutMS(Connection
*, value
);
734 static void handleHTTPTransferDecoding(Connection
*, value
);
735 static void handleHTTPContentDecoding(Connection
*, value
);
736 static void handleNewFilePerms(Connection
*, value
);
737 static void handleNewDirectoryPerms(Connection
*, value
);
738 static void handlePost301(Connection
*, value
);
739 static void handleSSHHostPublicKeyMD5(Connection
*, value
);
740 static void handleCopyPostFields(Connection
*, value
);
741 static void handleProxyTransferMode(Connection
*, value
);
742 static void handleSeekFunction(Connection
*, value
);
743 static void handleAutoReferer(Connection
*, value
);
744 static void handleOpenSocketFunction(Connection
*, value
);
745 static void handleProxyType(Connection
*, value
);
746 static void handleProtocols(Connection
*, value
);
747 static void handleRedirProtocols(Connection
*, value
);
748 static void handleResolve(Connection
*, value
);
749 static void handleDnsServers(Connection
*, value
);
751 CURLOptionMapping implementedOptionMap
[] =
753 {handleWriteFunction
, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION
},
754 {handleReadFunction
, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION
},
755 {handleInFileSize
, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE
},
756 {handleURL
, "CURLOPT_URL", CURLOPT_URL
},
757 {handleProxy
, "CURLOPT_PROXY", CURLOPT_PROXY
},
758 {handleProxyPort
, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT
},
759 {handleHTTPProxyTunnel
, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL
},
760 {handleVerbose
, "CURLOPT_VERBOSE", CURLOPT_VERBOSE
},
761 {handleHeader
, "CURLOPT_HEADER", CURLOPT_HEADER
},
762 {handleNoProgress
, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS
},
763 #if HAVE_DECL_CURLOPT_NOSIGNAL
764 {handleNoSignal
, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL
},
766 {handleNoSignal
, "CURLOPT_NOSIGNAL", 0},
768 {handleNoBody
, "CURLOPT_NOBODY", CURLOPT_NOBODY
},
769 {handleFailOnError
, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR
},
770 {handleUpload
, "CURLOPT_UPLOAD", CURLOPT_UPLOAD
},
771 {handlePost
, "CURLOPT_POST", CURLOPT_POST
},
772 {handleFTPListOnly
, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY
},
773 {handleFTPAppend
, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND
},
774 {handleNETRC
, "CURLOPT_NETRC", CURLOPT_NETRC
},
775 #if HAVE_DECL_CURLOPT_ENCODING
776 {handleEncoding
, "CURLOPT_ENCODING", CURLOPT_ENCODING
},
778 {handleEncoding
, "CURLOPT_ENCODING", 0},
780 {handleFollowLocation
, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION
},
781 {handleTransferText
, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT
},
782 {handlePut
, "CURLOPT_PUT", CURLOPT_PUT
},
783 {handleUserPwd
, "CURLOPT_USERPWD", CURLOPT_USERPWD
},
784 {handleProxyUserPwd
, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD
},
785 {handleRange
, "CURLOPT_RANGE", CURLOPT_RANGE
},
786 {handleErrorBuffer
, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER
},
787 {handleTimeout
, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT
},
788 {handlePostFields
, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS
},
789 {handlePostFieldSize
, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE
},
790 {handleReferer
, "CURLOPT_REFERER", CURLOPT_REFERER
},
791 {handleUserAgent
, "CURLOPT_USERAGENT", CURLOPT_USERAGENT
},
792 {handleFTPPort
, "CURLOPT_FTPPORT", CURLOPT_FTPPORT
},
793 {handleLowSpeedLimit
, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT
},
794 {handleLowSpeedTime
, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME
},
795 {handleResumeFrom
, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM
},
796 {handleCookie
, "CURLOPT_COOKIE", CURLOPT_COOKIE
},
797 {handleHTTPHeader
, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER
},
798 {handleHTTPPost
, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST
},
799 {handleSSLCert
, "CURLOPT_SSLCERT", CURLOPT_SSLCERT
},
800 {handleSSLCertType
, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE
},
801 {handleSSLCertPasswd
, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD
},
802 {handleSSLKey
, "CURLOPT_SSLKEY", CURLOPT_SSLKEY
},
803 {handleSSLKeyType
, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE
},
804 {handleSSLKeyPasswd
, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD
},
805 {handleSSLEngine
, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE
},
806 {handleSSLEngineDefault
, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT
},
807 {handleCRLF
, "CURLOPT_CRLF", CURLOPT_CRLF
},
808 {handleQuote
, "CURLOPT_QUOTE", CURLOPT_QUOTE
},
809 {handlePostQuote
, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE
},
810 {handleHeaderFunction
, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION
},
811 {handleCookieFile
, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE
},
812 {handleSSLVersion
, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION
},
813 {handleTimeCondition
, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION
},
814 {handleTimeValue
, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE
},
815 {handleCustomRequest
, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST
},
816 {handleInterface
, "CURLOPT_INTERFACE", CURLOPT_INTERFACE
},
817 {handleKRB4Level
, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL
},
818 {handleProgressFunction
, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION
},
819 {handleSSLVerifyPeer
, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER
},
820 {handleCAInfo
, "CURLOPT_CAINFO", CURLOPT_CAINFO
},
821 {handleCAPath
, "CURLOPT_CAPATH", CURLOPT_CAPATH
},
822 {handleFileTime
, "CURLOPT_FILETIME", CURLOPT_FILETIME
},
823 {handleMaxRedirs
, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS
},
824 {handleMaxConnects
, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS
},
825 {handleClosePolicy
, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY
},
826 {handleFreshConnect
, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT
},
827 {handleForbidReuse
, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE
},
828 {handleRandomFile
, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE
},
829 {handleEGDSocket
, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET
},
830 {handleConnectTimeout
, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT
},
831 {handleHTTPGet
, "CURLOPT_HTTPGET", CURLOPT_HTTPGET
},
832 {handleSSLVerifyHost
, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST
},
833 {handleCookieJar
, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR
},
834 {handleSSLCipherList
, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST
},
835 {handleHTTPVersion
, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION
},
836 {handleFTPUseEPSV
, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV
},
837 {handleDNSCacheTimeout
, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT
},
838 {handleDNSUseGlobalCache
, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE
},
839 {handleDebugFunction
, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION
},
840 #if HAVE_DECL_CURLOPT_PRIVATE
841 {handlePrivate
, "CURLOPT_PRIVATE", CURLOPT_PRIVATE
},
843 {handlePrivate
, "CURLOPT_PRIVATE", 0},
845 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
846 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES
},
848 {handleHTTP200Aliases
, "CURLOPT_HTTP200ALIASES", 0},
850 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
851 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH
},
853 {handleUnrestrictedAuth
, "CURLOPT_UNRESTRICTED_AUTH", 0},
855 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
856 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT
},
858 {handleFTPUseEPRT
, "CURLOPT_FTP_USE_EPRT", 0},
860 #if HAVE_DECL_CURLOPT_HTTPAUTH
861 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH
},
863 {handleHTTPAuth
, "CURLOPT_HTTPAUTH", 0},
865 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
866 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS
},
868 {handleFTPCreateMissingDirs
, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
870 #if HAVE_DECL_CURLOPT_PROXYAUTH
871 {handleProxyAuth
, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH
},
873 {handleProxyAuth
, "CURLOPT_PROXYAUTH", 0},
875 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
876 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT
},
878 {handleFTPResponseTimeout
, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
880 #if HAVE_DECL_CURLOPT_IPRESOLVE
881 {handleIPResolve
, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE
},
883 {handleIPResolve
, "CURLOPT_IPRESOLVE", 0},
885 #if HAVE_DECL_CURLOPT_MAXFILESIZE
886 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE
},
888 {handleMaxFileSize
, "CURLOPT_MAXFILESIZE", 0},
890 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
891 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE
},
893 {handleInFileSizeLarge
, "CURLOPT_INFILESIZE_LARGE", 0},
895 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
896 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE
},
898 {handleResumeFromLarge
, "CURLOPT_RESUME_FROM_LARGE", 0},
900 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
901 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE
},
903 {handleMaxFileSizeLarge
, "CURLOPT_MAXFILESIZE_LARGE", 0},
905 #if HAVE_DECL_CURLOPT_NETRC_FILE
906 {handleNETRCFile
, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE
},
908 {handleNETRCFile
, "CURLOPT_NETRC_FILE", 0},
910 #if HAVE_DECL_CURLOPT_FTP_SSL
911 {handleFTPSSL
, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL
},
913 {handleFTPSSL
, "CURLOPT_FTP_SSL", 0},
915 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
916 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE
},
918 {handlePostFieldSizeLarge
, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
920 #if HAVE_DECL_CURLOPT_TCP_NODELAY
921 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY
},
923 {handleTCPNoDelay
, "CURLOPT_TCP_NODELAY", 0},
925 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
926 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH
},
928 {handleFTPSSLAuth
, "CURLOPT_FTPSSLAUTH", 0},
930 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
931 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION
},
933 {handleIOCTLFunction
, "CURLOPT_IOCTLFUNCTION", 0},
935 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
936 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT
},
938 {handleFTPAccount
, "CURLOPT_FTP_ACCOUNT", 0},
940 #if HAVE_DECL_CURLOPT_COOKIELIST
941 {handleCookieList
, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST
},
943 {handleCookieList
, "CURLOPT_COOKIELIST", 0},
945 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
946 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH
},
948 {handleIgnoreContentLength
, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
950 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
951 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP
},
953 {handleFTPSkipPASVIP
, "CURLOPT_FTP_SKIP_PASV_IP", 0},
955 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
956 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD
},
958 {handleFTPFileMethod
, "CURLOPT_FTP_FILEMETHOD", 0},
960 #if HAVE_DECL_CURLOPT_LOCALPORT
961 {handleLocalPort
, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT
},
963 {handleLocalPort
, "CURLOPT_LOCALPORT", 0},
965 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
966 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE
},
968 {handleLocalPortRange
, "CURLOPT_LOCALPORTRANGE", 0},
970 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
971 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY
},
973 {handleConnectOnly
, "CURLOPT_CONNECT_ONLY", 0},
975 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
976 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE
},
978 {handleMaxSendSpeedLarge
, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
980 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
981 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE
},
983 {handleMaxRecvSpeedLarge
, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
985 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
986 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER
},
988 {handleFTPAlternativeToUser
, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
990 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
991 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE
},
993 {handleSSLSessionIdCache
, "CURLOPT_SSL_SESSIONID_CACHE", 0},
995 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
996 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES
},
998 {handleSSHAuthTypes
, "CURLOPT_SSH_AUTH_TYPES", 0},
1000 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
1001 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE
},
1003 {handleSSHPublicKeyFile
, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
1005 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
1006 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE
},
1008 {handleSSHPrivateKeyFile
, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
1010 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
1011 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC
},
1013 {handleFTPSSLCCC
, "CURLOPT_FTP_SSL_CCC", 0},
1015 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
1016 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS
},
1018 {handleTimeoutMS
, "CURLOPT_TIMEOUT_MS", 0},
1020 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
1021 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS
},
1023 {handleConnectTimeoutMS
, "CURLOPT_CONNECTTIMEOUT_MS", 0},
1025 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
1026 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING
},
1028 {handleHTTPTransferDecoding
, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
1030 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1031 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING
},
1033 {handleHTTPContentDecoding
, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1035 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1036 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS
},
1038 {handleNewFilePerms
, "CURLOPT_NEW_FILE_PERMS", 0},
1040 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1041 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS
},
1043 {handleNewDirectoryPerms
, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1045 #if HAVE_DECL_CURLOPT_POST301
1046 {handlePost301
, "CURLOPT_POST301", CURLOPT_POST301
},
1048 {handlePost301
, "CURLOPT_POST301", 0},
1050 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1051 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
},
1053 {handleSSHHostPublicKeyMD5
, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1055 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1056 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS
},
1058 {handleCopyPostFields
, "CURLOPT_COPYPOSTFIELDS", 0},
1060 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1061 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE
},
1063 {handleProxyTransferMode
, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1065 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1066 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION
},
1068 {handleSeekFunction
, "CURLOPT_SEEKFUNCTION", 0},
1070 #if HAVE_DECL_CURLOPT_AUTOREFERER
1071 {handleAutoReferer
, "CURLOPT_AUTOREFERER", CURLOPT_AUTOREFERER
},
1073 {handleAutoReferer
, "CURLOPT_AUTOREFERER", 0},
1075 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
1076 {handleOpenSocketFunction
, "CURLOPT_OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION
},
1078 {handleOpenSocketFunction
, "CURLOPT_OPENSOCKETFUNCTION", 0},
1080 #if HAVE_DECL_CURLOPT_PROXYTYPE
1081 {handleProxyType
, "CURLOPT_PROXYTYPE", CURLOPT_PROXYTYPE
},
1083 {handleProxyType
, "CURLOPT_PROXYTYPE", 0},
1085 #if HAVE_DECL_CURLOPT_PROTOCOLS
1086 {handleProtocols
, "CURLOPT_PROTOCOLS", CURLOPT_PROTOCOLS
},
1088 {handleProtocols
, "CURLOPT_PROTOCOLS", 0},
1090 #if HAVE_DECL_CURLOPT_REDIR_PROTOCOLS
1091 {handleRedirProtocols
, "CURLOPT_REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS
},
1093 {handleRedirProtocols
, "CURLOPT_REDIR_PROTOCOLS", 0},
1095 #if HAVE_DECL_CURLOPT_RESOLVE
1096 {handleResolve
, "CURLOPT_RESOLVE", CURLOPT_RESOLVE
},
1098 {handleResolve
, "CURLOPT_RESOLVE", 0},
1100 #if HAVE_DECL_CURLOPT_DNS_SERVERS
1101 {handleDnsServers
, "CURLOPT_DNS_SERVERS", CURLOPT_DNS_SERVERS
},
1103 {handleDnsServers
, "CURLOPT_DNS_SERVERS", 0},
1107 static char *findOption(CURLOptionMapping optionMap
[],
1110 return optionMap
[option
].name
;
1113 static void free_curl_slist(struct curl_slist
*slist
)
1118 curl_slist_free_all(slist
);
1121 static void raiseError(Connection
*conn
, CURLcode code
)
1124 CAMLlocal1(exceptionData
);
1126 char *errorString
= "Unknown Error";
1129 for (i
= 0; errorMap
[i
].name
!= NULL
; i
++)
1131 if (errorMap
[i
].error
== code
)
1133 errorString
= errorMap
[i
].name
;
1138 exceptionData
= caml_alloc(3, 0);
1140 Store_field(exceptionData
, 0, Val_int(code
));
1141 Store_field(exceptionData
, 1, Val_int(code
));
1142 Store_field(exceptionData
, 2, copy_string(errorString
));
1144 if (conn
!= NULL
&& conn
->errorBuffer
!= NULL
)
1146 Store_field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0,
1147 copy_string(conn
->errorBuffer
));
1150 exception
= caml_named_value("CurlException");
1152 if (exception
== NULL
)
1153 caml_failwith("CurlException not registered");
1155 raise_with_arg(*exception
, exceptionData
);
1160 static void resetOcamlValues(Connection
* connection
)
1164 for (i
= 0; i
< OcamlValuesSize
; i
++)
1165 Store_field(connection
->ocamlValues
, i
, Val_unit
);
1168 static Connection
* allocConnection(CURL
* h
)
1170 Connection
* connection
= (Connection
*)malloc(sizeof(Connection
));
1172 connection
->ocamlValues
= caml_alloc(OcamlValuesSize
, 0);
1173 resetOcamlValues(connection
);
1174 register_global_root(&connection
->ocamlValues
);
1176 connection
->connection
= h
;
1178 connection
->next
= NULL
;
1179 connection
->prev
= NULL
;
1181 if (connectionList
.tail
== NULL
)
1183 connectionList
.tail
= connection
;
1184 connectionList
.head
= connection
;
1188 connection
->prev
= connectionList
.head
;
1189 connectionList
.head
->next
= connection
;
1190 connectionList
.head
= connection
;
1193 connection
->refcount
= 0;
1195 connection
->url
= NULL
;
1196 connection
->proxy
= NULL
;
1197 connection
->userPwd
= NULL
;
1198 connection
->proxyUserPwd
= NULL
;
1199 connection
->range
= NULL
;
1200 connection
->errorBuffer
= NULL
;
1201 connection
->postFields
= NULL
;
1202 connection
->postFieldSize
= -1;
1203 connection
->referer
= NULL
;
1204 connection
->userAgent
= NULL
;
1205 connection
->ftpPort
= NULL
;
1206 connection
->cookie
= NULL
;
1207 connection
->httpHeader
= NULL
;
1208 connection
->httpPostFirst
= NULL
;
1209 connection
->httpPostLast
= NULL
;
1210 connection
->httpPostStrings
= NULL
;
1211 connection
->sslCert
= NULL
;
1212 connection
->sslCertType
= NULL
;
1213 connection
->sslCertPasswd
= NULL
;
1214 connection
->sslKey
= NULL
;
1215 connection
->sslKeyType
= NULL
;
1216 connection
->sslKeyPasswd
= NULL
;
1217 connection
->sslEngine
= NULL
;
1218 connection
->quote
= NULL
;
1219 connection
->postQuote
= NULL
;
1220 connection
->cookieFile
= NULL
;
1221 connection
->customRequest
= NULL
;
1222 connection
->interface_
= NULL
;
1223 connection
->caInfo
= NULL
;
1224 connection
->caPath
= NULL
;
1225 connection
->randomFile
= NULL
;
1226 connection
->egdSocket
= NULL
;
1227 connection
->cookieJar
= NULL
;
1228 connection
->sslCipherList
= NULL
;
1229 connection
->private = NULL
;
1230 connection
->http200Aliases
= NULL
;
1231 connection
->netrcFile
= NULL
;
1232 connection
->ftpaccount
= NULL
;
1233 connection
->cookielist
= NULL
;
1234 connection
->ftpAlternativeToUser
= NULL
;
1235 connection
->sshPublicKeyFile
= NULL
;
1236 connection
->sshPrivateKeyFile
= NULL
;
1237 connection
->copyPostFields
= NULL
;
1238 connection
->resolve
= NULL
;
1239 connection
->dns_servers
= NULL
;
1244 static Connection
*newConnection(void)
1248 caml_enter_blocking_section();
1249 h
= curl_easy_init();
1250 caml_leave_blocking_section();
1252 return allocConnection(h
);
1255 static Connection
*duplicateConnection(Connection
*original
)
1257 Connection
*connection
;
1260 caml_enter_blocking_section();
1261 h
= curl_easy_duphandle(original
->connection
);
1262 caml_leave_blocking_section();
1264 connection
= allocConnection(h
);
1266 Store_field(connection
->ocamlValues
, OcamlWriteCallback
,
1267 Field(original
->ocamlValues
, OcamlWriteCallback
));
1268 Store_field(connection
->ocamlValues
, OcamlReadCallback
,
1269 Field(original
->ocamlValues
, OcamlReadCallback
));
1270 Store_field(connection
->ocamlValues
, OcamlErrorBuffer
,
1271 Field(original
->ocamlValues
, OcamlErrorBuffer
));
1272 Store_field(connection
->ocamlValues
, OcamlPostFields
,
1273 Field(original
->ocamlValues
, OcamlPostFields
));
1274 Store_field(connection
->ocamlValues
, OcamlHTTPHeader
,
1275 Field(original
->ocamlValues
, OcamlHTTPHeader
));
1276 Store_field(connection
->ocamlValues
, OcamlQuote
,
1277 Field(original
->ocamlValues
, OcamlQuote
));
1278 Store_field(connection
->ocamlValues
, OcamlPostQuote
,
1279 Field(original
->ocamlValues
, OcamlPostQuote
));
1280 Store_field(connection
->ocamlValues
, OcamlHeaderCallback
,
1281 Field(original
->ocamlValues
, OcamlHeaderCallback
));
1282 Store_field(connection
->ocamlValues
, OcamlProgressCallback
,
1283 Field(original
->ocamlValues
, OcamlProgressCallback
));
1284 Store_field(connection
->ocamlValues
, OcamlDebugCallback
,
1285 Field(original
->ocamlValues
, OcamlDebugCallback
));
1286 Store_field(connection
->ocamlValues
, OcamlHTTP200Aliases
,
1287 Field(original
->ocamlValues
, OcamlHTTP200Aliases
));
1288 Store_field(connection
->ocamlValues
, OcamlIOCTLCallback
,
1289 Field(original
->ocamlValues
, OcamlIOCTLCallback
));
1290 Store_field(connection
->ocamlValues
, OcamlSeekFunctionCallback
,
1291 Field(original
->ocamlValues
, OcamlSeekFunctionCallback
));
1293 if (Field(original
->ocamlValues
, OcamlURL
) != Val_unit
)
1294 handleURL(connection
, Field(original
->ocamlValues
,
1296 if (Field(original
->ocamlValues
, OcamlProxy
) != Val_unit
)
1297 handleProxy(connection
, Field(original
->ocamlValues
,
1299 if (Field(original
->ocamlValues
, OcamlUserPWD
) != Val_unit
)
1300 handleUserPwd(connection
, Field(original
->ocamlValues
,
1302 if (Field(original
->ocamlValues
, OcamlProxyUserPWD
) != Val_unit
)
1303 handleProxyUserPwd(connection
, Field(original
->ocamlValues
,
1304 OcamlProxyUserPWD
));
1305 if (Field(original
->ocamlValues
, OcamlRange
) != Val_unit
)
1306 handleRange(connection
, Field(original
->ocamlValues
,
1308 if (Field(original
->ocamlValues
, OcamlErrorBuffer
) != Val_unit
)
1309 handleErrorBuffer(connection
, Field(original
->ocamlValues
,
1311 if (Field(original
->ocamlValues
, OcamlPostFields
) != Val_unit
)
1312 handlePostFields(connection
, Field(original
->ocamlValues
,
1314 if (Field(original
->ocamlValues
, OcamlReferer
) != Val_unit
)
1315 handleReferer(connection
, Field(original
->ocamlValues
,
1317 if (Field(original
->ocamlValues
, OcamlUserAgent
) != Val_unit
)
1318 handleUserAgent(connection
, Field(original
->ocamlValues
,
1320 if (Field(original
->ocamlValues
, OcamlFTPPort
) != Val_unit
)
1321 handleFTPPort(connection
, Field(original
->ocamlValues
,
1323 if (Field(original
->ocamlValues
, OcamlCookie
) != Val_unit
)
1324 handleCookie(connection
, Field(original
->ocamlValues
,
1326 if (Field(original
->ocamlValues
, OcamlHTTPHeader
) != Val_unit
)
1327 handleHTTPHeader(connection
, Field(original
->ocamlValues
,
1329 if (Field(original
->ocamlValues
, OcamlHTTPPost
) != Val_unit
)
1330 handleHTTPPost(connection
, Field(original
->ocamlValues
,
1332 if (Field(original
->ocamlValues
, OcamlSSLCert
) != Val_unit
)
1333 handleSSLCert(connection
, Field(original
->ocamlValues
,
1335 if (Field(original
->ocamlValues
, OcamlSSLCertType
) != Val_unit
)
1336 handleSSLCertType(connection
, Field(original
->ocamlValues
,
1338 if (Field(original
->ocamlValues
, OcamlSSLCertPasswd
) != Val_unit
)
1339 handleSSLCertPasswd(connection
, Field(original
->ocamlValues
,
1340 OcamlSSLCertPasswd
));
1341 if (Field(original
->ocamlValues
, OcamlSSLKey
) != Val_unit
)
1342 handleSSLKey(connection
, Field(original
->ocamlValues
,
1344 if (Field(original
->ocamlValues
, OcamlSSLKeyType
) != Val_unit
)
1345 handleSSLKeyType(connection
, Field(original
->ocamlValues
,
1347 if (Field(original
->ocamlValues
, OcamlSSLKeyPasswd
) != Val_unit
)
1348 handleSSLKeyPasswd(connection
, Field(original
->ocamlValues
,
1349 OcamlSSLKeyPasswd
));
1350 if (Field(original
->ocamlValues
, OcamlSSLEngine
) != Val_unit
)
1351 handleSSLEngine(connection
, Field(original
->ocamlValues
,
1353 if (Field(original
->ocamlValues
, OcamlQuote
) != Val_unit
)
1354 handleQuote(connection
, Field(original
->ocamlValues
,
1356 if (Field(original
->ocamlValues
, OcamlPostQuote
) != Val_unit
)
1357 handlePostQuote(connection
, Field(original
->ocamlValues
,
1359 if (Field(original
->ocamlValues
, OcamlCookieFile
) != Val_unit
)
1360 handleCookieFile(connection
, Field(original
->ocamlValues
,
1362 if (Field(original
->ocamlValues
, OcamlCustomRequest
) != Val_unit
)
1363 handleCustomRequest(connection
, Field(original
->ocamlValues
,
1364 OcamlCustomRequest
));
1365 if (Field(original
->ocamlValues
, OcamlInterface
) != Val_unit
)
1366 handleInterface(connection
, Field(original
->ocamlValues
,
1368 if (Field(original
->ocamlValues
, OcamlCAInfo
) != Val_unit
)
1369 handleCAInfo(connection
, Field(original
->ocamlValues
,
1371 if (Field(original
->ocamlValues
, OcamlCAPath
) != Val_unit
)
1372 handleCAPath(connection
, Field(original
->ocamlValues
,
1374 if (Field(original
->ocamlValues
, OcamlRandomFile
) != Val_unit
)
1375 handleRandomFile(connection
, Field(original
->ocamlValues
,
1377 if (Field(original
->ocamlValues
, OcamlEGDSocket
) != Val_unit
)
1378 handleEGDSocket(connection
, Field(original
->ocamlValues
,
1380 if (Field(original
->ocamlValues
, OcamlCookieJar
) != Val_unit
)
1381 handleCookieJar(connection
, Field(original
->ocamlValues
,
1383 if (Field(original
->ocamlValues
, OcamlSSLCipherList
) != Val_unit
)
1384 handleSSLCipherList(connection
, Field(original
->ocamlValues
,
1385 OcamlSSLCipherList
));
1386 if (Field(original
->ocamlValues
, OcamlPrivate
) != Val_unit
)
1387 handlePrivate(connection
, Field(original
->ocamlValues
,
1389 if (Field(original
->ocamlValues
, OcamlHTTP200Aliases
) != Val_unit
)
1390 handleHTTP200Aliases(connection
, Field(original
->ocamlValues
,
1391 OcamlHTTP200Aliases
));
1392 if (Field(original
->ocamlValues
, OcamlNETRCFile
) != Val_unit
)
1393 handleNETRCFile(connection
, Field(original
->ocamlValues
,
1395 if (Field(original
->ocamlValues
, OcamlFTPAccount
) != Val_unit
)
1396 handleFTPAccount(connection
, Field(original
->ocamlValues
,
1398 if (Field(original
->ocamlValues
, OcamlCookieList
) != Val_unit
)
1399 handleCookieList(connection
, Field(original
->ocamlValues
,
1401 if (Field(original
->ocamlValues
, OcamlFTPAlternativeToUser
) != Val_unit
)
1402 handleFTPAlternativeToUser(connection
,
1403 Field(original
->ocamlValues
,
1404 OcamlFTPAlternativeToUser
));
1405 if (Field(original
->ocamlValues
, OcamlSSHPublicKeyFile
) != Val_unit
)
1406 handleSSHPublicKeyFile(connection
,
1407 Field(original
->ocamlValues
,
1408 OcamlSSHPublicKeyFile
));
1409 if (Field(original
->ocamlValues
, OcamlSSHPrivateKeyFile
) != Val_unit
)
1410 handleSSHPrivateKeyFile(connection
,
1411 Field(original
->ocamlValues
,
1412 OcamlSSHPrivateKeyFile
));
1413 if (Field(original
->ocamlValues
, OcamlCopyPostFields
) != Val_unit
)
1414 handleCopyPostFields(connection
,
1415 Field(original
->ocamlValues
,
1416 OcamlCopyPostFields
));
1417 if (Field(original
->ocamlValues
, OcamlDNSServers
) != Val_unit
)
1418 handleDnsServers(connection
,
1419 Field(original
->ocamlValues
,
1425 static void free_if(void* p
) { if (NULL
!= p
) free(p
); }
1427 static void removeConnection(Connection
*connection
, int finalization
)
1429 const char* fin_url
= NULL
;
1431 if (!connection
->connection
)
1433 return; /* already cleaned up */
1438 /* cannot engage OCaml runtime at finalization, just report leak */
1439 if (CURLE_OK
!= curl_easy_getinfo(connection
->connection
, CURLINFO_EFFECTIVE_URL
, &fin_url
) || NULL
== fin_url
)
1441 fin_url
= "unknown";
1443 fprintf(stderr
,"Curl: handle %p leaked, conn %p, url %s\n", connection
->connection
, connection
, fin_url
);
1448 enter_blocking_section();
1449 curl_easy_cleanup(connection
->connection
);
1450 leave_blocking_section();
1453 connection
->connection
= NULL
;
1455 if (connectionList
.tail
== connection
)
1456 connectionList
.tail
= connectionList
.tail
->next
;
1457 if (connectionList
.head
== connection
)
1458 connectionList
.head
= connectionList
.head
->prev
;
1460 if (connection
->next
!= NULL
)
1461 connection
->next
->prev
= connection
->prev
;
1462 if (connection
->prev
!= NULL
)
1463 connection
->prev
->next
= connection
->next
;
1465 remove_global_root(&connection
->ocamlValues
);
1467 free_if(connection
->url
);
1468 free_if(connection
->proxy
);
1469 free_if(connection
->userPwd
);
1470 free_if(connection
->proxyUserPwd
);
1471 free_if(connection
->range
);
1472 free_if(connection
->errorBuffer
);
1473 free_if(connection
->postFields
);
1474 free_if(connection
->referer
);
1475 free_if(connection
->userAgent
);
1476 free_if(connection
->ftpPort
);
1477 free_if(connection
->cookie
);
1478 free_curl_slist(connection
->httpHeader
);
1479 if (connection
->httpPostFirst
!= NULL
)
1480 curl_formfree(connection
->httpPostFirst
);
1481 free_curl_slist(connection
->httpPostStrings
);
1482 free_curl_slist(connection
->resolve
);
1483 free_if(connection
->sslCert
);
1484 free_if(connection
->sslCertType
);
1485 free_if(connection
->sslCertPasswd
);
1486 free_if(connection
->sslKey
);
1487 free_if(connection
->sslKeyType
);
1488 free_if(connection
->sslKeyPasswd
);
1489 free_if(connection
->sslEngine
);
1490 free_curl_slist(connection
->quote
);
1491 free_curl_slist(connection
->postQuote
);
1492 free_if(connection
->cookieFile
);
1493 free_if(connection
->customRequest
);
1494 free_if(connection
->interface_
);
1495 free_if(connection
->caInfo
);
1496 free_if(connection
->caPath
);
1497 free_if(connection
->randomFile
);
1498 free_if(connection
->egdSocket
);
1499 free_if(connection
->cookieJar
);
1500 free_if(connection
->sslCipherList
);
1501 free_if(connection
->private);
1502 free_curl_slist(connection
->http200Aliases
);
1503 free_if(connection
->netrcFile
);
1504 free_if(connection
->ftpaccount
);
1505 free_if(connection
->cookielist
);
1506 free_if(connection
->ftpAlternativeToUser
);
1507 free_if(connection
->sshPublicKeyFile
);
1508 free_if(connection
->sshPrivateKeyFile
);
1509 free_if(connection
->copyPostFields
);
1510 free_if(connection
->dns_servers
);
1514 static void checkConnection(Connection
* connection
)
1519 static void checkConnection(Connection
*connection
)
1521 Connection
*listIter
;
1523 listIter
= connectionList
.tail
;
1525 while (listIter
!= NULL
)
1527 if (listIter
== connection
)
1530 listIter
= listIter
->next
;
1533 failwith("Invalid Connection");
1537 static Connection
* findConnection(CURL
* h
)
1539 Connection
*listIter
;
1541 listIter
= connectionList
.tail
;
1543 while (listIter
!= NULL
)
1545 if (listIter
->connection
== h
)
1548 listIter
= listIter
->next
;
1551 failwith("Unknown handle");
1554 void op_curl_easy_finalize(value v
)
1556 Connection
* conn
= Connection_val(v
);
1557 /* same connection may be referenced by several different
1558 OCaml values, see e.g. caml_curl_multi_remove_finished */
1560 if (0 == conn
->refcount
)
1562 removeConnection(conn
, 1);
1567 int op_curl_easy_compare(value v1
, value v2
)
1569 size_t p1
= (size_t)Connection_val(v1
);
1570 size_t p2
= (size_t)Connection_val(v2
);
1571 return (p1
== p2
? 0 : (p1
> p2
? 1 : -1)); /* compare addresses */
1574 intnat
op_curl_easy_hash(value v
)
1576 return (size_t)Connection_val(v
); /* address */
1579 static struct custom_operations curl_easy_ops
= {
1581 op_curl_easy_finalize
,
1582 op_curl_easy_compare
,
1584 custom_serialize_default
,
1585 custom_deserialize_default
,
1586 #if defined(custom_compare_ext_default)
1587 custom_compare_ext_default
,
1591 value
caml_curl_alloc(Connection
* conn
)
1593 value v
= caml_alloc_custom(&curl_easy_ops
, sizeof(Connection
*), 0, 1);
1594 Connection_val(v
) = conn
;
1599 #define WRAP_DATA_CALLBACK(f) \
1600 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1603 leave_blocking_section();\
1604 result = f##_nolock(ptr,size,nmemb,data);\
1605 enter_blocking_section();\
1609 static size_t writeFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1612 CAMLlocal2(result
, str
);
1613 Connection
*conn
= (Connection
*)data
;
1616 checkConnection(conn
);
1618 str
= alloc_string(size
*nmemb
);
1620 for (i
= 0; i
< size
*nmemb
; i
++)
1621 Byte(str
, i
) = ptr
[i
];
1623 result
= callback_exn(Field(conn
->ocamlValues
, OcamlWriteCallback
), str
);
1625 CAMLreturnT(size_t, Is_exception_result(result
) ? 0 : Int_val(result
));
1628 WRAP_DATA_CALLBACK(writeFunction
)
1630 static size_t readFunction_nolock(void *ptr
, size_t size
, size_t nmemb
, void *data
)
1634 Connection
*conn
= (Connection
*)data
;
1637 checkConnection(conn
);
1639 result
= callback_exn(Field(conn
->ocamlValues
, OcamlReadCallback
),
1640 Val_int(size
*nmemb
));
1642 if (Is_exception_result(result
))
1644 CAMLreturnT(size_t,CURL_READFUNC_ABORT
);
1647 length
= string_length(result
);
1649 if (length
<= size
*nmemb
)
1651 memcpy(ptr
, String_val(result
), length
);
1653 CAMLreturnT(size_t,length
);
1657 CAMLreturnT(size_t,CURL_READFUNC_ABORT
);
1661 WRAP_DATA_CALLBACK(readFunction
)
1663 static size_t headerFunction_nolock(char *ptr
, size_t size
, size_t nmemb
, void *data
)
1666 CAMLlocal2(result
,str
);
1667 Connection
*conn
= (Connection
*)data
;
1670 checkConnection(conn
);
1672 str
= alloc_string(size
*nmemb
);
1674 for (i
= 0; i
< size
*nmemb
; i
++)
1675 Byte(str
, i
) = ptr
[i
];
1677 result
= callback_exn(Field(conn
->ocamlValues
, OcamlHeaderCallback
), str
);
1679 CAMLreturnT(size_t, Is_exception_result(result
) ? 0 : Int_val(result
));
1682 WRAP_DATA_CALLBACK(headerFunction
)
1684 static int progressFunction_nolock(void *data
,
1692 CAMLlocalN(callbackData
, 4);
1693 Connection
*conn
= (Connection
*)data
;
1695 checkConnection(conn
);
1697 callbackData
[0] = copy_double(dlTotal
);
1698 callbackData
[1] = copy_double(dlNow
);
1699 callbackData
[2] = copy_double(ulTotal
);
1700 callbackData
[3] = copy_double(ulNow
);
1702 result
= callbackN_exn(Field(conn
->ocamlValues
, OcamlProgressCallback
),
1705 CAMLreturnT(int, Is_exception_result(result
) ? 1 : Bool_val(result
));
1708 static int progressFunction(void *data
,
1715 leave_blocking_section();
1716 r
= progressFunction_nolock(data
,dlTotal
,dlNow
,ulTotal
,ulNow
);
1717 enter_blocking_section();
1721 static int debugFunction_nolock(CURL
*debugConnection
,
1722 curl_infotype infoType
,
1724 size_t bufferLength
,
1728 CAMLlocal3(camlDebugConnection
, camlInfoType
, camlMessage
);
1730 Connection
*conn
= (Connection
*)data
;
1731 (void)debugConnection
; /* not used */
1733 checkConnection(conn
);
1735 camlDebugConnection
= (value
)conn
;
1736 camlInfoType
= Val_long(infoType
);
1737 camlMessage
= alloc_string(bufferLength
);
1739 for (i
= 0; i
< bufferLength
; i
++)
1740 Byte(camlMessage
, i
) = buffer
[i
];
1742 callback3_exn(Field(conn
->ocamlValues
, OcamlDebugCallback
),
1743 camlDebugConnection
,
1747 CAMLreturnT(int, 0);
1750 static int debugFunction(CURL
*debugConnection
,
1751 curl_infotype infoType
,
1753 size_t bufferLength
,
1757 leave_blocking_section();
1758 r
= debugFunction_nolock(debugConnection
, infoType
, buffer
, bufferLength
, data
);
1759 enter_blocking_section();
1763 static curlioerr
ioctlFunction_nolock(CURL
*ioctl
,
1768 CAMLlocal3(camlResult
, camlConnection
, camlCmd
);
1769 Connection
*conn
= (Connection
*)data
;
1770 curlioerr result
= CURLIOE_OK
;
1771 (void)ioctl
; /* not used */
1773 checkConnection(conn
);
1775 if (cmd
== CURLIOCMD_NOP
)
1776 camlCmd
= Val_long(0);
1777 else if (cmd
== CURLIOCMD_RESTARTREAD
)
1778 camlCmd
= Val_long(1);
1780 failwith("Invalid IOCTL Cmd!");
1782 camlConnection
= caml_curl_alloc(conn
);
1784 camlResult
= callback2_exn(Field(conn
->ocamlValues
, OcamlIOCTLCallback
),
1788 if (Is_exception_result(camlResult
))
1790 result
= CURLIOE_FAILRESTART
;
1793 switch (Long_val(camlResult
))
1795 case 0: /* CURLIOE_OK */
1796 result
= CURLIOE_OK
;
1799 case 1: /* CURLIOE_UNKNOWNCMD */
1800 result
= CURLIOE_UNKNOWNCMD
;
1803 case 2: /* CURLIOE_FAILRESTART */
1804 result
= CURLIOE_FAILRESTART
;
1807 default: /* Incorrect return value, but let's handle it */
1808 result
= CURLIOE_FAILRESTART
;
1812 CAMLreturnT(curlioerr
, result
);
1815 static curlioerr
ioctlFunction(CURL
*ioctl
,
1820 leave_blocking_section();
1821 r
= ioctlFunction_nolock(ioctl
, cmd
, data
);
1822 enter_blocking_section();
1826 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1827 static int seekFunction_nolock(void *data
,
1832 CAMLlocal3(camlResult
, camlOffset
, camlOrigin
);
1833 Connection
*conn
= (Connection
*)data
;
1835 camlOffset
= copy_int64(offset
);
1837 if (origin
== SEEK_SET
)
1838 camlOrigin
= Val_long(0);
1839 else if (origin
== SEEK_CUR
)
1840 camlOrigin
= Val_long(1);
1841 else if (origin
== SEEK_END
)
1842 camlOrigin
= Val_long(2);
1844 failwith("Invalid seek code");
1846 camlResult
= callback2_exn(Field(conn
->ocamlValues
,
1847 OcamlSeekFunctionCallback
),
1852 if (Is_exception_result(camlResult
))
1853 result
= CURL_SEEKFUNC_FAIL
;
1855 switch (Int_val(camlResult
))
1857 case 0: result
= CURL_SEEKFUNC_OK
; break;
1858 case 1: result
= CURL_SEEKFUNC_FAIL
; break;
1859 case 2: result
= CURL_SEEKFUNC_CANTSEEK
; break;
1860 default: failwith("Invalid seek result");
1863 CAMLreturnT(int, result
);
1866 static int seekFunction(void *data
,
1871 leave_blocking_section();
1872 r
= seekFunction_nolock(data
,offset
,origin
);
1873 enter_blocking_section();
1879 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
1880 static int openSocketFunction_nolock(void *data
,
1881 curlsocktype purpose
,
1882 struct curl_sockaddr
*addr
)
1886 Connection
*conn
= (Connection
*)data
;
1888 (void)purpose
; /* not used */
1890 sock
= socket(addr
->family
, addr
->socktype
, addr
->protocol
);
1895 result
= callback_exn(Field(conn
->ocamlValues
, OcamlOpenSocketFunctionCallback
), Val_int(sock
));
1896 if (Is_exception_result(result
))
1903 CAMLreturnT(int, (sock
== -1) ? CURL_SOCKET_BAD
: sock
);
1906 static int openSocketFunction(void *data
,
1907 curlsocktype purpose
,
1908 struct curl_sockaddr
*address
)
1911 leave_blocking_section();
1912 r
= openSocketFunction_nolock(data
,purpose
,address
);
1913 enter_blocking_section();
1920 ** curl_global_init helper function
1923 CAMLprim value
helper_curl_global_init(value initOption
)
1925 CAMLparam1(initOption
);
1927 switch (Long_val(initOption
))
1929 case 0: /* CURLINIT_GLOBALALL */
1930 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL
)));
1933 case 1: /* CURLINIT_GLOBALSSL */
1934 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL
)));
1937 case 2: /* CURLINIT_GLOBALWIN32 */
1938 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32
)));
1941 case 3: /* CURLINIT_GLOBALNOTHING */
1942 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING
)));
1946 failwith("Invalid Initialization Option");
1950 /* Keep compiler happy, we should never get here due to failwith() */
1951 CAMLreturn(Val_unit
);
1955 ** curl_global_cleanup helper function
1958 CAMLprim value
helper_curl_global_cleanup(void)
1962 curl_global_cleanup();
1964 CAMLreturn(Val_unit
);
1968 ** curl_easy_init helper function
1970 CAMLprim value
helper_curl_easy_init(void)
1975 result
= caml_curl_alloc(newConnection());
1980 CAMLprim value
helper_curl_easy_reset(value conn
)
1983 Connection
*connection
= Connection_val(conn
);
1985 checkConnection(connection
);
1986 curl_easy_reset(connection
->connection
);
1987 resetOcamlValues(connection
);
1989 CAMLreturn(Val_unit
);
1993 ** curl_easy_setopt helper utility functions
1996 static void handleWriteFunction(Connection
*conn
, value option
)
1999 CURLcode result
= CURLE_OK
;
2001 if (Tag_val(option
) == Closure_tag
)
2002 Store_field(conn
->ocamlValues
, OcamlWriteCallback
, option
);
2004 failwith("Not a proper closure");
2006 result
= curl_easy_setopt(conn
->connection
,
2007 CURLOPT_WRITEFUNCTION
,
2010 if (result
!= CURLE_OK
)
2011 raiseError(conn
, result
);
2013 result
= curl_easy_setopt(conn
->connection
,
2017 if (result
!= CURLE_OK
)
2018 raiseError(conn
, result
);
2023 static void handleReadFunction(Connection
*conn
, value option
)
2026 CURLcode result
= CURLE_OK
;
2028 if (Tag_val(option
) == Closure_tag
)
2029 Store_field(conn
->ocamlValues
, OcamlReadCallback
, option
);
2031 failwith("Not a proper closure");
2033 result
= curl_easy_setopt(conn
->connection
,
2034 CURLOPT_READFUNCTION
,
2037 if (result
!= CURLE_OK
)
2038 raiseError(conn
, result
);
2040 result
= curl_easy_setopt(conn
->connection
,
2044 if (result
!= CURLE_OK
)
2045 raiseError(conn
, result
);
2050 static void handleURL(Connection
*conn
, value option
)
2053 CURLcode result
= CURLE_OK
;
2055 Store_field(conn
->ocamlValues
, OcamlURL
, option
);
2057 if (conn
->url
!= NULL
)
2060 conn
->url
= strdup(String_val(option
));
2062 result
= curl_easy_setopt(conn
->connection
,
2066 if (result
!= CURLE_OK
)
2067 raiseError(conn
, result
);
2072 static void handleInFileSize(Connection
*conn
, value option
)
2075 CURLcode result
= CURLE_OK
;
2077 result
= curl_easy_setopt(conn
->connection
,
2081 if (result
!= CURLE_OK
)
2082 raiseError(conn
, result
);
2087 static void handleProxy(Connection
*conn
, value option
)
2090 CURLcode result
= CURLE_OK
;
2092 Store_field(conn
->ocamlValues
, OcamlProxy
, option
);
2094 if (conn
->proxy
!= NULL
)
2097 conn
->proxy
= strdup(String_val(option
));
2099 result
= curl_easy_setopt(conn
->connection
,
2103 if (result
!= CURLE_OK
)
2104 raiseError(conn
, result
);
2109 static void handleProxyPort(Connection
*conn
, value option
)
2112 CURLcode result
= CURLE_OK
;
2114 result
= curl_easy_setopt(conn
->connection
,
2118 if (result
!= CURLE_OK
)
2119 raiseError(conn
, result
);
2124 static void handleHTTPProxyTunnel(Connection
*conn
, value option
)
2127 CURLcode result
= CURLE_OK
;
2129 result
= curl_easy_setopt(conn
->connection
,
2130 CURLOPT_HTTPPROXYTUNNEL
,
2133 if (result
!= CURLE_OK
)
2134 raiseError(conn
, result
);
2139 static void handleVerbose(Connection
*conn
, value option
)
2142 CURLcode result
= CURLE_OK
;
2144 result
= curl_easy_setopt(conn
->connection
,
2148 if (result
!= CURLE_OK
)
2149 raiseError(conn
, result
);
2154 static void handleHeader(Connection
*conn
, value option
)
2157 CURLcode result
= CURLE_OK
;
2159 result
= curl_easy_setopt(conn
->connection
,
2163 if (result
!= CURLE_OK
)
2164 raiseError(conn
, result
);
2169 static void handleNoProgress(Connection
*conn
, value option
)
2172 CURLcode result
= CURLE_OK
;
2174 result
= curl_easy_setopt(conn
->connection
,
2178 if (result
!= CURLE_OK
)
2179 raiseError(conn
, result
);
2184 static void handleNoSignal(Connection
*conn
, value option
)
2186 #if HAVE_DECL_CURLOPT_NOSIGNAL
2188 CURLcode result
= CURLE_OK
;
2190 result
= curl_easy_setopt(conn
->connection
,
2194 if (result
!= CURLE_OK
)
2195 raiseError(conn
, result
);
2199 #pragma message("libcurl does not implement CURLOPT_NOSIGNAL")
2200 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2204 static void handleNoBody(Connection
*conn
, value option
)
2207 CURLcode result
= CURLE_OK
;
2209 result
= curl_easy_setopt(conn
->connection
,
2213 if (result
!= CURLE_OK
)
2214 raiseError(conn
, result
);
2219 static void handleFailOnError(Connection
*conn
, value option
)
2222 CURLcode result
= CURLE_OK
;
2224 result
= curl_easy_setopt(conn
->connection
,
2225 CURLOPT_FAILONERROR
,
2228 if (result
!= CURLE_OK
)
2229 raiseError(conn
, result
);
2234 static void handleUpload(Connection
*conn
, value option
)
2237 CURLcode result
= CURLE_OK
;
2239 result
= curl_easy_setopt(conn
->connection
,
2243 if (result
!= CURLE_OK
)
2244 raiseError(conn
, result
);
2249 static void handlePost(Connection
*conn
, value option
)
2252 CURLcode result
= CURLE_OK
;
2254 result
= curl_easy_setopt(conn
->connection
,
2258 if (result
!= CURLE_OK
)
2259 raiseError(conn
, result
);
2264 static void handleFTPListOnly(Connection
*conn
, value option
)
2267 CURLcode result
= CURLE_OK
;
2269 result
= curl_easy_setopt(conn
->connection
,
2270 CURLOPT_FTPLISTONLY
,
2273 if (result
!= CURLE_OK
)
2274 raiseError(conn
, result
);
2279 static void handleFTPAppend(Connection
*conn
, value option
)
2282 CURLcode result
= CURLE_OK
;
2284 result
= curl_easy_setopt(conn
->connection
,
2288 if (result
!= CURLE_OK
)
2289 raiseError(conn
, result
);
2294 static void handleNETRC(Connection
*conn
, value option
)
2297 CURLcode result
= CURLE_OK
;
2300 switch (Long_val(option
))
2302 case 0: /* CURL_NETRC_OPTIONAL */
2303 netrc
= CURL_NETRC_OPTIONAL
;
2306 case 1:/* CURL_NETRC_IGNORED */
2307 netrc
= CURL_NETRC_IGNORED
;
2310 case 2: /* CURL_NETRC_REQUIRED */
2311 netrc
= CURL_NETRC_REQUIRED
;
2315 failwith("Invalid NETRC Option");
2319 result
= curl_easy_setopt(conn
->connection
,
2323 if (result
!= CURLE_OK
)
2324 raiseError(conn
, result
);
2329 static void handleEncoding(Connection
*conn
, value option
)
2331 #if HAVE_DECL_CURLOPT_ENCODING
2333 CURLcode result
= CURLE_OK
;
2335 switch (Long_val(option
))
2337 case 0: /* CURL_ENCODING_NONE */
2338 result
= curl_easy_setopt(conn
->connection
,
2343 case 1: /* CURL_ENCODING_DEFLATE */
2344 result
= curl_easy_setopt(conn
->connection
,
2349 case 2: /* CURL_ENCODING_GZIP */
2350 result
= curl_easy_setopt(conn
->connection
,
2355 case 3: /* CURL_ENCODING_ANY */
2356 result
= curl_easy_setopt(conn
->connection
,
2362 failwith("Invalid Encoding Option");
2366 if (result
!= CURLE_OK
)
2367 raiseError(conn
, result
);
2371 #pragma message("libcurl does not implement CURLOPT_ENCODING")
2372 failwith("libcurl does not implement CURLOPT_ENCODING");
2376 static void handleFollowLocation(Connection
*conn
, value option
)
2379 CURLcode result
= CURLE_OK
;
2381 result
= curl_easy_setopt(conn
->connection
,
2382 CURLOPT_FOLLOWLOCATION
,
2385 if (result
!= CURLE_OK
)
2386 raiseError(conn
, result
);
2391 static void handleTransferText(Connection
*conn
, value option
)
2394 CURLcode result
= CURLE_OK
;
2396 result
= curl_easy_setopt(conn
->connection
,
2397 CURLOPT_TRANSFERTEXT
,
2400 if (result
!= CURLE_OK
)
2401 raiseError(conn
, result
);
2406 static void handlePut(Connection
*conn
, value option
)
2409 CURLcode result
= CURLE_OK
;
2411 result
= curl_easy_setopt(conn
->connection
,
2415 if (result
!= CURLE_OK
)
2416 raiseError(conn
, result
);
2421 static void handleUserPwd(Connection
*conn
, value option
)
2424 CURLcode result
= CURLE_OK
;
2426 Store_field(conn
->ocamlValues
, OcamlUserPWD
, option
);
2428 if (conn
->userPwd
!= NULL
)
2429 free(conn
->userPwd
);
2431 conn
->userPwd
= strdup(String_val(option
));
2433 result
= curl_easy_setopt(conn
->connection
,
2437 if (result
!= CURLE_OK
)
2438 raiseError(conn
, result
);
2443 static void handleProxyUserPwd(Connection
*conn
, value option
)
2446 CURLcode result
= CURLE_OK
;
2448 Store_field(conn
->ocamlValues
, OcamlProxyUserPWD
, option
);
2450 if (conn
->proxyUserPwd
!= NULL
)
2451 free(conn
->proxyUserPwd
);
2453 conn
->proxyUserPwd
= strdup(String_val(option
));
2455 result
= curl_easy_setopt(conn
->connection
,
2456 CURLOPT_PROXYUSERPWD
,
2457 conn
->proxyUserPwd
);
2459 if (result
!= CURLE_OK
)
2460 raiseError(conn
, result
);
2465 static void handleRange(Connection
*conn
, value option
)
2468 CURLcode result
= CURLE_OK
;
2470 Store_field(conn
->ocamlValues
, OcamlRange
, option
);
2472 if (conn
->range
!= NULL
)
2475 conn
->range
= strdup(String_val(option
));
2477 result
= curl_easy_setopt(conn
->connection
,
2481 if (result
!= CURLE_OK
)
2482 raiseError(conn
, result
);
2487 static void handleErrorBuffer(Connection
*conn
, value option
)
2490 CURLcode result
= CURLE_OK
;
2492 Store_field(conn
->ocamlValues
, OcamlErrorBuffer
, option
);
2494 if (conn
->errorBuffer
!= NULL
)
2495 free(conn
->errorBuffer
);
2497 conn
->errorBuffer
= malloc(sizeof(char) * CURL_ERROR_SIZE
);
2499 result
= curl_easy_setopt(conn
->connection
,
2500 CURLOPT_ERRORBUFFER
,
2503 if (result
!= CURLE_OK
)
2504 raiseError(conn
, result
);
2509 static void handleTimeout(Connection
*conn
, value option
)
2512 CURLcode result
= CURLE_OK
;
2514 result
= curl_easy_setopt(conn
->connection
,
2518 if (result
!= CURLE_OK
)
2519 raiseError(conn
, result
);
2524 static void handlePostFields(Connection
*conn
, value option
)
2527 CURLcode result
= CURLE_OK
;
2529 Store_field(conn
->ocamlValues
, OcamlPostFields
, option
);
2531 if (conn
->postFields
!= NULL
)
2532 free(conn
->postFields
);
2534 conn
->postFields
= malloc(string_length(option
)+1);
2535 memcpy(conn
->postFields
, String_val(option
), string_length(option
)+1);
2537 result
= curl_easy_setopt(conn
->connection
,
2541 if (result
!= CURLE_OK
)
2542 raiseError(conn
, result
);
2547 static void handlePostFieldSize(Connection
*conn
, value option
)
2550 CURLcode result
= CURLE_OK
;
2552 result
= curl_easy_setopt(conn
->connection
,
2553 CURLOPT_POSTFIELDSIZE
,
2556 if (result
!= CURLE_OK
)
2557 raiseError(conn
, result
);
2562 static void handleReferer(Connection
*conn
, value option
)
2565 CURLcode result
= CURLE_OK
;
2567 Store_field(conn
->ocamlValues
, OcamlReferer
, option
);
2569 if (conn
->referer
!= NULL
)
2570 free(conn
->referer
);
2572 conn
->referer
= strdup(String_val(option
));
2574 result
= curl_easy_setopt(conn
->connection
,
2578 if (result
!= CURLE_OK
)
2579 raiseError(conn
, result
);
2584 static void handleUserAgent(Connection
*conn
, value option
)
2587 CURLcode result
= CURLE_OK
;
2589 Store_field(conn
->ocamlValues
, OcamlUserAgent
, option
);
2591 if (conn
->userAgent
!= NULL
)
2592 free(conn
->userAgent
);
2594 conn
->userAgent
= strdup(String_val(option
));
2596 result
= curl_easy_setopt(conn
->connection
,
2600 if (result
!= CURLE_OK
)
2601 raiseError(conn
, result
);
2606 static void handleFTPPort(Connection
*conn
, value option
)
2609 CURLcode result
= CURLE_OK
;
2611 Store_field(conn
->ocamlValues
, OcamlFTPPort
, option
);
2613 if (conn
->ftpPort
!= NULL
)
2614 free(conn
->ftpPort
);
2616 conn
->ftpPort
= strdup(String_val(option
));
2618 result
= curl_easy_setopt(conn
->connection
,
2622 if (result
!= CURLE_OK
)
2623 raiseError(conn
, result
);
2628 static void handleLowSpeedLimit(Connection
*conn
, value option
)
2631 CURLcode result
= CURLE_OK
;
2633 result
= curl_easy_setopt(conn
->connection
,
2634 CURLOPT_LOW_SPEED_LIMIT
,
2637 if (result
!= CURLE_OK
)
2638 raiseError(conn
, result
);
2643 static void handleLowSpeedTime(Connection
*conn
, value option
)
2646 CURLcode result
= CURLE_OK
;
2648 result
= curl_easy_setopt(conn
->connection
,
2649 CURLOPT_LOW_SPEED_TIME
,
2652 if (result
!= CURLE_OK
)
2653 raiseError(conn
, result
);
2658 static void handleResumeFrom(Connection
*conn
, value option
)
2661 CURLcode result
= CURLE_OK
;
2663 result
= curl_easy_setopt(conn
->connection
,
2664 CURLOPT_RESUME_FROM
,
2667 if (result
!= CURLE_OK
)
2668 raiseError(conn
, result
);
2673 static void handleCookie(Connection
*conn
, value option
)
2676 CURLcode result
= CURLE_OK
;
2678 Store_field(conn
->ocamlValues
, OcamlCookie
, option
);
2680 if (conn
->cookie
!= NULL
)
2683 conn
->cookie
= strdup(String_val(option
));
2685 result
= curl_easy_setopt(conn
->connection
,
2689 if (result
!= CURLE_OK
)
2690 raiseError(conn
, result
);
2695 static void handleHTTPHeader(Connection
*conn
, value option
)
2698 CAMLlocal1(listIter
);
2699 CURLcode result
= CURLE_OK
;
2701 Store_field(conn
->ocamlValues
, OcamlHTTPHeader
, option
);
2703 free_curl_slist(conn
->httpHeader
);
2704 conn
->httpHeader
= NULL
;
2708 while (!Is_long(listIter
))
2710 conn
->httpHeader
= curl_slist_append(conn
->httpHeader
, String_val(Field(listIter
, 0)));
2712 listIter
= Field(listIter
, 1);
2715 result
= curl_easy_setopt(conn
->connection
,
2719 if (result
!= CURLE_OK
)
2720 raiseError(conn
, result
);
2725 static void handleHTTPPost(Connection
*conn
, value option
)
2728 CAMLlocal3(listIter
, formItem
, contentType
);
2729 CURLcode result
= CURLE_OK
;
2730 char *str1
, *str2
, *str3
, *str4
;
2734 Store_field(conn
->ocamlValues
, OcamlHTTPPost
, option
);
2736 if (conn
->httpPostFirst
!= NULL
)
2737 curl_formfree(conn
->httpPostFirst
);
2739 conn
->httpPostFirst
= NULL
;
2740 conn
->httpPostLast
= NULL
;
2742 free_curl_slist(conn
->httpPostStrings
);
2743 conn
->httpPostStrings
= NULL
;
2745 while (!Is_long(listIter
))
2747 formItem
= Field(listIter
, 0);
2749 switch (Tag_val(formItem
))
2751 case 0: /* CURLFORM_CONTENT */
2752 if (Wosize_val(formItem
) < 3)
2754 failwith("Incorrect CURLFORM_CONTENT parameters");
2757 if (Is_long(Field(formItem
, 2)) &&
2758 Long_val(Field(formItem
, 2)) == 0)
2760 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2762 String_val(Field(formItem
, 0)),
2763 string_length(Field(formItem
, 0)));
2764 str1
[string_length(Field(formItem
, 0))] = 0;
2765 conn
->httpPostStrings
=
2766 curl_slist_append(conn
->httpPostStrings
, str1
);
2768 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2770 String_val(Field(formItem
, 1)),
2771 string_length(Field(formItem
, 1)));
2772 str2
[string_length(Field(formItem
, 1))] = 0;
2773 conn
->httpPostStrings
=
2774 curl_slist_append(conn
->httpPostStrings
, str2
);
2776 curl_formadd(&conn
->httpPostFirst
,
2777 &conn
->httpPostLast
,
2780 CURLFORM_NAMELENGTH
,
2781 string_length(Field(formItem
, 0)),
2782 CURLFORM_PTRCONTENTS
,
2784 CURLFORM_CONTENTSLENGTH
,
2785 string_length(Field(formItem
, 1)),
2788 else if (Is_block(Field(formItem
, 2)))
2790 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2792 String_val(Field(formItem
, 0)),
2793 string_length(Field(formItem
, 0)));
2794 str1
[string_length(Field(formItem
, 0))] = 0;
2795 conn
->httpPostStrings
=
2796 curl_slist_append(conn
->httpPostStrings
, str1
);
2798 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2800 String_val(Field(formItem
, 1)),
2801 string_length(Field(formItem
, 1)));
2802 str2
[string_length(Field(formItem
, 1))] = 0;
2803 conn
->httpPostStrings
=
2804 curl_slist_append(conn
->httpPostStrings
, str2
);
2806 contentType
= Field(formItem
, 2);
2808 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2810 String_val(Field(contentType
, 0)),
2811 string_length(Field(contentType
, 0)));
2812 str3
[string_length(Field(contentType
, 0))] = 0;
2813 conn
->httpPostStrings
=
2814 curl_slist_append(conn
->httpPostStrings
, str3
);
2816 curl_formadd(&conn
->httpPostFirst
,
2817 &conn
->httpPostLast
,
2820 CURLFORM_NAMELENGTH
,
2821 string_length(Field(formItem
, 0)),
2822 CURLFORM_PTRCONTENTS
,
2824 CURLFORM_CONTENTSLENGTH
,
2825 string_length(Field(formItem
, 1)),
2826 CURLFORM_CONTENTTYPE
,
2832 failwith("Incorrect CURLFORM_CONTENT parameters");
2836 case 1: /* CURLFORM_FILECONTENT */
2837 if (Wosize_val(formItem
) < 3)
2839 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2842 if (Is_long(Field(formItem
, 2)) &&
2843 Long_val(Field(formItem
, 2)) == 0)
2845 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2847 String_val(Field(formItem
, 0)),
2848 string_length(Field(formItem
, 0)));
2849 str1
[string_length(Field(formItem
, 0))] = 0;
2850 conn
->httpPostStrings
=
2851 curl_slist_append(conn
->httpPostStrings
, str1
);
2853 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2855 String_val(Field(formItem
, 1)),
2856 string_length(Field(formItem
, 1)));
2857 str2
[string_length(Field(formItem
, 1))] = 0;
2858 conn
->httpPostStrings
=
2859 curl_slist_append(conn
->httpPostStrings
, str2
);
2861 curl_formadd(&conn
->httpPostFirst
,
2862 &conn
->httpPostLast
,
2865 CURLFORM_NAMELENGTH
,
2866 string_length(Field(formItem
, 0)),
2867 CURLFORM_FILECONTENT
,
2871 else if (Is_block(Field(formItem
, 2)))
2873 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2875 String_val(Field(formItem
, 0)),
2876 string_length(Field(formItem
, 0)));
2877 str1
[string_length(Field(formItem
, 0))] = 0;
2878 conn
->httpPostStrings
=
2879 curl_slist_append(conn
->httpPostStrings
, str1
);
2881 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2883 String_val(Field(formItem
, 1)),
2884 string_length(Field(formItem
, 1)));
2885 str2
[string_length(Field(formItem
, 1))] = 0;
2886 conn
->httpPostStrings
=
2887 curl_slist_append(conn
->httpPostStrings
, str2
);
2889 contentType
= Field(formItem
, 2);
2891 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2893 String_val(Field(contentType
, 0)),
2894 string_length(Field(contentType
, 0)));
2895 str3
[string_length(Field(contentType
, 0))] = 0;
2896 conn
->httpPostStrings
=
2897 curl_slist_append(conn
->httpPostStrings
, str3
);
2899 curl_formadd(&conn
->httpPostFirst
,
2900 &conn
->httpPostLast
,
2903 CURLFORM_NAMELENGTH
,
2904 string_length(Field(formItem
, 0)),
2905 CURLFORM_FILECONTENT
,
2907 CURLFORM_CONTENTTYPE
,
2913 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2917 case 2: /* CURLFORM_FILE */
2918 if (Wosize_val(formItem
) < 3)
2920 failwith("Incorrect CURLFORM_FILE parameters");
2923 if (Is_long(Field(formItem
, 2)) &&
2924 Long_val(Field(formItem
, 2)) == 0)
2926 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2928 String_val(Field(formItem
, 0)),
2929 string_length(Field(formItem
, 0)));
2930 str1
[string_length(Field(formItem
, 0))] = 0;
2931 conn
->httpPostStrings
=
2932 curl_slist_append(conn
->httpPostStrings
, str1
);
2934 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2936 String_val(Field(formItem
, 1)),
2937 string_length(Field(formItem
, 1)));
2938 str2
[string_length(Field(formItem
, 1))] = 0;
2939 conn
->httpPostStrings
=
2940 curl_slist_append(conn
->httpPostStrings
, str2
);
2942 curl_formadd(&conn
->httpPostFirst
,
2943 &conn
->httpPostLast
,
2946 CURLFORM_NAMELENGTH
,
2947 string_length(Field(formItem
, 0)),
2952 else if (Is_block(Field(formItem
, 2)))
2954 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
2956 String_val(Field(formItem
, 0)),
2957 string_length(Field(formItem
, 0)));
2958 str1
[string_length(Field(formItem
, 0))] = 0;
2959 conn
->httpPostStrings
=
2960 curl_slist_append(conn
->httpPostStrings
, str1
);
2962 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
2964 String_val(Field(formItem
, 1)),
2965 string_length(Field(formItem
, 1)));
2966 str2
[string_length(Field(formItem
, 1))] = 0;
2967 conn
->httpPostStrings
=
2968 curl_slist_append(conn
->httpPostStrings
, str2
);
2970 contentType
= Field(formItem
, 2);
2972 str3
= (char *)malloc(string_length(Field(contentType
, 0))+1);
2974 String_val(Field(contentType
, 0)),
2975 string_length(Field(contentType
, 0)));
2976 str3
[string_length(Field(contentType
, 0))] = 0;
2977 conn
->httpPostStrings
=
2978 curl_slist_append(conn
->httpPostStrings
, str3
);
2980 curl_formadd(&conn
->httpPostFirst
,
2981 &conn
->httpPostLast
,
2984 CURLFORM_NAMELENGTH
,
2985 string_length(Field(formItem
, 0)),
2988 CURLFORM_CONTENTTYPE
,
2994 failwith("Incorrect CURLFORM_FILE parameters");
2998 case 3: /* CURLFORM_BUFFER */
2999 if (Wosize_val(formItem
) < 4)
3001 failwith("Incorrect CURLFORM_BUFFER parameters");
3004 if (Is_long(Field(formItem
, 3)) &&
3005 Long_val(Field(formItem
, 3)) == 0)
3007 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
3009 String_val(Field(formItem
, 0)),
3010 string_length(Field(formItem
, 0)));
3011 str1
[string_length(Field(formItem
, 0))] = 0;
3012 conn
->httpPostStrings
=
3013 curl_slist_append(conn
->httpPostStrings
, str1
);
3015 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
3017 String_val(Field(formItem
, 1)),
3018 string_length(Field(formItem
, 1)));
3019 str2
[string_length(Field(formItem
, 1))] = 0;
3020 conn
->httpPostStrings
=
3021 curl_slist_append(conn
->httpPostStrings
, str2
);
3023 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
3025 String_val(Field(formItem
, 2)),
3026 string_length(Field(formItem
, 2)));
3027 str3
[string_length(Field(formItem
, 2))] = 0;
3028 conn
->httpPostStrings
=
3029 curl_slist_append(conn
->httpPostStrings
, str3
);
3031 curl_formadd(&conn
->httpPostFirst
,
3032 &conn
->httpPostLast
,
3035 CURLFORM_NAMELENGTH
,
3036 string_length(Field(formItem
, 0)),
3041 CURLFORM_BUFFERLENGTH
,
3042 string_length(Field(formItem
, 2)),
3045 else if (Is_block(Field(formItem
, 3)))
3047 str1
= (char *)malloc(string_length(Field(formItem
, 0))+1);
3049 String_val(Field(formItem
, 0)),
3050 string_length(Field(formItem
, 0)));
3051 str1
[string_length(Field(formItem
, 0))] = 0;
3052 conn
->httpPostStrings
=
3053 curl_slist_append(conn
->httpPostStrings
, str1
);
3055 str2
= (char *)malloc(string_length(Field(formItem
, 1))+1);
3057 String_val(Field(formItem
, 1)),
3058 string_length(Field(formItem
, 1)));
3059 str2
[string_length(Field(formItem
, 1))] = 0;
3060 conn
->httpPostStrings
=
3061 curl_slist_append(conn
->httpPostStrings
, str2
);
3063 str3
= (char *)malloc(string_length(Field(formItem
, 2))+1);
3065 String_val(Field(formItem
, 2)),
3066 string_length(Field(formItem
, 2)));
3067 str3
[string_length(Field(formItem
, 2))] = 0;
3068 conn
->httpPostStrings
=
3069 curl_slist_append(conn
->httpPostStrings
, str3
);
3071 contentType
= Field(formItem
, 3);
3073 str4
= (char *)malloc(string_length(Field(contentType
, 0))+1);
3075 String_val(Field(contentType
, 0)),
3076 string_length(Field(contentType
, 0)));
3077 str4
[string_length(Field(contentType
, 0))] = 0;
3078 conn
->httpPostStrings
=
3079 curl_slist_append(conn
->httpPostStrings
, str4
);
3081 curl_formadd(&conn
->httpPostFirst
,
3082 &conn
->httpPostLast
,
3085 CURLFORM_NAMELENGTH
,
3086 string_length(Field(formItem
, 0)),
3091 CURLFORM_BUFFERLENGTH
,
3092 string_length(Field(formItem
, 2)),
3093 CURLFORM_CONTENTTYPE
,
3099 failwith("Incorrect CURLFORM_BUFFER parameters");
3104 listIter
= Field(listIter
, 1);
3107 result
= curl_easy_setopt(conn
->connection
,
3109 conn
->httpPostFirst
);
3111 if (result
!= CURLE_OK
)
3112 raiseError(conn
, result
);
3117 static void handleSSLCert(Connection
*conn
, value option
)
3120 CURLcode result
= CURLE_OK
;
3122 Store_field(conn
->ocamlValues
, OcamlSSLCert
, option
);
3124 if (conn
->sslCert
!= NULL
)
3125 free(conn
->sslCert
);
3127 conn
->sslCert
= strdup(String_val(option
));
3129 result
= curl_easy_setopt(conn
->connection
,
3133 if (result
!= CURLE_OK
)
3134 raiseError(conn
, result
);
3139 static void handleSSLCertType(Connection
*conn
, value option
)
3142 CURLcode result
= CURLE_OK
;
3144 Store_field(conn
->ocamlValues
, OcamlSSLCertType
, option
);
3146 if (conn
->sslCertType
!= NULL
)
3147 free(conn
->sslCertType
);
3149 conn
->sslCertType
= strdup(String_val(option
));
3151 result
= curl_easy_setopt(conn
->connection
,
3152 CURLOPT_SSLCERTTYPE
,
3155 if (result
!= CURLE_OK
)
3156 raiseError(conn
, result
);
3161 static void handleSSLCertPasswd(Connection
*conn
, value option
)
3164 CURLcode result
= CURLE_OK
;
3166 Store_field(conn
->ocamlValues
, OcamlSSLCertPasswd
, option
);
3168 if (conn
->sslCertPasswd
!= NULL
)
3169 free(conn
->sslCertPasswd
);
3171 conn
->sslCertPasswd
= strdup(String_val(option
));
3173 result
= curl_easy_setopt(conn
->connection
,
3174 CURLOPT_SSLCERTPASSWD
,
3175 conn
->sslCertPasswd
);
3177 if (result
!= CURLE_OK
)
3178 raiseError(conn
, result
);
3183 static void handleSSLKey(Connection
*conn
, value option
)
3186 CURLcode result
= CURLE_OK
;
3188 Store_field(conn
->ocamlValues
, OcamlSSLKey
, option
);
3190 if (conn
->sslKey
!= NULL
)
3193 conn
->sslKey
= strdup(String_val(option
));
3195 result
= curl_easy_setopt(conn
->connection
,
3199 if (result
!= CURLE_OK
)
3200 raiseError(conn
, result
);
3205 static void handleSSLKeyType(Connection
*conn
, value option
)
3208 CURLcode result
= CURLE_OK
;
3210 Store_field(conn
->ocamlValues
, OcamlSSLKeyType
, option
);
3212 if (conn
->sslKeyType
!= NULL
)
3213 free(conn
->sslKeyType
);
3215 conn
->sslKeyType
= strdup(String_val(option
));
3217 result
= curl_easy_setopt(conn
->connection
,
3221 if (result
!= CURLE_OK
)
3222 raiseError(conn
, result
);
3227 static void handleSSLKeyPasswd(Connection
*conn
, value option
)
3230 CURLcode result
= CURLE_OK
;
3232 Store_field(conn
->ocamlValues
, OcamlSSLKeyPasswd
, option
);
3234 if (conn
->sslKeyPasswd
!= NULL
)
3235 free(conn
->sslKeyPasswd
);
3237 conn
->sslKeyPasswd
= strdup(String_val(option
));
3239 result
= curl_easy_setopt(conn
->connection
,
3240 CURLOPT_SSLKEYPASSWD
,
3241 conn
->sslKeyPasswd
);
3243 if (result
!= CURLE_OK
)
3244 raiseError(conn
, result
);
3249 static void handleSSLEngine(Connection
*conn
, value option
)
3252 CURLcode result
= CURLE_OK
;
3254 Store_field(conn
->ocamlValues
, OcamlSSLEngine
, option
);
3256 if (conn
->sslEngine
!= NULL
)
3257 free(conn
->sslEngine
);
3259 conn
->sslEngine
= strdup(String_val(option
));
3261 result
= curl_easy_setopt(conn
->connection
,
3265 if (result
!= CURLE_OK
)
3266 raiseError(conn
, result
);
3271 static void handleSSLEngineDefault(Connection
*conn
, value option
)
3274 CURLcode result
= CURLE_OK
;
3276 result
= curl_easy_setopt(conn
->connection
,
3277 CURLOPT_SSLENGINE_DEFAULT
,
3280 if (result
!= CURLE_OK
)
3281 raiseError(conn
, result
);
3286 static void handleCRLF(Connection
*conn
, value option
)
3289 CURLcode result
= CURLE_OK
;
3291 result
= curl_easy_setopt(conn
->connection
,
3295 if (result
!= CURLE_OK
)
3296 raiseError(conn
, result
);
3301 static void handleQuote(Connection
*conn
, value option
)
3304 CAMLlocal1(listIter
);
3305 CURLcode result
= CURLE_OK
;
3307 Store_field(conn
->ocamlValues
, OcamlQuote
, option
);
3309 free_curl_slist(conn
->quote
);
3314 while (!Is_long(listIter
))
3316 conn
->quote
= curl_slist_append(conn
->quote
, String_val(Field(listIter
, 0)));
3318 listIter
= Field(listIter
, 1);
3321 result
= curl_easy_setopt(conn
->connection
,
3325 if (result
!= CURLE_OK
)
3326 raiseError(conn
, result
);
3331 static void handlePostQuote(Connection
*conn
, value option
)
3334 CAMLlocal1(listIter
);
3335 CURLcode result
= CURLE_OK
;
3337 Store_field(conn
->ocamlValues
, OcamlPostQuote
, option
);
3339 free_curl_slist(conn
->postQuote
);
3340 conn
->postQuote
= NULL
;
3344 while (!Is_long(listIter
))
3346 conn
->postQuote
= curl_slist_append(conn
->postQuote
, String_val(Field(listIter
, 0)));
3348 listIter
= Field(listIter
, 1);
3351 result
= curl_easy_setopt(conn
->connection
,
3355 if (result
!= CURLE_OK
)
3356 raiseError(conn
, result
);
3361 static void handleHeaderFunction(Connection
*conn
, value option
)
3364 CURLcode result
= CURLE_OK
;
3366 if (Tag_val(option
) == Closure_tag
)
3367 Store_field(conn
->ocamlValues
, OcamlHeaderCallback
, option
);
3369 failwith("Not a proper closure");
3371 result
= curl_easy_setopt(conn
->connection
,
3372 CURLOPT_HEADERFUNCTION
,
3375 if (result
!= CURLE_OK
)
3376 raiseError(conn
, result
);
3378 result
= curl_easy_setopt(conn
->connection
,
3379 CURLOPT_WRITEHEADER
,
3382 if (result
!= CURLE_OK
)
3383 raiseError(conn
, result
);
3388 static void handleCookieFile(Connection
*conn
, value option
)
3391 CURLcode result
= CURLE_OK
;
3393 Store_field(conn
->ocamlValues
, OcamlCookieFile
, option
);
3395 if (conn
->cookieFile
!= NULL
)
3396 free(conn
->cookieFile
);
3398 conn
->cookieFile
= strdup(String_val(option
));
3400 result
= curl_easy_setopt(conn
->connection
,
3404 if (result
!= CURLE_OK
)
3405 raiseError(conn
, result
);
3410 static void handleSSLVersion(Connection
*conn
, value option
)
3413 CURLcode result
= CURLE_OK
;
3415 result
= curl_easy_setopt(conn
->connection
,
3419 if (result
!= CURLE_OK
)
3420 raiseError(conn
, result
);
3425 static void handleTimeCondition(Connection
*conn
, value option
)
3428 CURLcode result
= CURLE_OK
;
3429 int timecond
= CURL_TIMECOND_NONE
;
3431 switch (Long_val(option
))
3433 case 0: timecond
= CURL_TIMECOND_NONE
; break;
3434 case 1: timecond
= CURL_TIMECOND_IFMODSINCE
; break;
3435 case 2: timecond
= CURL_TIMECOND_IFUNMODSINCE
; break;
3436 case 3: timecond
= CURL_TIMECOND_LASTMOD
; break;
3438 failwith("Invalid TIMECOND Option");
3442 result
= curl_easy_setopt(conn
->connection
, CURLOPT_TIMECONDITION
, timecond
);
3444 if (result
!= CURLE_OK
)
3445 raiseError(conn
, result
);
3450 static void handleTimeValue(Connection
*conn
, value option
)
3453 CURLcode result
= CURLE_OK
;
3455 result
= curl_easy_setopt(conn
->connection
,
3459 if (result
!= CURLE_OK
)
3460 raiseError(conn
, result
);
3465 static void handleCustomRequest(Connection
*conn
, value option
)
3468 CURLcode result
= CURLE_OK
;
3470 Store_field(conn
->ocamlValues
, OcamlCustomRequest
, option
);
3472 if (conn
->customRequest
!= NULL
)
3473 free(conn
->customRequest
);
3475 conn
->customRequest
= strdup(String_val(option
));
3477 result
= curl_easy_setopt(conn
->connection
,
3478 CURLOPT_CUSTOMREQUEST
,
3479 conn
->customRequest
);
3481 if (result
!= CURLE_OK
)
3482 raiseError(conn
, result
);
3487 static void handleInterface(Connection
*conn
, value option
)
3490 CURLcode result
= CURLE_OK
;
3492 Store_field(conn
->ocamlValues
, OcamlInterface
, option
);
3494 if (conn
->interface_
!= NULL
)
3495 free(conn
->interface_
);
3497 conn
->interface_
= strdup(String_val(option
));
3499 result
= curl_easy_setopt(conn
->connection
,
3503 if (result
!= CURLE_OK
)
3504 raiseError(conn
, result
);
3509 static void handleKRB4Level(Connection
*conn
, value option
)
3512 CURLcode result
= CURLE_OK
;
3514 switch (Long_val(option
))
3516 case 0: /* KRB4_NONE */
3517 result
= curl_easy_setopt(conn
->connection
,
3522 case 1: /* KRB4_CLEAR */
3523 result
= curl_easy_setopt(conn
->connection
,
3528 case 2: /* KRB4_SAFE */
3529 result
= curl_easy_setopt(conn
->connection
,
3534 case 3: /* KRB4_CONFIDENTIAL */
3535 result
= curl_easy_setopt(conn
->connection
,
3540 case 4: /* KRB4_PRIVATE */
3541 result
= curl_easy_setopt(conn
->connection
,
3547 failwith("Invalid KRB4 Option");
3551 if (result
!= CURLE_OK
)
3552 raiseError(conn
, result
);
3557 static void handleProgressFunction(Connection
*conn
, value option
)
3560 CURLcode result
= CURLE_OK
;
3562 if (Tag_val(option
) == Closure_tag
)
3563 Store_field(conn
->ocamlValues
, OcamlProgressCallback
, option
);
3565 failwith("Not a proper closure");
3567 result
= curl_easy_setopt(conn
->connection
,
3568 CURLOPT_PROGRESSFUNCTION
,
3570 if (result
!= CURLE_OK
)
3571 raiseError(conn
, result
);
3573 result
= curl_easy_setopt(conn
->connection
,
3574 CURLOPT_PROGRESSDATA
,
3577 if (result
!= CURLE_OK
)
3578 raiseError(conn
, result
);
3583 static void handleSSLVerifyPeer(Connection
*conn
, value option
)
3586 CURLcode result
= CURLE_OK
;
3588 result
= curl_easy_setopt(conn
->connection
,
3589 CURLOPT_SSL_VERIFYPEER
,
3592 if (result
!= CURLE_OK
)
3593 raiseError(conn
, result
);
3598 static void handleCAInfo(Connection
*conn
, value option
)
3601 CURLcode result
= CURLE_OK
;
3603 Store_field(conn
->ocamlValues
, OcamlCAInfo
, option
);
3605 if (conn
->caInfo
!= NULL
)
3608 conn
->caInfo
= strdup(String_val(option
));
3610 result
= curl_easy_setopt(conn
->connection
,
3614 if (result
!= CURLE_OK
)
3615 raiseError(conn
, result
);
3620 static void handleCAPath(Connection
*conn
, value option
)
3623 CURLcode result
= CURLE_OK
;
3625 Store_field(conn
->ocamlValues
, OcamlCAPath
, option
);
3627 if (conn
->caPath
!= NULL
)
3630 conn
->caPath
= strdup(String_val(option
));
3632 result
= curl_easy_setopt(conn
->connection
,
3636 if (result
!= CURLE_OK
)
3637 raiseError(conn
, result
);
3642 static void handleFileTime(Connection
*conn
, value option
)
3645 CURLcode result
= CURLE_OK
;
3647 result
= curl_easy_setopt(conn
->connection
,
3651 if (result
!= CURLE_OK
)
3652 raiseError(conn
, result
);
3657 static void handleMaxRedirs(Connection
*conn
, value option
)
3660 CURLcode result
= CURLE_OK
;
3662 result
= curl_easy_setopt(conn
->connection
,
3666 if (result
!= CURLE_OK
)
3667 raiseError(conn
, result
);
3672 static void handleMaxConnects(Connection
*conn
, value option
)
3675 CURLcode result
= CURLE_OK
;
3677 result
= curl_easy_setopt(conn
->connection
,
3678 CURLOPT_MAXCONNECTS
,
3681 if (result
!= CURLE_OK
)
3682 raiseError(conn
, result
);
3687 static void handleClosePolicy(Connection
*conn
, value option
)
3690 CURLcode result
= CURLE_OK
;
3692 switch (Long_val(option
))
3694 case 0: /* CLOSEPOLICY_OLDEST */
3695 result
= curl_easy_setopt(conn
->connection
,
3696 CURLOPT_CLOSEPOLICY
,
3697 CURLCLOSEPOLICY_OLDEST
);
3700 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3701 result
= curl_easy_setopt(conn
->connection
,
3702 CURLOPT_CLOSEPOLICY
,
3703 CURLCLOSEPOLICY_LEAST_RECENTLY_USED
);
3707 failwith("Invalid CLOSEPOLICY Option");
3711 if (result
!= CURLE_OK
)
3712 raiseError(conn
, result
);
3717 static void handleFreshConnect(Connection
*conn
, value option
)
3720 CURLcode result
= CURLE_OK
;
3722 result
= curl_easy_setopt(conn
->connection
,
3723 CURLOPT_FRESH_CONNECT
,
3726 if (result
!= CURLE_OK
)
3727 raiseError(conn
, result
);
3732 static void handleForbidReuse(Connection
*conn
, value option
)
3735 CURLcode result
= CURLE_OK
;
3737 result
= curl_easy_setopt(conn
->connection
,
3738 CURLOPT_FORBID_REUSE
,
3741 if (result
!= CURLE_OK
)
3742 raiseError(conn
, result
);
3747 static void handleRandomFile(Connection
*conn
, value option
)
3750 CURLcode result
= CURLE_OK
;
3752 Store_field(conn
->ocamlValues
, OcamlRandomFile
, option
);
3754 if (conn
->randomFile
!= NULL
)
3755 free(conn
->randomFile
);
3757 conn
->randomFile
= strdup(String_val(option
));
3759 result
= curl_easy_setopt(conn
->connection
,
3760 CURLOPT_RANDOM_FILE
,
3763 if (result
!= CURLE_OK
)
3764 raiseError(conn
, result
);
3769 static void handleEGDSocket(Connection
*conn
, value option
)
3772 CURLcode result
= CURLE_OK
;
3774 Store_field(conn
->ocamlValues
, OcamlEGDSocket
, option
);
3776 if (conn
->egdSocket
!= NULL
)
3777 free(conn
->egdSocket
);
3779 conn
->egdSocket
= strdup(String_val(option
));
3781 result
= curl_easy_setopt(conn
->connection
,
3785 if (result
!= CURLE_OK
)
3786 raiseError(conn
, result
);
3791 static void handleConnectTimeout(Connection
*conn
, value option
)
3794 CURLcode result
= CURLE_OK
;
3796 result
= curl_easy_setopt(conn
->connection
,
3797 CURLOPT_CONNECTTIMEOUT
,
3800 if (result
!= CURLE_OK
)
3801 raiseError(conn
, result
);
3806 static void handleHTTPGet(Connection
*conn
, value option
)
3809 CURLcode result
= CURLE_OK
;
3811 result
= curl_easy_setopt(conn
->connection
,
3815 if (result
!= CURLE_OK
)
3816 raiseError(conn
, result
);
3821 static void handleSSLVerifyHost(Connection
*conn
, value option
)
3824 CURLcode result
= CURLE_OK
;
3826 switch (Long_val(option
))
3828 case 0: /* SSLVERIFYHOST_NONE */
3829 case 1: /* SSLVERIFYHOST_EXISTENCE */
3830 case 2: /* SSLVERIFYHOST_HOSTNAME */
3831 result
= curl_easy_setopt(conn
->connection
,
3832 CURLOPT_SSL_VERIFYHOST
,
3833 /* map EXISTENCE to HOSTNAME */
3834 Long_val(option
) == 0 ? 0 : 2);
3838 failwith("Invalid SSLVERIFYHOST Option");
3842 if (result
!= CURLE_OK
)
3843 raiseError(conn
, result
);
3848 static void handleCookieJar(Connection
*conn
, value option
)
3851 CURLcode result
= CURLE_OK
;
3853 Store_field(conn
->ocamlValues
, OcamlCookieJar
, option
);
3855 if (conn
->cookieJar
!= NULL
)
3856 free(conn
->cookieJar
);
3858 conn
->cookieJar
= strdup(String_val(option
));
3860 result
= curl_easy_setopt(conn
->connection
,
3864 if (result
!= CURLE_OK
)
3865 raiseError(conn
, result
);
3870 static void handleSSLCipherList(Connection
*conn
, value option
)
3873 CURLcode result
= CURLE_OK
;
3875 Store_field(conn
->ocamlValues
, OcamlSSLCipherList
, option
);
3877 if (conn
->sslCipherList
!= NULL
)
3878 free(conn
->sslCipherList
);
3880 conn
->sslCipherList
= strdup(String_val(option
));
3882 result
= curl_easy_setopt(conn
->connection
,
3883 CURLOPT_SSL_CIPHER_LIST
,
3884 conn
->sslCipherList
);
3886 if (result
!= CURLE_OK
)
3887 raiseError(conn
, result
);
3892 static void handleHTTPVersion(Connection
*conn
, value option
)
3895 CURLcode result
= CURLE_OK
;
3897 switch (Long_val(option
))
3899 case 0: /* HTTP_VERSION_NONE */
3900 result
= curl_easy_setopt(conn
->connection
,
3901 CURLOPT_HTTP_VERSION
,
3902 CURL_HTTP_VERSION_NONE
);
3905 case 1: /* HTTP_VERSION_1_0 */
3906 result
= curl_easy_setopt(conn
->connection
,
3907 CURLOPT_HTTP_VERSION
,
3908 CURL_HTTP_VERSION_1_0
);
3911 case 2: /* HTTP_VERSION_1_1 */
3912 result
= curl_easy_setopt(conn
->connection
,
3913 CURLOPT_HTTP_VERSION
,
3914 CURL_HTTP_VERSION_1_1
);
3918 failwith("Invalid HTTP_VERSION Option");
3922 if (result
!= CURLE_OK
)
3923 raiseError(conn
, result
);
3928 static void handleFTPUseEPSV(Connection
*conn
, value option
)
3931 CURLcode result
= CURLE_OK
;
3933 result
= curl_easy_setopt(conn
->connection
,
3934 CURLOPT_FTP_USE_EPSV
,
3937 if (result
!= CURLE_OK
)
3938 raiseError(conn
, result
);
3943 static void handleDNSCacheTimeout(Connection
*conn
, value option
)
3946 CURLcode result
= CURLE_OK
;
3948 result
= curl_easy_setopt(conn
->connection
,
3949 CURLOPT_DNS_CACHE_TIMEOUT
,
3952 if (result
!= CURLE_OK
)
3953 raiseError(conn
, result
);
3958 static void handleDNSUseGlobalCache(Connection
*conn
, value option
)
3961 CURLcode result
= CURLE_OK
;
3963 result
= curl_easy_setopt(conn
->connection
,
3964 CURLOPT_DNS_USE_GLOBAL_CACHE
,
3967 if (result
!= CURLE_OK
)
3968 raiseError(conn
, result
);
3973 static void handleDebugFunction(Connection
*conn
, value option
)
3976 CURLcode result
= CURLE_OK
;
3978 if (Tag_val(option
) == Closure_tag
)
3979 Store_field(conn
->ocamlValues
, OcamlDebugCallback
, option
);
3981 failwith("Not a proper closure");
3983 result
= curl_easy_setopt(conn
->connection
,
3984 CURLOPT_DEBUGFUNCTION
,
3986 if (result
!= CURLE_OK
)
3987 raiseError(conn
, result
);
3989 result
= curl_easy_setopt(conn
->connection
,
3993 if (result
!= CURLE_OK
)
3994 raiseError(conn
, result
);
3999 static void handlePrivate(Connection
*conn
, value option
)
4001 #if HAVE_DECL_CURLOPT_PRIVATE
4003 CURLcode result
= CURLE_OK
;
4005 Store_field(conn
->ocamlValues
, OcamlPrivate
, option
);
4007 if (conn
->private != NULL
)
4008 free(conn
->private);
4010 conn
->private = strdup(String_val(option
));
4012 result
= curl_easy_setopt(conn
->connection
,
4016 if (result
!= CURLE_OK
)
4017 raiseError(conn
, result
);
4021 #pragma message("libcurl does not implement CURLOPT_PRIVATE")
4022 failwith("libcurl does not implement CURLOPT_PRIVATE");
4026 static void handleHTTP200Aliases(Connection
*conn
, value option
)
4028 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
4030 CAMLlocal1(listIter
);
4031 CURLcode result
= CURLE_OK
;
4033 Store_field(conn
->ocamlValues
, OcamlHTTP200Aliases
, option
);
4035 free_curl_slist(conn
->http200Aliases
);
4036 conn
->http200Aliases
= NULL
;
4040 while (!Is_long(listIter
))
4042 conn
->http200Aliases
= curl_slist_append(conn
->http200Aliases
, String_val(Field(listIter
, 0)));
4044 listIter
= Field(listIter
, 1);
4047 result
= curl_easy_setopt(conn
->connection
,
4048 CURLOPT_HTTP200ALIASES
,
4049 conn
->http200Aliases
);
4051 if (result
!= CURLE_OK
)
4052 raiseError(conn
, result
);
4056 #pragma message("libcurl does not implement CURLOPT_HTTP200ALIASES")
4057 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
4061 static void handleUnrestrictedAuth(Connection
*conn
, value option
)
4063 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
4065 CURLcode result
= CURLE_OK
;
4067 result
= curl_easy_setopt(conn
->connection
,
4068 CURLOPT_UNRESTRICTED_AUTH
,
4071 if (result
!= CURLE_OK
)
4072 raiseError(conn
, result
);
4076 #pragma message("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH")
4077 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4081 static void handleFTPUseEPRT(Connection
*conn
, value option
)
4083 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4085 CURLcode result
= CURLE_OK
;
4087 result
= curl_easy_setopt(conn
->connection
,
4088 CURLOPT_FTP_USE_EPRT
,
4091 if (result
!= CURLE_OK
)
4092 raiseError(conn
, result
);
4096 #pragma message("libcurl does not implement CURLOPT_FTP_USE_EPRT")
4097 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4101 static void handleHTTPAuth(Connection
*conn
, value option
)
4103 #if HAVE_DECL_CURLOPT_HTTPAUTH
4105 CAMLlocal1(listIter
);
4106 CURLcode result
= CURLE_OK
;
4107 long auth
= CURLAUTH_NONE
;
4111 while (!Is_long(listIter
))
4113 switch (Long_val(Field(listIter
, 0)))
4115 case 0: /* CURLAUTH_BASIC */
4116 auth
|= CURLAUTH_BASIC
;
4119 case 1: /* CURLAUTH_DIGEST */
4120 auth
|= CURLAUTH_DIGEST
;
4123 case 2: /* CURLAUTH_GSSNEGOTIATE */
4124 auth
|= CURLAUTH_GSSNEGOTIATE
;
4127 case 3: /* CURLAUTH_NTLM */
4128 auth
|= CURLAUTH_NTLM
;
4131 case 4: /* CURLAUTH_ANY */
4132 auth
|= CURLAUTH_ANY
;
4135 case 5: /* CURLAUTH_ANYSAFE */
4136 auth
|= CURLAUTH_ANYSAFE
;
4140 failwith("Invalid HTTPAUTH Value");
4144 listIter
= Field(listIter
, 1);
4147 result
= curl_easy_setopt(conn
->connection
,
4151 if (result
!= CURLE_OK
)
4152 raiseError(conn
, result
);
4156 #pragma message("libcurl does not implement CURLOPT_HTTPAUTH")
4157 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4161 static void handleFTPCreateMissingDirs(Connection
*conn
, value option
)
4163 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4165 CURLcode result
= CURLE_OK
;
4167 result
= curl_easy_setopt(conn
->connection
,
4168 CURLOPT_FTP_CREATE_MISSING_DIRS
,
4171 if (result
!= CURLE_OK
)
4172 raiseError(conn
, result
);
4176 #pragma message("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS")
4177 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4181 static void handleProxyAuth(Connection
*conn
, value option
)
4183 #if HAVE_DECL_CURLOPT_PROXYAUTH
4185 CAMLlocal1(listIter
);
4186 CURLcode result
= CURLE_OK
;
4187 long auth
= CURLAUTH_NONE
;
4191 while (!Is_long(listIter
))
4193 switch (Long_val(Field(listIter
, 0)))
4195 case 0: /* CURLAUTH_BASIC */
4196 auth
|= CURLAUTH_BASIC
;
4199 case 1: /* CURLAUTH_DIGEST */
4200 auth
|= CURLAUTH_DIGEST
;
4203 case 2: /* CURLAUTH_GSSNEGOTIATE */
4204 auth
|= CURLAUTH_GSSNEGOTIATE
;
4207 case 3: /* CURLAUTH_NTLM */
4208 auth
|= CURLAUTH_NTLM
;
4211 case 4: /* CURLAUTH_ANY */
4212 auth
|= CURLAUTH_ANY
;
4215 case 5: /* CURLAUTH_ANYSAFE */
4216 auth
|= CURLAUTH_ANYSAFE
;
4220 failwith("Invalid HTTPAUTH Value");
4224 listIter
= Field(listIter
, 1);
4227 result
= curl_easy_setopt(conn
->connection
,
4231 if (result
!= CURLE_OK
)
4232 raiseError(conn
, result
);
4236 #pragma message("libcurl does not implement CURLOPT_PROXYAUTH")
4237 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4241 static void handleFTPResponseTimeout(Connection
*conn
, value option
)
4243 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4245 CURLcode result
= CURLE_OK
;
4247 result
= curl_easy_setopt(conn
->connection
,
4248 CURLOPT_FTP_RESPONSE_TIMEOUT
,
4251 if (result
!= CURLE_OK
)
4252 raiseError(conn
, result
);
4256 #pragma message("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT")
4257 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4261 static void handleIPResolve(Connection
*conn
, value option
)
4263 #if HAVE_DECL_CURLOPT_IPRESOLVE
4265 CURLcode result
= CURLE_OK
;
4267 switch (Long_val(option
))
4269 case 0: /* CURL_IPRESOLVE_WHATEVER */
4270 result
= curl_easy_setopt(conn
->connection
,
4272 CURL_IPRESOLVE_WHATEVER
);
4275 case 1: /* CURL_IPRESOLVE_V4 */
4276 result
= curl_easy_setopt(conn
->connection
,
4281 case 2: /* CURL_IPRESOLVE_V6 */
4282 result
= curl_easy_setopt(conn
->connection
,
4288 failwith("Invalid IPRESOLVE Value");
4292 if (result
!= CURLE_OK
)
4293 raiseError(conn
, result
);
4297 #pragma message("libcurl does not implement CURLOPT_IPRESOLVE")
4298 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4302 static void handleMaxFileSize(Connection
*conn
, value option
)
4304 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4306 CURLcode result
= CURLE_OK
;
4308 result
= curl_easy_setopt(conn
->connection
,
4309 CURLOPT_MAXFILESIZE
,
4312 if (result
!= CURLE_OK
)
4313 raiseError(conn
, result
);
4317 #pragma message("libcurl does not implement CURLOPT_MAXFILESIZE")
4318 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4322 static void handleInFileSizeLarge(Connection
*conn
, value option
)
4324 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4326 CURLcode result
= CURLE_OK
;
4328 result
= curl_easy_setopt(conn
->connection
,
4329 CURLOPT_INFILESIZE_LARGE
,
4332 if (result
!= CURLE_OK
)
4333 raiseError(conn
, result
);
4337 #pragma message("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4338 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4342 static void handleResumeFromLarge(Connection
*conn
, value option
)
4344 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4346 CURLcode result
= CURLE_OK
;
4348 result
= curl_easy_setopt(conn
->connection
,
4349 CURLOPT_RESUME_FROM_LARGE
,
4352 if (result
!= CURLE_OK
)
4353 raiseError(conn
, result
);
4357 #pragma message("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4358 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4362 static void handleMaxFileSizeLarge(Connection
*conn
, value option
)
4364 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4366 CURLcode result
= CURLE_OK
;
4368 result
= curl_easy_setopt(conn
->connection
,
4369 CURLOPT_MAXFILESIZE_LARGE
,
4372 if (result
!= CURLE_OK
)
4373 raiseError(conn
, result
);
4377 #pragma message("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE")
4378 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4382 static void handleNETRCFile(Connection
*conn
, value option
)
4384 #if HAVE_DECL_CURLOPT_NETRC_FILE
4386 CURLcode result
= CURLE_OK
;
4388 Store_field(conn
->ocamlValues
, OcamlNETRCFile
, option
);
4390 if (conn
->netrcFile
!= NULL
)
4391 free(conn
->netrcFile
);
4393 conn
->netrcFile
= strdup(String_val(option
));
4395 result
= curl_easy_setopt(conn
->connection
,
4399 if (result
!= CURLE_OK
)
4400 raiseError(conn
, result
);
4404 #pragma message("libcurl does not implement CURLOPT_NETRC_FILE")
4405 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4409 static void handleFTPSSL(Connection
*conn
, value option
)
4411 #if HAVE_DECL_CURLOPT_FTP_SSL
4413 CURLcode result
= CURLE_OK
;
4415 switch (Long_val(option
))
4417 case 0: /* CURLFTPSSL_NONE */
4418 result
= curl_easy_setopt(conn
->connection
,
4423 case 1: /* CURLFTPSSL_TRY */
4424 result
= curl_easy_setopt(conn
->connection
,
4429 case 2: /* CURLFTPSSL_CONTROL */
4430 result
= curl_easy_setopt(conn
->connection
,
4432 CURLFTPSSL_CONTROL
);
4435 case 3: /* CURLFTPSSL_ALL */
4436 result
= curl_easy_setopt(conn
->connection
,
4442 failwith("Invalid FTP_SSL Value");
4446 if (result
!= CURLE_OK
)
4447 raiseError(conn
, result
);
4451 #pragma message("libcurl does not implement CURLOPT_FTP_SSL")
4452 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4456 static void handlePostFieldSizeLarge(Connection
*conn
, value option
)
4458 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4460 CURLcode result
= CURLE_OK
;
4462 result
= curl_easy_setopt(conn
->connection
,
4463 CURLOPT_POSTFIELDSIZE_LARGE
,
4466 if (result
!= CURLE_OK
)
4467 raiseError(conn
, result
);
4471 #pragma message("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE")
4472 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4476 static void handleTCPNoDelay(Connection
*conn
, value option
)
4478 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4480 CURLcode result
= CURLE_OK
;
4482 result
= curl_easy_setopt(conn
->connection
,
4483 CURLOPT_TCP_NODELAY
,
4486 if (result
!= CURLE_OK
)
4487 raiseError(conn
, result
);
4491 #pragma message("libcurl does not implement CURLOPT_TCP_NODELAY")
4492 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4496 static void handleFTPSSLAuth(Connection
*conn
, value option
)
4498 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4500 CURLcode result
= CURLE_OK
;
4502 switch (Long_val(option
))
4504 case 0: /* CURLFTPAUTH_DEFAULT */
4505 result
= curl_easy_setopt(conn
->connection
,
4507 CURLFTPAUTH_DEFAULT
);
4510 case 1: /* CURLFTPAUTH_SSL */
4511 result
= curl_easy_setopt(conn
->connection
,
4516 case 2: /* CURLFTPAUTH_TLS */
4517 result
= curl_easy_setopt(conn
->connection
,
4523 failwith("Invalid FTPSSLAUTH value");
4527 if (result
!= CURLE_OK
)
4528 raiseError(conn
, result
);
4532 #pragma message("libcurl does not implement CURLOPT_FTPSSLAUTH")
4533 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4537 static void handleIOCTLFunction(Connection
*conn
, value option
)
4539 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4541 CURLcode result
= CURLE_OK
;
4543 if (Tag_val(option
) == Closure_tag
)
4544 Store_field(conn
->ocamlValues
, OcamlIOCTLCallback
, option
);
4546 failwith("Not a proper closure");
4548 result
= curl_easy_setopt(conn
->connection
,
4549 CURLOPT_IOCTLFUNCTION
,
4551 if (result
!= CURLE_OK
)
4552 raiseError(conn
, result
);
4554 result
= curl_easy_setopt(conn
->connection
,
4558 if (result
!= CURLE_OK
)
4559 raiseError(conn
, result
);
4563 #pragma message("libcurl does not implement CURLOPT_IOCTLFUNCTION")
4564 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4568 static void handleFTPAccount(Connection
*conn
, value option
)
4570 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4572 CURLcode result
= CURLE_OK
;
4574 Store_field(conn
->ocamlValues
, OcamlFTPAccount
, option
);
4576 if (conn
->ftpaccount
!= NULL
)
4577 free(conn
->ftpaccount
);
4579 conn
->ftpaccount
= strdup(String_val(option
));
4581 result
= curl_easy_setopt(conn
->connection
,
4582 CURLOPT_FTP_ACCOUNT
,
4585 if (result
!= CURLE_OK
)
4586 raiseError(conn
, result
);
4590 #pragma message("libcurl does not implement CURLOPT_FTP_ACCOUNT")
4591 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4595 static void handleCookieList(Connection
*conn
, value option
)
4597 #if HAVE_DECL_CURLOPT_COOKIELIST
4599 CURLcode result
= CURLE_OK
;
4601 Store_field(conn
->ocamlValues
, OcamlCookieList
, option
);
4603 if (conn
->cookielist
!= NULL
)
4604 free(conn
->cookielist
);
4606 conn
->cookielist
= strdup(String_val(option
));
4608 result
= curl_easy_setopt(conn
->connection
,
4612 if (result
!= CURLE_OK
)
4613 raiseError(conn
, result
);
4617 #pragma message("libcurl does not implement CURLOPT_COOKIELIST")
4618 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4622 static void handleIgnoreContentLength(Connection
*conn
, value option
)
4624 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4626 CURLcode result
= CURLE_OK
;
4628 result
= curl_easy_setopt(conn
->connection
,
4629 CURLOPT_IGNORE_CONTENT_LENGTH
,
4632 if (result
!= CURLE_OK
)
4633 raiseError(conn
, result
);
4637 #pragma message("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH")
4638 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4642 static void handleFTPSkipPASVIP(Connection
*conn
, value option
)
4644 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4646 CURLcode result
= CURLE_OK
;
4648 result
= curl_easy_setopt(conn
->connection
,
4649 CURLOPT_FTP_SKIP_PASV_IP
,
4652 if (result
!= CURLE_OK
)
4653 raiseError(conn
, result
);
4657 #pragma message("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP")
4658 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4662 static void handleFTPFileMethod(Connection
*conn
, value option
)
4664 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4666 CURLcode result
= CURLE_OK
;
4668 switch (Long_val(option
))
4670 case 0: /* CURLFTPMETHOD_DEFAULT */
4671 result
= curl_easy_setopt(conn
->connection
,
4672 CURLOPT_FTP_FILEMETHOD
,
4673 CURLFTPMETHOD_DEFAULT
);
4676 case 1: /* CURLFTMETHOD_MULTICWD */
4677 result
= curl_easy_setopt(conn
->connection
,
4678 CURLOPT_FTP_FILEMETHOD
,
4679 CURLFTPMETHOD_MULTICWD
);
4682 case 2: /* CURLFTPMETHOD_NOCWD */
4683 result
= curl_easy_setopt(conn
->connection
,
4684 CURLOPT_FTP_FILEMETHOD
,
4685 CURLFTPMETHOD_NOCWD
);
4688 case 3: /* CURLFTPMETHOD_SINGLECWD */
4689 result
= curl_easy_setopt(conn
->connection
,
4690 CURLOPT_FTP_FILEMETHOD
,
4691 CURLFTPMETHOD_SINGLECWD
);
4694 failwith("Invalid FTP_FILEMETHOD value");
4698 if (result
!= CURLE_OK
)
4699 raiseError(conn
, result
);
4703 #pragma message("libcurl does not implement CURLOPT_FTP_FILEMETHOD")
4704 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4708 static void handleLocalPort(Connection
*conn
, value option
)
4710 #if HAVE_DECL_CURLOPT_LOCALPORT
4712 CURLcode result
= CURLE_OK
;
4714 result
= curl_easy_setopt(conn
->connection
,
4718 if (result
!= CURLE_OK
)
4719 raiseError(conn
, result
);
4723 #pragma message("libcurl does not implement CURLOPT_LOCALPORT")
4724 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4728 static void handleLocalPortRange(Connection
*conn
, value option
)
4730 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4732 CURLcode result
= CURLE_OK
;
4734 result
= curl_easy_setopt(conn
->connection
,
4735 CURLOPT_LOCALPORTRANGE
,
4738 if (result
!= CURLE_OK
)
4739 raiseError(conn
, result
);
4743 #pragma message("libcurl does not implement CURLOPT_LOCALPORTRANGE")
4744 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4748 static void handleConnectOnly(Connection
*conn
, value option
)
4750 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4752 CURLcode result
= CURLE_OK
;
4754 result
= curl_easy_setopt(conn
->connection
,
4755 CURLOPT_CONNECT_ONLY
,
4758 if (result
!= CURLE_OK
)
4759 raiseError(conn
, result
);
4763 #pragma message("libcurl does not implement CURLOPT_CONNECT_ONLY")
4764 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4768 static void handleMaxSendSpeedLarge(Connection
*conn
, value option
)
4770 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4772 CURLcode result
= CURLE_OK
;
4774 result
= curl_easy_setopt(conn
->connection
,
4775 CURLOPT_MAX_SEND_SPEED_LARGE
,
4778 if (result
!= CURLE_OK
)
4779 raiseError(conn
, result
);
4783 #pragma message("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE")
4784 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4788 static void handleMaxRecvSpeedLarge(Connection
*conn
, value option
)
4790 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4792 CURLcode result
= CURLE_OK
;
4794 result
= curl_easy_setopt(conn
->connection
,
4795 CURLOPT_MAX_RECV_SPEED_LARGE
,
4798 if (result
!= CURLE_OK
)
4799 raiseError(conn
, result
);
4803 #pragma message("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE")
4804 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4808 static void handleFTPAlternativeToUser(Connection
*conn
, value option
)
4810 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4812 CURLcode result
= CURLE_OK
;
4814 Store_field(conn
->ocamlValues
, OcamlFTPAlternativeToUser
, option
);
4816 if (conn
->ftpAlternativeToUser
!= NULL
)
4817 free(conn
->ftpAlternativeToUser
);
4819 conn
->ftpAlternativeToUser
= strdup(String_val(option
));
4821 result
= curl_easy_setopt(conn
->connection
,
4822 CURLOPT_FTP_ALTERNATIVE_TO_USER
,
4823 conn
->ftpAlternativeToUser
);
4825 if (result
!= CURLE_OK
)
4826 raiseError(conn
, result
);
4830 #pragma message("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER")
4831 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4835 static void handleSSLSessionIdCache(Connection
*conn
, value option
)
4837 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4839 CURLcode result
= CURLE_OK
;
4841 result
= curl_easy_setopt(conn
->connection
,
4842 CURLOPT_SSL_SESSIONID_CACHE
,
4845 if (result
!= CURLE_OK
)
4846 raiseError(conn
, result
);
4850 #pragma message("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE")
4851 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4855 static void handleSSHAuthTypes(Connection
*conn
, value option
)
4857 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4859 CAMLlocal1(listIter
);
4860 CURLcode result
= CURLE_OK
;
4861 long authTypes
= CURLSSH_AUTH_NONE
;
4865 while (!Is_long(listIter
))
4867 switch (Long_val(Field(listIter
, 0)))
4869 case 0: /* CURLSSH_AUTH_ANY */
4870 authTypes
|= CURLSSH_AUTH_ANY
;
4873 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4874 authTypes
|= CURLSSH_AUTH_PUBLICKEY
;
4877 case 2: /* CURLSSH_AUTH_PASSWORD */
4878 authTypes
|= CURLSSH_AUTH_PASSWORD
;
4881 case 3: /* CURLSSH_AUTH_HOST */
4882 authTypes
|= CURLSSH_AUTH_HOST
;
4885 case 4: /* CURLSSH_AUTH_KEYBOARD */
4886 authTypes
|= CURLSSH_AUTH_KEYBOARD
;
4890 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4894 listIter
= Field(listIter
, 1);
4897 result
= curl_easy_setopt(conn
->connection
,
4898 CURLOPT_SSH_AUTH_TYPES
,
4901 if (result
!= CURLE_OK
)
4902 raiseError(conn
, result
);
4906 #pragma message("libcurl does not implement CURLOPT_SSH_AUTH_TYPES")
4907 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4911 static void handleSSHPublicKeyFile(Connection
*conn
, value option
)
4913 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4915 CURLcode result
= CURLE_OK
;
4917 Store_field(conn
->ocamlValues
, OcamlSSHPublicKeyFile
, option
);
4919 if (conn
->sshPublicKeyFile
!= NULL
)
4920 free(conn
->sshPublicKeyFile
);
4922 conn
->sshPublicKeyFile
= strdup(String_val(option
));
4924 result
= curl_easy_setopt(conn
->connection
,
4925 CURLOPT_SSH_PUBLIC_KEYFILE
,
4926 conn
->sshPublicKeyFile
);
4928 if (result
!= CURLE_OK
)
4929 raiseError(conn
, result
);
4933 #pragma message("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE")
4934 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4938 static void handleSSHPrivateKeyFile(Connection
*conn
, value option
)
4940 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4942 CURLcode result
= CURLE_OK
;
4944 Store_field(conn
->ocamlValues
, OcamlSSHPrivateKeyFile
, option
);
4946 if (conn
->sshPrivateKeyFile
!= NULL
)
4947 free(conn
->sshPrivateKeyFile
);
4949 conn
->sshPrivateKeyFile
= strdup(String_val(option
));
4951 result
= curl_easy_setopt(conn
->connection
,
4952 CURLOPT_SSH_PRIVATE_KEYFILE
,
4953 conn
->sshPrivateKeyFile
);
4955 if (result
!= CURLE_OK
)
4956 raiseError(conn
, result
);
4960 #pragma message("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE")
4961 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4965 static void handleFTPSSLCCC(Connection
*conn
, value option
)
4967 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4969 CURLcode result
= CURLE_OK
;
4971 switch (Long_val(option
))
4973 case 0: /* CURLFTPSSL_CCC_NONE */
4974 result
= curl_easy_setopt(conn
->connection
,
4975 CURLOPT_FTP_SSL_CCC
,
4976 CURLFTPSSL_CCC_NONE
);
4979 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4980 result
= curl_easy_setopt(conn
->connection
,
4981 CURLOPT_FTP_SSL_CCC
,
4982 CURLFTPSSL_CCC_PASSIVE
);
4985 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4986 result
= curl_easy_setopt(conn
->connection
,
4987 CURLOPT_FTP_SSL_CCC
,
4988 CURLFTPSSL_CCC_ACTIVE
);
4992 failwith("Invalid FTPSSL_CCC value");
4996 if (result
!= CURLE_OK
)
4997 raiseError(conn
, result
);
5001 #pragma message("libcurl does not implement CURLOPT_FTP_SSL_CCC")
5002 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
5006 static void handleTimeoutMS(Connection
*conn
, value option
)
5008 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
5010 CURLcode result
= CURLE_OK
;
5012 result
= curl_easy_setopt(conn
->connection
,
5016 if (result
!= CURLE_OK
)
5017 raiseError(conn
, result
);
5021 #pragma message("libcurl does not implement CURLOPT_TIMEOUT_MS")
5022 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
5026 static void handleConnectTimeoutMS(Connection
*conn
, value option
)
5028 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
5030 CURLcode result
= CURLE_OK
;
5032 result
= curl_easy_setopt(conn
->connection
,
5033 CURLOPT_CONNECTTIMEOUT_MS
,
5036 if (result
!= CURLE_OK
)
5037 raiseError(conn
, result
);
5041 #pragma message("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS")
5042 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
5046 static void handleHTTPTransferDecoding(Connection
*conn
, value option
)
5048 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
5050 CURLcode result
= CURLE_OK
;
5052 result
= curl_easy_setopt(conn
->connection
,
5053 CURLOPT_HTTP_TRANSFER_DECODING
,
5056 if (result
!= CURLE_OK
)
5057 raiseError(conn
, result
);
5061 #pragma message("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING")
5062 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
5066 static void handleHTTPContentDecoding(Connection
*conn
, value option
)
5068 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
5070 CURLcode result
= CURLE_OK
;
5072 result
= curl_easy_setopt(conn
->connection
,
5073 CURLOPT_HTTP_CONTENT_DECODING
,
5076 if (result
!= CURLE_OK
)
5077 raiseError(conn
, result
);
5081 #pragma message("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING")
5082 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5086 static void handleNewFilePerms(Connection
*conn
, value option
)
5088 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5090 CURLcode result
= CURLE_OK
;
5092 result
= curl_easy_setopt(conn
->connection
,
5093 CURLOPT_NEW_FILE_PERMS
,
5096 if (result
!= CURLE_OK
)
5097 raiseError(conn
, result
);
5101 #pragma message("libcurl does not implement CURLOPT_NEW_FILE_PERMS")
5102 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5106 static void handleNewDirectoryPerms(Connection
*conn
, value option
)
5108 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5110 CURLcode result
= CURLE_OK
;
5112 result
= curl_easy_setopt(conn
->connection
,
5113 CURLOPT_NEW_DIRECTORY_PERMS
,
5116 if (result
!= CURLE_OK
)
5117 raiseError(conn
, result
);
5121 #pragma message("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS")
5122 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5126 static void handlePost301(Connection
*conn
, value option
)
5128 #if HAVE_DECL_CURLOPT_POST301
5130 CURLcode result
= CURLE_OK
;
5132 result
= curl_easy_setopt(conn
->connection
,
5136 if (result
!= CURLE_OK
)
5137 raiseError(conn
, result
);
5141 #pragma message("libcurl does not implement CURLOPT_POST301")
5142 failwith("libcurl does not implement CURLOPT_POST301");
5146 static void handleSSHHostPublicKeyMD5(Connection
*conn
, value option
)
5148 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5150 CURLcode result
= CURLE_OK
;
5152 Store_field(conn
->ocamlValues
, OcamlSSHHostPublicKeyMD5
, option
);
5154 if (conn
->sshHostPublicKeyMD5
!= NULL
)
5155 free(conn
->sshHostPublicKeyMD5
);
5157 conn
->sshHostPublicKeyMD5
= strdup(String_val(option
));
5159 result
= curl_easy_setopt(conn
->connection
,
5160 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
,
5161 conn
->sshHostPublicKeyMD5
);
5163 if (result
!= CURLE_OK
)
5164 raiseError(conn
, result
);
5168 #pragma message("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5")
5169 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5173 static void handleCopyPostFields(Connection
*conn
, value option
)
5175 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5177 CURLcode result
= CURLE_OK
;
5179 Store_field(conn
->ocamlValues
, OcamlCopyPostFields
, option
);
5181 if (conn
->copyPostFields
!= NULL
)
5182 free(conn
->copyPostFields
);
5184 conn
->copyPostFields
= strdup(String_val(option
));
5186 result
= curl_easy_setopt(conn
->connection
,
5187 CURLOPT_COPYPOSTFIELDS
,
5188 conn
->copyPostFields
);
5190 if (result
!= CURLE_OK
)
5191 raiseError(conn
, result
);
5195 #pragma message("libcurl does not implement CURLOPT_COPYPOSTFIELDS")
5196 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5200 static void handleProxyTransferMode(Connection
*conn
, value option
)
5202 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5204 CURLcode result
= CURLE_OK
;
5206 result
= curl_easy_setopt(conn
->connection
,
5207 CURLOPT_PROXY_TRANSFER_MODE
,
5210 if (result
!= CURLE_OK
)
5211 raiseError(conn
, result
);
5215 #pragma message("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE")
5216 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5220 static void handleSeekFunction(Connection
*conn
, value option
)
5222 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5224 CURLcode result
= CURLE_OK
;
5226 if (Tag_val(option
) == Closure_tag
)
5227 Store_field(conn
->ocamlValues
, OcamlSeekFunctionCallback
, option
);
5229 failwith("Not a proper closure");
5231 result
= curl_easy_setopt(conn
->connection
,
5232 CURLOPT_SEEKFUNCTION
,
5235 if (result
!= CURLE_OK
)
5236 raiseError(conn
, result
);
5238 result
= curl_easy_setopt(conn
->connection
,
5242 if (result
!= CURLE_OK
)
5243 raiseError(conn
, result
);
5247 #pragma message("libcurl does not implement CURLOPT_SEEKFUNCTION")
5248 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5252 static void handleAutoReferer(Connection
*conn
, value option
)
5254 #if HAVE_DECL_CURLOPT_AUTOREFERER
5256 CURLcode result
= curl_easy_setopt(conn
->connection
,
5257 CURLOPT_AUTOREFERER
,
5260 if (result
!= CURLE_OK
)
5261 raiseError(conn
, result
);
5265 #pragma message("libcurl does not implement CURLOPT_AUTOREFERER")
5266 failwith("libcurl does not implement CURLOPT_AUTOREFERER");
5270 static void handleOpenSocketFunction(Connection
*conn
, value option
)
5272 #if HAVE_DECL_CURLOPT_OPENSOCKETFUNCTION
5274 CURLcode result
= CURLE_OK
;
5276 Store_field(conn
->ocamlValues
, OcamlOpenSocketFunctionCallback
, option
);
5278 result
= curl_easy_setopt(conn
->connection
,
5279 CURLOPT_OPENSOCKETDATA
,
5282 if (result
!= CURLE_OK
)
5283 raiseError(conn
, result
);
5285 result
= curl_easy_setopt(conn
->connection
,
5286 CURLOPT_OPENSOCKETFUNCTION
,
5287 openSocketFunction
);
5289 if (result
!= CURLE_OK
)
5290 raiseError(conn
, result
);
5294 #pragma message("libcurl does not implement CURLOPT_OPENSOCKETFUNCTION")
5295 failwith("libcurl does not implement CURLOPT_OPENSOCKETFUNCTION");
5299 static void handleProxyType(Connection
*conn
, value option
)
5301 #if HAVE_DECL_CURLOPT_PROXYTYPE
5303 CURLcode result
= CURLE_OK
;
5306 switch (Long_val(option
))
5308 case 0: proxy_type
= CURLPROXY_HTTP
; break;
5309 case 1: proxy_type
= CURLPROXY_HTTP_1_0
; break;
5310 case 2: proxy_type
= CURLPROXY_SOCKS4
; break;
5311 case 3: proxy_type
= CURLPROXY_SOCKS5
; break;
5312 case 4: proxy_type
= CURLPROXY_SOCKS4A
; break;
5313 case 5: proxy_type
= CURLPROXY_SOCKS5_HOSTNAME
; break;
5315 failwith("Invalid curl proxy type");
5318 result
= curl_easy_setopt(conn
->connection
,
5322 if (result
!= CURLE_OK
)
5323 raiseError(conn
, result
);
5327 #pragma message("libcurl does not implement CURLOPT_PROXYTYPE")
5328 failwith("libcurl does not implement CURLOPT_PROXYTYPE");
5332 #if HAVE_DECL_CURLOPT_PROTOCOLS && HAVE_DECL_CURLOPT_REDIR_PROTOCOLS
5337 CURLPROTO_HTTP
, CURLPROTO_HTTPS
, CURLPROTO_FTP
, CURLPROTO_FTPS
, CURLPROTO_SCP
, CURLPROTO_SFTP
,
5338 CURLPROTO_TELNET
, CURLPROTO_LDAP
, CURLPROTO_LDAPS
, CURLPROTO_DICT
, CURLPROTO_FILE
, CURLPROTO_TFTP
,
5339 /* factor out with autoconf? */
5340 #if defined(CURLPROTO_IMAP)
5345 #if defined(CURLPROTO_IMAPS)
5350 #if defined(CURLPROTO_POP3)
5355 #if defined(CURLPROTO_POP3S)
5360 #if defined(CURLPROTO_SMTP)
5365 #if defined(CURLPROTO_SMTPS)
5370 #if defined(CURLPROTO_RTSP)
5375 #if defined(CURLPROTO_RTMP)
5380 #if defined(CURLPROTO_RTMPT)
5385 #if defined(CURLPROTO_RTMPE)
5390 #if defined(CURLPROTO_RTMPTE)
5395 #if defined(CURLPROTO_RTMPS)
5400 #if defined(CURLPROTO_RTMPTS)
5405 #if defined(CURLPROTO_GOPHER)
5412 static void handleProtocolsOption(CURLoption curlopt
, Connection
*conn
, value option
)
5415 CURLcode result
= CURLE_OK
;
5419 while (Val_emptylist
!= option
)
5421 index
= Int_val(Field(option
, 0));
5422 if ((index
< 0) || ((size_t)index
>= sizeof(protoMap
) / sizeof(protoMap
[0])))
5423 failwith("Invalid curl protocol");
5425 protocols
= protocols
| protoMap
[index
];
5427 option
= Field(option
, 1);
5430 result
= curl_easy_setopt(conn
->connection
,
5434 if (result
!= CURLE_OK
)
5435 raiseError(conn
, result
);
5440 static void handleProtocols(Connection
*conn
, value option
)
5442 handleProtocolsOption(CURLOPT_PROTOCOLS
, conn
, option
);
5445 static void handleRedirProtocols(Connection
*conn
, value option
)
5447 handleProtocolsOption(CURLOPT_REDIR_PROTOCOLS
, conn
, option
);
5451 #pragma message("libcurl does not implement CURLOPT_PROTOCOLS or CURLOPT_REDIR_PROTOCOLS")
5452 static void handleProtocols(Connection
*conn
, value option
)
5454 failwith("libcurl does not implement CURLOPT_PROTOCOLS");
5456 static void handleRedirProtocols(Connection
*conn
, value option
)
5458 failwith("libcurl does not implement CURLOPT_REDIR_PROTOCOLS");
5462 #if HAVE_DECL_CURLOPT_RESOLVE
5463 static void handleResolve(Connection
*conn
, value option
)
5468 CURLcode result
= CURLE_OK
;
5470 free_curl_slist(conn
->resolve
);
5471 conn
->resolve
= NULL
;
5475 while (head
!= Val_emptylist
)
5477 conn
->resolve
= curl_slist_append(conn
->resolve
, String_val(Field(head
,0)));
5478 head
= Field(head
, 1);
5481 result
= curl_easy_setopt(conn
->connection
,
5485 if (result
!= CURLE_OK
)
5486 raiseError(conn
, result
);
5492 #pragma message("libcurl does not implement CURLOPT_RESOLVE")
5493 static void handleResolve(Connection
*conn
, value option
)
5495 failwith("libcurl does not implement CURLOPT_RESOLVE");
5499 #if HAVE_DECL_CURLOPT_DNS_SERVERS
5500 static void handleDnsServers(Connection
*conn
, value option
)
5504 Store_field(conn
->ocamlValues
, OcamlDNSServers
, option
);
5506 CURLcode result
= CURLE_OK
;
5507 free_if(conn
->dns_servers
);
5509 conn
->dns_servers
= strdup(String_val(option
));
5511 result
= curl_easy_setopt(conn
->connection
,
5512 CURLOPT_DNS_SERVERS
,
5515 if (result
!= CURLE_OK
)
5516 raiseError(conn
, result
);
5521 #pragma message("libcurl does not implement CURLOPT_DNS_SERVERS")
5522 static void handleDnsServers(Connection
*conn
, value option
)
5524 failwith("libcurl does not implement CURLOPT_DNS_SERVERS");
5529 ** curl_easy_setopt helper function
5532 CAMLprim value
helper_curl_easy_setopt(value conn
, value option
)
5534 CAMLparam2(conn
, option
);
5536 Connection
*connection
= Connection_val(conn
);
5538 checkConnection(connection
);
5540 if (Is_long(option
))
5544 sprintf(error
, "Unimplemented Option: %s",
5545 findOption(unimplementedOptionMap
,
5546 (CURLoption
)(Long_val(option
))));
5551 if (!Is_block(option
))
5552 failwith("Not a block");
5554 if (Wosize_val(option
) < 1)
5555 failwith("Insufficient data in block");
5557 data
= Field(option
, 0);
5559 if (Tag_val(option
) < sizeof(implementedOptionMap
)/sizeof(CURLOptionMapping
))
5560 (*implementedOptionMap
[Tag_val(option
)].optionHandler
)(connection
,
5563 failwith("Invalid CURLOPT Option");
5565 CAMLreturn(Val_unit
);
5569 ** curl_easy_perform helper function
5572 CAMLprim value
helper_curl_easy_perform(value conn
)
5575 CURLcode result
= CURLE_OK
;
5576 Connection
*connection
= Connection_val(conn
);
5578 checkConnection(connection
);
5580 enter_blocking_section();
5581 result
= curl_easy_perform(connection
->connection
);
5582 leave_blocking_section();
5584 if (result
!= CURLE_OK
)
5585 raiseError(connection
, result
);
5587 CAMLreturn(Val_unit
);
5591 ** curl_easy_cleanup helper function
5594 CAMLprim value
helper_curl_easy_cleanup(value conn
)
5597 Connection
*connection
= Connection_val(conn
);
5599 checkConnection(connection
);
5601 removeConnection(connection
, 0);
5603 CAMLreturn(Val_unit
);
5607 ** curl_easy_duphandle helper function
5610 CAMLprim value
helper_curl_easy_duphandle(value conn
)
5614 Connection
*connection
= Connection_val(conn
);
5616 checkConnection(connection
);
5618 result
= caml_curl_alloc(duplicateConnection(connection
));
5624 ** curl_easy_getinfo helper function
5627 enum GetInfoResultType
{
5628 StringValue
, LongValue
, DoubleValue
, StringListValue
5631 value
convertStringList(struct curl_slist
*slist
)
5634 CAMLlocal3(result
, current
, next
);
5635 struct curl_slist
*p
= slist
;
5637 result
= Val_int(0);
5638 current
= Val_int(0);
5643 next
= alloc_tuple(2);
5644 Store_field(next
, 0, copy_string(p
->data
));
5645 Store_field(next
, 1, Val_int(0));
5647 if (result
== Val_int(0))
5650 if (current
!= Val_int(0))
5651 Store_field(current
, 1, next
);
5658 curl_slist_free_all(slist
);
5663 CAMLprim value
helper_curl_easy_getinfo(value conn
, value option
)
5665 CAMLparam2(conn
, option
);
5667 CURLcode curlResult
;
5668 Connection
*connection
= Connection_val(conn
);
5669 enum GetInfoResultType resultType
;
5670 char *strValue
= NULL
;
5673 struct curl_slist
*stringListValue
= NULL
;
5675 checkConnection(connection
);
5677 switch(Long_val(option
))
5679 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5680 case 0: /* CURLINFO_EFFECTIVE_URL */
5681 resultType
= StringValue
;
5683 curlResult
= curl_easy_getinfo(connection
->connection
,
5684 CURLINFO_EFFECTIVE_URL
,
5688 #pragma message("libcurl does not provide CURLINFO_EFFECTIVE_URL")
5691 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5692 case 1: /* CURLINFO_HTTP_CODE */
5693 case 2: /* CURLINFO_RESPONSE_CODE */
5694 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5695 resultType
= LongValue
;
5697 curlResult
= curl_easy_getinfo(connection
->connection
,
5698 CURLINFO_RESPONSE_CODE
,
5701 resultType
= LongValue
;
5703 curlResult
= curl_easy_getinfo(connection
->connection
,
5710 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5711 case 3: /* CURLINFO_TOTAL_TIME */
5712 resultType
= DoubleValue
;
5714 curlResult
= curl_easy_getinfo(connection
->connection
,
5715 CURLINFO_TOTAL_TIME
,
5720 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5721 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5722 resultType
= DoubleValue
;
5724 curlResult
= curl_easy_getinfo(connection
->connection
,
5725 CURLINFO_NAMELOOKUP_TIME
,
5730 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5731 case 5: /* CURLINFO_CONNECT_TIME */
5732 resultType
= DoubleValue
;
5734 curlResult
= curl_easy_getinfo(connection
->connection
,
5735 CURLINFO_CONNECT_TIME
,
5740 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5741 case 6: /* CURLINFO_PRETRANSFER_TIME */
5742 resultType
= DoubleValue
;
5744 curlResult
= curl_easy_getinfo(connection
->connection
,
5745 CURLINFO_PRETRANSFER_TIME
,
5750 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5751 case 7: /* CURLINFO_SIZE_UPLOAD */
5752 resultType
= DoubleValue
;
5754 curlResult
= curl_easy_getinfo(connection
->connection
,
5755 CURLINFO_SIZE_UPLOAD
,
5760 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5761 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5762 resultType
= DoubleValue
;
5764 curlResult
= curl_easy_getinfo(connection
->connection
,
5765 CURLINFO_SIZE_DOWNLOAD
,
5770 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5771 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5772 resultType
= DoubleValue
;
5774 curlResult
= curl_easy_getinfo(connection
->connection
,
5775 CURLINFO_SPEED_DOWNLOAD
,
5780 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5781 case 10: /* CURLINFO_SPEED_UPLOAD */
5782 resultType
= DoubleValue
;
5784 curlResult
= curl_easy_getinfo(connection
->connection
,
5785 CURLINFO_SPEED_UPLOAD
,
5791 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5792 case 11: /* CURLINFO_HEADER_SIZE */
5793 resultType
= LongValue
;
5795 curlResult
= curl_easy_getinfo(connection
->connection
,
5796 CURLINFO_HEADER_SIZE
,
5801 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5802 case 12: /* CURLINFO_REQUEST_SIZE */
5803 resultType
= LongValue
;
5805 curlResult
= curl_easy_getinfo(connection
->connection
,
5806 CURLINFO_REQUEST_SIZE
,
5811 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5812 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5813 resultType
= LongValue
;
5815 curlResult
= curl_easy_getinfo(connection
->connection
,
5816 CURLINFO_SSL_VERIFYRESULT
,
5821 #if HAVE_DECL_CURLINFO_FILETIME
5822 case 14: /* CURLINFO_FILETIME */
5823 resultType
= DoubleValue
;
5825 curlResult
= curl_easy_getinfo(connection
->connection
,
5829 doubleValue
= longValue
;
5833 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5834 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5835 resultType
= DoubleValue
;
5837 curlResult
= curl_easy_getinfo(connection
->connection
,
5838 CURLINFO_CONTENT_LENGTH_DOWNLOAD
,
5843 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5844 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5845 resultType
= DoubleValue
;
5847 curlResult
= curl_easy_getinfo(connection
->connection
,
5848 CURLINFO_CONTENT_LENGTH_UPLOAD
,
5853 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5854 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5855 resultType
= DoubleValue
;
5857 curlResult
= curl_easy_getinfo(connection
->connection
,
5858 CURLINFO_STARTTRANSFER_TIME
,
5863 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5864 case 18: /* CURLINFO_CONTENT_TYPE */
5865 resultType
= StringValue
;
5867 curlResult
= curl_easy_getinfo(connection
->connection
,
5868 CURLINFO_CONTENT_TYPE
,
5873 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5874 case 19: /* CURLINFO_REDIRECT_TIME */
5875 resultType
= DoubleValue
;
5877 curlResult
= curl_easy_getinfo(connection
->connection
,
5878 CURLINFO_REDIRECT_TIME
,
5883 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5884 case 20: /* CURLINFO_REDIRECT_COUNT */
5885 resultType
= LongValue
;
5887 curlResult
= curl_easy_getinfo(connection
->connection
,
5888 CURLINFO_REDIRECT_COUNT
,
5893 #if HAVE_DECL_CURLINFO_PRIVATE
5894 case 21: /* CURLINFO_PRIVATE */
5895 resultType
= StringValue
;
5897 curlResult
= curl_easy_getinfo(connection
->connection
,
5903 #if HAVE_DECL_CURLINFO_HTTP_CONNECTCODE
5904 case 22: /* CURLINFO_HTTP_CONNECTCODE */
5905 resultType
= LongValue
;
5907 curlResult
= curl_easy_getinfo(connection
->connection
,
5908 CURLINFO_HTTP_CONNECTCODE
,
5913 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5914 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5915 resultType
= LongValue
;
5917 curlResult
= curl_easy_getinfo(connection
->connection
,
5918 CURLINFO_HTTPAUTH_AVAIL
,
5923 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5924 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5925 resultType
= LongValue
;
5927 curlResult
= curl_easy_getinfo(connection
->connection
,
5928 CURLINFO_PROXYAUTH_AVAIL
,
5933 #if HAVE_DECL_CURLINFO_OS_ERRNO
5934 case 25: /* CURLINFO_OS_ERRNO */
5935 resultType
= LongValue
;
5937 curlResult
= curl_easy_getinfo(connection
->connection
,
5943 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5944 case 26: /* CURLINFO_NUM_CONNECTS */
5945 resultType
= LongValue
;
5947 curlResult
= curl_easy_getinfo(connection
->connection
,
5948 CURLINFO_NUM_CONNECTS
,
5953 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5954 case 27: /* CURLINFO_SSL_ENGINES */
5955 resultType
= StringListValue
;
5957 curlResult
= curl_easy_getinfo(connection
->connection
,
5958 CURLINFO_SSL_ENGINES
,
5963 #if HAVE_DECL_CURLINFO_COOKIELIST
5964 case 28: /* CURLINFO_COOKIELIST */
5965 resultType
= StringListValue
;
5967 curlResult
= curl_easy_getinfo(connection
->connection
,
5968 CURLINFO_COOKIELIST
,
5973 #if HAVE_DECL_CURLINFO_LASTSOCKET
5974 case 29: /* CURLINFO_LASTSOCKET */
5975 resultType
= LongValue
;
5977 curlResult
= curl_easy_getinfo(connection
->connection
,
5978 CURLINFO_LASTSOCKET
,
5983 #if HAVE_DECL_CURLINFO_FTP_ENTRY_PATH
5984 case 30: /* CURLINFO_FTP_ENTRY_PATH */
5985 resultType
= StringValue
;
5987 curlResult
= curl_easy_getinfo(connection
->connection
,
5988 CURLINFO_FTP_ENTRY_PATH
,
5993 #if HAVE_DECL_CURLINFO_REDIRECT_URL
5994 case 31: /* CURLINFO_REDIRECT_URL */
5995 resultType
= StringValue
;
5997 curlResult
= curl_easy_getinfo(connection
->connection
,
5998 CURLINFO_REDIRECT_URL
,
6002 #pragma message("libcurl does not provide CURLINFO_REDIRECT_URL")
6005 #if HAVE_DECL_CURLINFO_PRIMARY_IP
6006 case 32: /* CURLINFO_PRIMARY_IP */
6007 resultType
= StringValue
;
6009 curlResult
= curl_easy_getinfo(connection
->connection
,
6010 CURLINFO_PRIMARY_IP
,
6014 #pragma message("libcurl does not provide CURLINFO_PRIMARY_IP")
6017 #if HAVE_DECL_CURLINFO_LOCAL_IP
6018 case 33: /* CURLINFO_LOCAL_IP */
6019 resultType
= StringValue
;
6021 curlResult
= curl_easy_getinfo(connection
->connection
,
6026 #pragma message("libcurl does not provide CURLINFO_LOCAL_IP")
6029 #if HAVE_DECL_CURLINFO_LOCAL_PORT
6030 case 34: /* CURLINFO_LOCAL_PORT */
6031 resultType
= LongValue
;
6033 curlResult
= curl_easy_getinfo(connection
->connection
,
6034 CURLINFO_LOCAL_PORT
,
6038 #pragma message("libcurl does not provide CURLINFO_LOCAL_PORT")
6041 #if HAVE_DECL_CURLINFO_CONDITION_UNMET
6042 case 35: /* CURLINFO_CONDITION_UNMET */
6043 resultType
= LongValue
;
6045 curlResult
= curl_easy_getinfo(connection
->connection
,
6046 CURLINFO_CONDITION_UNMET
,
6050 #pragma message("libcurl does not provide CURLINFO_CONDITION_UNMET")
6054 failwith("Invalid CURLINFO Option");
6058 if (curlResult
!= CURLE_OK
)
6059 raiseError(connection
, curlResult
);
6064 result
= alloc(1, StringValue
);
6065 Store_field(result
, 0, copy_string(strValue
?strValue
:""));
6069 result
= alloc(1, LongValue
);
6070 Store_field(result
, 0, Val_long(longValue
));
6074 result
= alloc(1, DoubleValue
);
6075 Store_field(result
, 0, copy_double(doubleValue
));
6078 case StringListValue
:
6079 result
= alloc(1, StringListValue
);
6080 Store_field(result
, 0, convertStringList(stringListValue
));
6088 ** curl_escape helper function
6091 CAMLprim value
helper_curl_escape(value str
)
6097 curlResult
= curl_escape(String_val(str
), string_length(str
));
6098 result
= copy_string(curlResult
);
6105 ** curl_unescape helper function
6108 CAMLprim value
helper_curl_unescape(value str
)
6114 curlResult
= curl_unescape(String_val(str
), string_length(str
));
6115 result
= copy_string(curlResult
);
6122 ** curl_getdate helper function
6125 CAMLprim value
helper_curl_getdate(value str
, value now
)
6127 CAMLparam2(str
, now
);
6132 curlNow
= (time_t)Double_val(now
);
6133 curlResult
= curl_getdate(String_val(str
), &curlNow
);
6134 result
= copy_double((double)curlResult
);
6140 ** curl_version helper function
6143 CAMLprim value
helper_curl_version(void)
6149 str
= curl_version();
6150 result
= copy_string(str
);
6155 struct CURLVersionBitsMapping
6161 struct CURLVersionBitsMapping versionBitsMap
[] =
6163 {CURL_VERSION_IPV6
, "ipv6"},
6164 {CURL_VERSION_KERBEROS4
, "kerberos4"},
6165 {CURL_VERSION_SSL
, "ssl"},
6166 {CURL_VERSION_LIBZ
, "libz"},
6167 {CURL_VERSION_NTLM
, "ntlm"},
6168 {CURL_VERSION_GSSNEGOTIATE
, "gssnegotiate"},
6169 {CURL_VERSION_DEBUG
, "debug"},
6170 {CURL_VERSION_CURLDEBUG
, "curldebug"},
6171 {CURL_VERSION_ASYNCHDNS
, "asynchdns"},
6172 {CURL_VERSION_SPNEGO
, "spnego"},
6173 {CURL_VERSION_LARGEFILE
, "largefile"},
6174 {CURL_VERSION_IDN
, "idn"},
6175 {CURL_VERSION_SSPI
, "sspi"},
6176 {CURL_VERSION_CONV
, "conv"},
6177 #if HAVE_DECL_CURL_VERSION_TLSAUTH_SRP
6178 {CURL_VERSION_TLSAUTH_SRP
, "srp"},
6180 #if HAVE_DECL_CURL_VERSION_NTLM_WB
6181 {CURL_VERSION_NTLM_WB
, "wb"},
6185 CAMLprim value
caml_curl_version_info(value unit
)
6188 CAMLlocal4(v
, vlist
, vnum
, vfeatures
);
6189 const char* const* p
= NULL
;
6192 curl_version_info_data
* data
= curl_version_info(CURLVERSION_NOW
);
6193 if (NULL
== data
) caml_failwith("curl_version_info");
6195 vlist
= Val_emptylist
;
6196 for (p
= data
->protocols
; NULL
!= *p
; p
++)
6198 vlist
= Val_cons(vlist
, caml_copy_string(*p
));
6201 vfeatures
= Val_emptylist
;
6202 for (i
= 0; i
< sizeof(versionBitsMap
)/sizeof(versionBitsMap
[0]); i
++)
6204 if (0 != (versionBitsMap
[i
].code
& data
->features
))
6205 vfeatures
= Val_cons(vfeatures
, caml_copy_string(versionBitsMap
[i
].name
));
6208 vnum
= caml_alloc_tuple(3);
6209 Store_field(vnum
,0,Val_int(0xFF & (data
->version_num
>> 16)));
6210 Store_field(vnum
,1,Val_int(0xFF & (data
->version_num
>> 8)));
6211 Store_field(vnum
,2,Val_int(0xFF & (data
->version_num
)));
6213 v
= caml_alloc_tuple(12);
6214 Store_field(v
,0,caml_copy_string(data
->version
));
6215 Store_field(v
,1,vnum
);
6216 Store_field(v
,2,caml_copy_string(data
->host
));
6217 Store_field(v
,3,vfeatures
);
6218 Store_field(v
,4,data
->ssl_version
? Val_some(caml_copy_string(data
->ssl_version
)) : Val_none
);
6219 Store_field(v
,5,data
->libz_version
? Val_some(caml_copy_string(data
->libz_version
)) : Val_none
);
6220 Store_field(v
,6,vlist
);
6221 Store_field(v
,7,caml_copy_string((data
->age
>= 1 && data
->ares
) ? data
->ares
: ""));
6222 Store_field(v
,8,Val_int((data
->age
>= 1) ? data
->ares_num
: 0));
6223 Store_field(v
,9,caml_copy_string((data
->age
>= 2 && data
->libidn
) ? data
->libidn
: ""));
6224 Store_field(v
,10,Val_int((data
->age
>= 3) ? data
->iconv_ver_num
: 0));
6225 Store_field(v
,11,caml_copy_string((data
->age
>= 3 && data
->libssh_version
) ? data
->libssh_version
: ""));
6230 CAMLprim value
caml_curl_pause(value conn
, value opts
)
6232 CAMLparam2(conn
, opts
);
6233 CAMLlocal4(v
, vlist
, vnum
, vfeatures
);
6234 Connection
*connection
= Connection_val(conn
);
6238 while (Val_emptylist
!= opts
)
6240 switch (Int_val(Field(opts
,0)))
6242 case 0: bitmask
|= CURLPAUSE_SEND
; break;
6243 case 1: bitmask
|= CURLPAUSE_RECV
; break;
6244 case 2: bitmask
|= CURLPAUSE_ALL
; break;
6245 default: caml_failwith("wrong pauseOption");
6247 opts
= Field(opts
,1);
6250 result
= curl_easy_pause(connection
->connection
,bitmask
);
6251 if (result
!= CURLE_OK
)
6252 raiseError(connection
, result
);
6254 CAMLreturn(Val_unit
);
6258 * Curl multi stack support
6260 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
6261 * Other exported functions are prefixed with caml_curlm_, some of them
6262 * can/should be decomposed into smaller parts.
6265 struct ml_multi_handle
6268 value values
; /* callbacks */
6273 curlmopt_socket_function
,
6274 curlmopt_timer_function
,
6276 /* last, not used */
6280 typedef struct ml_multi_handle ml_multi_handle
;
6282 #define Multi_val(v) (*(ml_multi_handle**)Data_custom_val(v))
6283 #define CURLM_val(v) (Multi_val(v)->handle)
6285 static struct custom_operations curl_multi_ops
= {
6287 custom_finalize_default
,
6288 custom_compare_default
,
6289 custom_hash_default
,
6290 custom_serialize_default
,
6291 custom_deserialize_default
,
6292 #if defined(custom_compare_ext_default)
6293 custom_compare_ext_default
,
6297 CAMLprim value
caml_curl_multi_init(value unit
)
6301 ml_multi_handle
* multi
= (ml_multi_handle
*)caml_stat_alloc(sizeof(ml_multi_handle
));
6302 CURLM
* h
= curl_multi_init();
6306 caml_stat_free(multi
);
6307 failwith("caml_curl_multi_init");
6311 multi
->values
= caml_alloc(multi_values_total
, 0);
6312 caml_register_generational_global_root(&multi
->values
);
6314 v
= caml_alloc_custom(&curl_multi_ops
, sizeof(ml_multi_handle
*), 0, 1);
6315 Multi_val(v
) = multi
;
6320 CAMLprim value
caml_curl_multi_cleanup(value handle
)
6323 ml_multi_handle
* h
= Multi_val(handle
);
6326 CAMLreturn(Val_unit
);
6328 caml_remove_generational_global_root(&h
->values
);
6330 if (CURLM_OK
!= curl_multi_cleanup(h
->handle
))
6331 failwith("caml_curl_multi_cleanup");
6333 Multi_val(handle
) = (ml_multi_handle
*)NULL
;
6335 CAMLreturn(Val_unit
);
6338 static CURL
* curlm_remove_finished(CURLM
* multi_handle
, CURLcode
* result
)
6340 int msgs_in_queue
= 0;
6344 CURLMsg
* msg
= curl_multi_info_read(multi_handle
, &msgs_in_queue
);
6345 if (NULL
== msg
) return NULL
;
6346 if (CURLMSG_DONE
== msg
->msg
)
6348 CURL
* easy_handle
= msg
->easy_handle
;
6349 if (result
) *result
= msg
->data
.result
;
6350 if (CURLM_OK
!= curl_multi_remove_handle(multi_handle
, easy_handle
))
6352 /*failwith("curlm_remove_finished");*/
6359 CAMLprim value
caml_curlm_remove_finished(value v_multi
)
6361 CAMLparam1(v_multi
);
6362 CAMLlocal2(v_easy
, v_tuple
);
6364 CURLM
* multi_handle
;
6366 Connection
* conn
= NULL
;
6368 multi_handle
= CURLM_val(v_multi
);
6370 caml_enter_blocking_section();
6371 handle
= curlm_remove_finished(multi_handle
,&result
);
6372 caml_leave_blocking_section();
6376 CAMLreturn(Val_none
);
6380 conn
= findConnection(handle
);
6381 if (conn
->errorBuffer
!= NULL
)
6383 Store_field(Field(conn
->ocamlValues
, OcamlErrorBuffer
), 0, caml_copy_string(conn
->errorBuffer
));
6386 /* NB: same handle, but different block */
6387 v_easy
= caml_curl_alloc(conn
);
6388 v_tuple
= caml_alloc(2, 0);
6389 Store_field(v_tuple
,0,v_easy
);
6390 Store_field(v_tuple
,1,Val_int(result
)); /* CURLcode */
6391 CAMLreturn(Val_some(v_tuple
));
6395 static int curlm_wait_data(CURLM
* multi_handle
)
6397 struct timeval timeout
;
6409 /* set a suitable timeout */
6411 timeout
.tv_usec
= 0;
6413 /* get file descriptors from the transfers */
6414 ret
= curl_multi_fdset(multi_handle
, &fdread
, &fdwrite
, &fdexcep
, &maxfd
);
6416 if (ret
== CURLM_OK
&& maxfd
>= 0)
6418 int rc
= select(maxfd
+1, &fdread
, &fdwrite
, &fdexcep
, &timeout
);
6419 if (-1 != rc
) return 0;
6424 CAMLprim value
caml_curlm_wait_data(value v_multi
)
6426 CAMLparam1(v_multi
);
6428 CURLM
* h
= CURLM_val(v_multi
);
6430 caml_enter_blocking_section();
6431 ret
= curlm_wait_data(h
);
6432 caml_leave_blocking_section();
6434 CAMLreturn(Val_bool(0 == ret
));
6437 CAMLprim value
caml_curl_multi_add_handle(value v_multi
, value v_easy
)
6439 CAMLparam2(v_multi
,v_easy
);
6440 CURLM
* multi
= CURLM_val(v_multi
);
6441 Connection
* conn
= Connection_val(v_easy
);
6443 /* prevent collection of OCaml value while the easy handle is used
6444 and may invoke callbacks registered on OCaml side */
6447 /* may invoke callbacks so need to be consistent with locks */
6448 caml_enter_blocking_section();
6449 if (CURLM_OK
!= curl_multi_add_handle(multi
, conn
->connection
))
6451 conn
->refcount
--; /* not added, revert */
6452 caml_leave_blocking_section();
6453 failwith("caml_curl_multi_add_handle");
6455 caml_leave_blocking_section();
6457 CAMLreturn(Val_unit
);
6460 CAMLprim value
caml_curl_multi_remove_handle(value v_multi
, value v_easy
)
6462 CAMLparam2(v_multi
,v_easy
);
6463 CURLM
* multi
= CURLM_val(v_multi
);
6464 Connection
* conn
= Connection_val(v_easy
);
6466 /* may invoke callbacks so need to be consistent with locks */
6467 caml_enter_blocking_section();
6468 if (CURLM_OK
!= curl_multi_remove_handle(multi
, conn
->connection
))
6470 caml_leave_blocking_section();
6471 failwith("caml_curl_multi_remove_handle");
6474 caml_leave_blocking_section();
6476 CAMLreturn(Val_unit
);
6479 CAMLprim value
caml_curl_multi_perform_all(value v_multi
)
6481 CAMLparam1(v_multi
);
6482 int still_running
= 0;
6483 CURLM
* h
= CURLM_val(v_multi
);
6485 caml_enter_blocking_section();
6486 while (CURLM_CALL_MULTI_PERFORM
== curl_multi_perform(h
, &still_running
));
6487 caml_leave_blocking_section();
6489 CAMLreturn(Val_int(still_running
));
6492 CAMLprim value
helper_curl_easy_strerror(value v_code
)
6495 CAMLreturn(caml_copy_string(curl_easy_strerror(Int_val(v_code
))));
6499 * Wrappers for the curl_multi_socket_action infrastructure
6500 * Based on curl hiperfifo.c example
6505 #define Val_socket(v) win_alloc_socket(v)
6508 #error Socket_val not defined in unixsupport.h
6512 #define Socket_val(v) Long_val(v)
6515 #define Val_socket(v) Val_int(v)
6519 static void raise_error(char const* msg
)
6521 static value
* exception
= NULL
;
6523 if (NULL
== exception
)
6525 exception
= caml_named_value("Curl.Multi.Error");
6526 if (NULL
== exception
) caml_invalid_argument("Curl.Multi.Error");
6529 caml_raise_with_string(*exception
, msg
);
6532 static void check_mcode(CURLMcode code
)
6534 char const *s
= NULL
;
6537 case CURLM_OK
: return;
6538 case CURLM_CALL_MULTI_PERFORM
: s
="CURLM_CALL_MULTI_PERFORM"; break;
6539 case CURLM_BAD_HANDLE
: s
="CURLM_BAD_HANDLE"; break;
6540 case CURLM_BAD_EASY_HANDLE
: s
="CURLM_BAD_EASY_HANDLE"; break;
6541 case CURLM_OUT_OF_MEMORY
: s
="CURLM_OUT_OF_MEMORY"; break;
6542 case CURLM_INTERNAL_ERROR
: s
="CURLM_INTERNAL_ERROR"; break;
6543 case CURLM_UNKNOWN_OPTION
: s
="CURLM_UNKNOWN_OPTION"; break;
6544 case CURLM_LAST
: s
="CURLM_LAST"; break;
6545 case CURLM_BAD_SOCKET
: s
="CURLM_BAD_SOCKET"; break;
6546 default : s
="CURLM_unknown"; break;
6551 CAMLprim value
caml_curl_multi_socket_action(value v_multi
, value v_fd
, value v_kind
)
6553 CAMLparam3(v_multi
, v_fd
, v_kind
);
6554 CURLM
* h
= CURLM_val(v_multi
);
6555 int still_running
= 0;
6556 CURLMcode rc
= CURLM_OK
;
6557 curl_socket_t socket
;
6560 if (Val_none
== v_fd
)
6562 socket
= CURL_SOCKET_TIMEOUT
;
6566 socket
= Socket_val(Field(v_fd
, 0));
6569 switch (Int_val(v_kind
))
6572 case 1 : kind
|= CURL_CSELECT_IN
; break;
6573 case 2 : kind
|= CURL_CSELECT_OUT
; break;
6574 case 3 : kind
|= CURL_CSELECT_IN
| CURL_CSELECT_OUT
; break;
6576 raise_error("caml_curl_multi_socket_action");
6579 /* fprintf(stdout,"fd %u kind %u\n",socket, kind); fflush(stdout); */
6581 caml_enter_blocking_section();
6583 rc
= curl_multi_socket_action(h
, socket
, kind
, &still_running
);
6584 } while (rc
== CURLM_CALL_MULTI_PERFORM
);
6585 caml_leave_blocking_section();
6589 CAMLreturn(Val_int(still_running
));
6592 CAMLprim value
caml_curl_multi_socket_all(value v_multi
)
6594 CAMLparam1(v_multi
);
6595 int still_running
= 0;
6596 CURLMcode rc
= CURLM_OK
;
6597 CURLM
* h
= CURLM_val(v_multi
);
6599 caml_enter_blocking_section();
6601 rc
= curl_multi_socket_all(h
, &still_running
);
6602 } while (rc
== CURLM_CALL_MULTI_PERFORM
);
6603 caml_leave_blocking_section();
6607 CAMLreturn(Val_int(still_running
));
6610 static int curlm_sock_cb_nolock(CURL
*e
, curl_socket_t sock
, int what
, ml_multi_handle
* multi
, void *sockp
)
6613 CAMLlocal2(v_what
,csock
);
6615 (void)sockp
; /* not used */
6617 /* v_what = Val_int(what); */
6620 case CURL_POLL_NONE
: v_what
= Val_int(0); break;
6621 case CURL_POLL_IN
: v_what
= Val_int(1); break;
6622 case CURL_POLL_OUT
: v_what
= Val_int(2); break;
6623 case CURL_POLL_INOUT
: v_what
= Val_int(3); break;
6624 case CURL_POLL_REMOVE
: v_what
= Val_int(4); break;
6626 fprintf(stderr
, "curlm_sock_cb sock=%d what=%d\n", sock
, what
);
6628 raise_error("curlm_sock_cb"); /* FIXME exception from callback */
6630 csock
=Val_socket(sock
);
6631 caml_callback2(Field(multi
->values
,curlmopt_socket_function
),
6637 static int curlm_sock_cb(CURL
*e
, curl_socket_t sock
, int what
, void *cbp
, void *sockp
)
6640 caml_leave_blocking_section();
6641 ret
= curlm_sock_cb_nolock(e
, sock
, what
, (ml_multi_handle
*)cbp
, sockp
);
6642 caml_enter_blocking_section();
6646 CAMLprim value
caml_curl_multi_socketfunction(value v_multi
, value v_cb
)
6648 CAMLparam2(v_multi
, v_cb
);
6649 ml_multi_handle
* multi
= Multi_val(v_multi
);
6651 Store_field(multi
->values
, curlmopt_socket_function
, v_cb
);
6653 curl_multi_setopt(multi
->handle
, CURLMOPT_SOCKETFUNCTION
, curlm_sock_cb
);
6654 curl_multi_setopt(multi
->handle
, CURLMOPT_SOCKETDATA
, multi
);
6656 CAMLreturn(Val_unit
);
6659 static void curlm_timer_cb_nolock(ml_multi_handle
*multi
, long timeout_ms
)
6662 caml_callback(Field(multi
->values
,curlmopt_timer_function
), Val_long(timeout_ms
));
6666 static int curlm_timer_cb(CURLM
*multi
, long timeout_ms
, void *userp
)
6670 caml_leave_blocking_section();
6671 curlm_timer_cb_nolock((ml_multi_handle
*)userp
, timeout_ms
);
6672 caml_enter_blocking_section();
6676 CAMLprim value
caml_curl_multi_timerfunction(value v_multi
, value v_cb
)
6678 CAMLparam2(v_multi
, v_cb
);
6679 ml_multi_handle
* multi
= Multi_val(v_multi
);
6681 Store_field(multi
->values
, curlmopt_timer_function
, v_cb
);
6683 curl_multi_setopt(multi
->handle
, CURLMOPT_TIMERFUNCTION
, curlm_timer_cb
);
6684 curl_multi_setopt(multi
->handle
, CURLMOPT_TIMERDATA
, multi
);
6686 CAMLreturn(Val_unit
);
6689 CAMLprim value
caml_curl_multi_timeout(value v_multi
)
6691 CAMLparam1(v_multi
);
6693 CURLMcode rc
= CURLM_OK
;
6694 ml_multi_handle
* multi
= Multi_val(v_multi
);
6696 rc
= curl_multi_timeout(multi
->handle
, &ms
);
6700 CAMLreturn(Val_long(ms
));