use -Wall
[ocurl.git] / curl-helper.c
blobe583f12c1a4886eb54ef0e52af55fd4dae28ae69
1 /***
2 *** curl-helper.c
3 ***
4 *** Copyright (c) 2003-2008, Lars Nilsson, <lars@quantumchamaeleon.com>
5 ***/
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <stdarg.h>
11 #include <curl/curl.h>
13 #include <caml/alloc.h>
14 #include <caml/memory.h>
15 #include <caml/mlvalues.h>
16 #include <caml/callback.h>
17 #include <caml/fail.h>
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #else
22 #warning "No config file given."
23 #endif
25 void leave_blocking_section(void);
26 void enter_blocking_section(void);
28 #define Val_none Val_int(0)
30 static inline value
31 Val_some( value v )
33 CAMLparam1( v );
34 CAMLlocal1( some );
35 some = caml_alloc(1, 0);
36 Store_field( some, 0, v );
37 CAMLreturn( some );
40 typedef struct Connection Connection;
41 typedef struct ConnectionList ConnectionList;
43 #define Connection_val(v) ((Connection *)Field(v, 0))
45 enum OcamlValues
47 OcamlWriteCallback,
48 OcamlReadCallback,
49 OcamlErrorBuffer,
50 OcamlPostFields,
51 OcamlHTTPHeader,
52 OcamlHTTPPost,
53 OcamlQuote,
54 OcamlPostQuote,
55 OcamlHeaderCallback,
56 OcamlProgressCallback,
57 OcamlPasswdCallback,
58 OcamlDebugCallback,
59 OcamlHTTP200Aliases,
60 OcamlIOCTLCallback,
61 OcamlSeekFunctionCallback,
63 OcamlURL,
64 OcamlProxy,
65 OcamlUserPWD,
66 OcamlProxyUserPWD,
67 OcamlRange,
68 OcamlReferer,
69 OcamlUserAgent,
70 OcamlFTPPort,
71 OcamlCookie,
72 OcamlHTTPPostStrings,
73 OcamlSSLCert,
74 OcamlSSLCertType,
75 OcamlSSLCertPasswd,
76 OcamlSSLKey,
77 OcamlSSLKeyType,
78 OcamlSSLKeyPasswd,
79 OcamlSSLEngine,
80 OcamlCookieFile,
81 OcamlCustomRequest,
82 OcamlInterface,
83 OcamlCAInfo,
84 OcamlCAPath,
85 OcamlRandomFile,
86 OcamlEGDSocket,
87 OcamlCookieJar,
88 OcamlSSLCipherList,
89 OcamlPrivate,
90 OcamlNETRCFile,
91 OcamlFTPAccount,
92 OcamlCookieList,
93 OcamlFTPAlternativeToUser,
94 OcamlSSHPublicKeyFile,
95 OcamlSSHPrivateKeyFile,
96 OcamlSSHHostPublicKeyMD5,
97 OcamlCopyPostFields,
99 /* Not used, last for size */
100 OcamlValuesSize
103 struct Connection
105 CURL *connection;
106 Connection *next;
107 Connection *prev;
109 value ocamlValues;
111 char *url;
112 char *proxy;
113 char *userPwd;
114 char *proxyUserPwd;
115 char *range;
116 char *errorBuffer;
117 char *postFields;
118 int postFieldSize;
119 char *referer;
120 char *userAgent;
121 char *ftpPort;
122 char *cookie;
123 struct curl_slist *httpHeader;
124 struct curl_httppost *httpPostFirst;
125 struct curl_httppost *httpPostLast;
126 struct curl_slist *httpPostStrings;
127 char *sslCert;
128 char *sslCertType;
129 char *sslCertPasswd;
130 char *sslKey;
131 char *sslKeyType;
132 char *sslKeyPasswd;
133 char *sslEngine;
134 struct curl_slist *quote;
135 struct curl_slist *postQuote;
136 char *cookieFile;
137 char *customRequest;
138 char *interface;
139 char *caInfo;
140 char *caPath;
141 char *randomFile;
142 char *egdSocket;
143 char *cookieJar;
144 char *sslCipherList;
145 char *private;
146 struct curl_slist *http200Aliases;
147 char *netrcFile;
148 char *ftpaccount;
149 char *cookielist;
150 char *ftpAlternativeToUser;
151 char *sshPublicKeyFile;
152 char *sshPrivateKeyFile;
153 char *sshHostPublicKeyMD5;
154 char *copyPostFields;
157 struct ConnectionList
159 Connection *head;
160 Connection *tail;
163 static ConnectionList connectionList = {NULL, NULL};
165 typedef struct CURLErrorMapping CURLErrorMapping;
167 struct CURLErrorMapping
169 char *name;
170 CURLcode error;
173 CURLErrorMapping errorMap[] =
175 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
176 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL},
177 #else
178 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
179 #endif
180 #if HAVE_DECL_CURLE_FAILED_INIT
181 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT},
182 #else
183 {"CURLE_FAILED_INIT", -1},
184 #endif
185 #if HAVE_DECL_CURLE_URL_MALFORMAT
186 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT},
187 #else
188 {"CURLE_URL_MALFORMAT", -1},
189 #endif
190 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
191 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER},
192 #else
193 {"CURLE_URL_MALFORMAT_USER", -1},
194 #endif
195 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
196 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY},
197 #else
198 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
199 #endif
200 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
201 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST},
202 #else
203 {"CURLE_COULDNT_RESOLVE_HOST", -1},
204 #endif
205 #if HAVE_DECL_CURLE_COULDNT_CONNECT
206 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT},
207 #else
208 {"CURLE_COULDNT_CONNECT", -1},
209 #endif
210 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
211 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY},
212 #else
213 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
214 #endif
215 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
216 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED},
217 #else
218 {"CURLE_FTP_ACCESS_DENIED", -1},
219 #endif
220 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
221 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT},
222 #else
223 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
224 #endif
225 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
226 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY},
227 #else
228 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
229 #endif
230 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
231 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY},
232 #else
233 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
234 #endif
235 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
236 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY},
237 #else
238 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
239 #endif
240 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
241 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT},
242 #else
243 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
244 #endif
245 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
246 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST},
247 #else
248 {"CURLE_FTP_CANT_GET_HOST", -1},
249 #endif
250 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
251 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT},
252 #else
253 {"CURLE_FTP_CANT_RECONNECT", -1},
254 #endif
255 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
256 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY},
257 #else
258 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
259 #endif
260 #if HAVE_DECL_CURLE_PARTIAL_FILE
261 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE},
262 #else
263 {"CURLE_PARTIAL_FILE", -1},
264 #endif
265 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
266 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE},
267 #else
268 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
269 #endif
270 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
271 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR},
272 #else
273 {"CURLE_FTP_WRITE_ERROR", -1},
274 #endif
275 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
276 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR},
277 #else
278 {"CURLE_FTP_QUOTE_ERROR", -1},
279 #endif
280 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
281 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND},
282 #else
283 {"CURLE_HTTP_NOT_FOUND", -1},
284 #endif
285 #if HAVE_DECL_CURLE_WRITE_ERROR
286 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR},
287 #else
288 {"CURLE_WRITE_ERROR", -1},
289 #endif
290 #if HAVE_DECL_CURLE_MALFORMAT_USER
291 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER},
292 #else
293 {"CURLE_MALFORMAT_USER", -1},
294 #endif
295 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
296 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE},
297 #else
298 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
299 #endif
300 #if HAVE_DECL_CURLE_READ_ERROR
301 {"CURLE_READ_ERROR", CURLE_READ_ERROR},
302 #else
303 {"CURLE_READ_ERROR", -1},
304 #endif
305 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
306 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY},
307 #else
308 {"CURLE_OUT_OF_MEMORY", -1},
309 #endif
310 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
311 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED},
312 #else
313 {"CURLE_OPERATION_TIMEOUTED", -1},
314 #endif
315 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
316 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII},
317 #else
318 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
319 #endif
320 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
321 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED},
322 #else
323 {"CURLE_FTP_PORT_FAILED", -1},
324 #endif
325 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
326 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST},
327 #else
328 {"CURLE_FTP_COULDNT_USE_REST", -1},
329 #endif
330 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
331 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE},
332 #else
333 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
334 #endif
335 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
336 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR},
337 #else
338 {"CURLE_HTTP_RANGE_ERROR", -1},
339 #endif
340 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
341 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR},
342 #else
343 {"CURLE_HTTP_POST_ERROR", -1},
344 #endif
345 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
346 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR},
347 #else
348 {"CURLE_SSL_CONNECT_ERROR", -1},
349 #endif
350 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
351 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME},
352 #else
353 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
354 #endif
355 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
356 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE},
357 #else
358 {"CURLE_FILE_COULDNT_READ_FILE", -1},
359 #endif
360 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
361 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND},
362 #else
363 {"CURLE_LDAP_CANNOT_BIND", -1},
364 #endif
365 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
366 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED},
367 #else
368 {"CURLE_LDAP_SEARCH_FAILED", -1},
369 #endif
370 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
371 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND},
372 #else
373 {"CURLE_LIBRARY_NOT_FOUND", -1},
374 #endif
375 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
376 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND},
377 #else
378 {"CURLE_FUNCTION_NOT_FOUND", -1},
379 #endif
380 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
381 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK},
382 #else
383 {"CURLE_ABORTED_BY_CALLBACK", -1},
384 #endif
385 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
386 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT},
387 #else
388 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
389 #endif
390 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
391 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER},
392 #else
393 {"CURLE_BAD_CALLING_ORDER", -1},
394 #endif
395 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
396 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED},
397 #else
398 {"CURLE_HTTP_PORT_FAILED", -1},
399 #endif
400 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
401 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED},
402 #else
403 {"CURLE_BAD_PASSWORD_ENTERED", -1},
404 #endif
405 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
406 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS},
407 #else
408 {"CURLE_TOO_MANY_REDIRECTS", -1},
409 #endif
410 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
411 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION},
412 #else
413 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
414 #endif
415 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
416 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX},
417 #else
418 {"CURLE_TELNET_OPTION_SYNTAX", -1},
419 #endif
420 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
421 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE},
422 #else
423 {"CURLE_SSL_PEER_CERTIFICATE", -1},
424 #endif
425 #if HAVE_DECL_CURLE_GOT_NOTHING
426 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING},
427 #else
428 {"CURLE_GOT_NOTHING", -1},
429 #endif
430 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
431 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND},
432 #else
433 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
434 #endif
435 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
436 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED},
437 #else
438 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
439 #endif
440 #if HAVE_DECL_CURLE_SEND_ERROR
441 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR},
442 #else
443 {"CURLE_SEND_ERROR", -1},
444 #endif
445 #if HAVE_DECL_CURLE_RECV_ERROR
446 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR},
447 #else
448 {"CURLE_RECV_ERROR", -1},
449 #endif
450 #if HAVE_DECL_CURLE_SHARE_IN_USE
451 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE},
452 #else
453 {"CURLE_SHARE_IN_USE", -1},
454 #endif
455 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
456 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM},
457 #else
458 {"CURLE_SSL_CERTPROBLEN", -1},
459 #endif
460 #if HAVE_DECL_CURLE_SSL_CIPHER
461 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER},
462 #else
463 {"CURLE_SSL_CIPHER", -1},
464 #endif
465 #if HAVE_DECL_CURLE_SSL_CACERT
466 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT},
467 #else
468 {"CURLE_SSL_CACERT", -1},
469 #endif
470 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
471 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING},
472 #else
473 {"CURLE_BAD_CONTENT_ENCODING", -1},
474 #endif
475 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
476 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL},
477 #else
478 {"CURLE_LDAP_INVALID_URL", -1},
479 #endif
480 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
481 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED},
482 #else
483 {"CURLE_FILESIZE_EXCEEDED", -1},
484 #endif
485 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
486 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED},
487 #else
488 {"CURLE_FTP_SSL_FAILED", -1},
489 #endif
490 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
491 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND},
492 #else
493 {"CURLE_SEND_FAIL_REWIND", -1},
494 #endif
495 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
496 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED},
497 #else
498 {"CURLE_SSL_ENGINE_INITFAILED", -1},
499 #endif
500 #if HAVE_DECL_CURLE_LOGIN_DENIED
501 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED},
502 #else
503 {"CURLE_LOGIN_DENIED", -1},
504 #endif
505 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
506 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND},
507 #else
508 {"CURLE_TFTP_NOTFOUND", -1},
509 #endif
510 #if HAVE_DECL_CURLE_TFTP_PERM
511 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM},
512 #else
513 {"CURLE_TFTP_PERM", -1},
514 #endif
515 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
516 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL},
517 #else
518 {"CURLE_REMOTE_DISK_FULL", -1},
519 #endif
520 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
521 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL},
522 #else
523 {"CURLE_TFTP_ILLEGAL", -1},
524 #endif
525 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
526 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID},
527 #else
528 {"CURLE_TFTP_UNKNOWNID", -1},
529 #endif
530 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
531 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS},
532 #else
533 {"CURLE_REMOTE_FILE_EXISTS", -1},
534 #endif
535 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
536 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER},
537 #else
538 {"CURLE_TFTP_NOSUCHUSER", -1},
539 #endif
540 #if HAVE_DECL_CURLE_CONV_FAILED
541 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED},
542 #else
543 {"CURLE_CONV_FAILED", -1},
544 #endif
545 #if HAVE_DECL_CURLE_CONV_REQUIRED
546 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED},
547 #else
548 {"CURLE_CONV_REQUIRED", -1},
549 #endif
550 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
551 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE},
552 #else
553 {"CURLE_SSL_CACERT_BADFILE", -1},
554 #endif
555 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
556 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND},
557 #else
558 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
559 #endif
560 #if HAVE_DECL_CURLE_SSH
561 {"CURLE_SSH", CURLE_SSH},
562 #else
563 {"CURLE_SSH", -1},
564 #endif
565 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
566 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED},
567 #else
568 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
569 #endif
570 #if HAVE_DECL_CURLE_AGAIN
571 {"CURLE_AGAIN", CURLE_AGAIN},
572 #else
573 {"CURLE_AGAIN", -1},
574 #endif
575 {"CURLE_OK", CURLE_OK},
576 {NULL, 0}
579 typedef struct CURLOptionMapping CURLOptionMapping;
581 struct CURLOptionMapping
583 void (*optionHandler)(Connection *, value);
584 char *name;
585 CURLoption option;
588 CURLOptionMapping unimplementedOptionMap[] =
590 {NULL, "CURLOPT_STDERR", CURLOPT_STDERR},
591 {NULL, NULL, 0}
594 static void handleWriteFunction(Connection *, value);
595 static void handleReadFunction(Connection *, value);
596 static void handleInFileSize(Connection *, value);
597 static void handleURL(Connection *, value);
598 static void handleProxy(Connection *, value);
599 static void handleProxyPort(Connection *, value);
600 static void handleHTTPProxyTunnel(Connection *, value);
601 static void handleVerbose(Connection *, value);
602 static void handleHeader(Connection *, value);
603 static void handleNoProgress(Connection *, value);
604 static void handleNoSignal(Connection *, value);
605 static void handleNoBody(Connection *, value);
606 static void handleFailOnError(Connection *, value);
607 static void handleUpload(Connection *, value);
608 static void handlePost(Connection *, value);
609 static void handleFTPListOnly(Connection *, value);
610 static void handleFTPAppend(Connection *, value);
611 static void handleNETRC(Connection *, value);
612 static void handleEncoding(Connection *, value);
613 static void handleFollowLocation(Connection *, value);
614 static void handleTransferText(Connection *, value);
615 static void handlePut(Connection *, value);
616 static void handleUserPwd(Connection *, value);
617 static void handleProxyUserPwd(Connection *, value);
618 static void handleRange(Connection *, value);
619 static void handleErrorBuffer(Connection *, value);
620 static void handleTimeout(Connection *, value);
621 static void handlePostFields(Connection *, value);
622 static void handlePostFieldSize(Connection *, value);
623 static void handleReferer(Connection *, value);
624 static void handleUserAgent(Connection *, value);
625 static void handleFTPPort(Connection *, value);
626 static void handleLowSpeedLimit(Connection *, value);
627 static void handleLowSpeedTime(Connection *, value);
628 static void handleResumeFrom(Connection *, value);
629 static void handleCookie(Connection *, value);
630 static void handleHTTPHeader(Connection *, value);
631 static void handleHTTPPost(Connection *, value);
632 static void handleSSLCert(Connection *, value);
633 static void handleSSLCertType(Connection *, value);
634 static void handleSSLCertPasswd(Connection *, value);
635 static void handleSSLKey(Connection *, value);
636 static void handleSSLKeyType(Connection *, value);
637 static void handleSSLKeyPasswd(Connection *, value);
638 static void handleSSLEngine(Connection *, value);
639 static void handleSSLEngineDefault(Connection *, value);
640 static void handleCRLF(Connection *, value);
641 static void handleQuote(Connection *, value);
642 static void handlePostQuote(Connection *, value);
643 static void handleHeaderFunction(Connection *, value);
644 static void handleCookieFile(Connection *, value);
645 static void handleSSLVersion(Connection *, value);
646 static void handleTimeCondition(Connection *, value);
647 static void handleTimeValue(Connection *, value);
648 static void handleCustomRequest(Connection *, value);
649 static void handleInterface(Connection *, value);
650 static void handleKRB4Level(Connection *, value);
651 static void handleProgressFunction(Connection *, value);
652 static void handleSSLVerifyPeer(Connection *, value);
653 static void handleCAInfo(Connection *, value);
654 static void handleCAPath(Connection *, value);
655 static void handlePasswdFunction(Connection *, value);
656 static void handleFileTime(Connection *, value);
657 static void handleMaxRedirs(Connection *, value);
658 static void handleMaxConnects(Connection *, value);
659 static void handleClosePolicy(Connection *, value);
660 static void handleFreshConnect(Connection *, value);
661 static void handleForbidReuse(Connection *, value);
662 static void handleRandomFile(Connection *, value);
663 static void handleEGDSocket(Connection *, value);
664 static void handleConnectTimeout(Connection *, value);
665 static void handleHTTPGet(Connection *, value);
666 static void handleSSLVerifyHost(Connection *, value);
667 static void handleCookieJar(Connection *, value);
668 static void handleSSLCipherList(Connection *, value);
669 static void handleHTTPVersion(Connection *, value);
670 static void handleFTPUseEPSV(Connection *, value);
671 static void handleDNSCacheTimeout(Connection *, value);
672 static void handleDNSUseGlobalCache(Connection *, value);
673 static void handleDebugFunction(Connection *, value);
674 static void handlePrivate(Connection *, value);
675 static void handleHTTP200Aliases(Connection *, value);
676 static void handleUnrestrictedAuth(Connection *, value);
677 static void handleFTPUseEPRT(Connection *, value);
678 static void handleHTTPAuth(Connection *, value);
679 static void handleFTPCreateMissingDirs(Connection *, value);
680 static void handleProxyAuth(Connection *, value);
681 static void handleFTPResponseTimeout(Connection *, value);
682 static void handleIPResolve(Connection *, value);
683 static void handleMaxFileSize(Connection *, value);
684 static void handleInFileSizeLarge(Connection *, value);
685 static void handleResumeFromLarge(Connection *, value);
686 static void handleMaxFileSizeLarge(Connection *, value);
687 static void handleNETRCFile(Connection *, value);
688 static void handleFTPSSL(Connection *, value);
689 static void handlePostFieldSizeLarge(Connection *, value);
690 static void handleTCPNoDelay(Connection *, value);
691 static void handleFTPSSLAuth(Connection *, value);
692 static void handleIOCTLFunction(Connection *, value);
693 static void handleFTPAccount(Connection *, value);
694 static void handleCookieList(Connection *, value);
695 static void handleIgnoreContentLength(Connection *, value);
696 static void handleFTPSkipPASVIP(Connection *, value);
697 static void handleFTPFileMethod(Connection *, value);
698 static void handleLocalPort(Connection *, value);
699 static void handleLocalPortRange(Connection *, value);
700 static void handleConnectOnly(Connection *, value);
701 static void handleMaxSendSpeedLarge(Connection *, value);
702 static void handleMaxRecvSpeedLarge(Connection *, value);
703 static void handleFTPAlternativeToUser(Connection *, value);
704 static void handleSSLSessionIdCache(Connection *, value);
705 static void handleSSHAuthTypes(Connection *, value);
706 static void handleSSHPublicKeyFile(Connection *, value);
707 static void handleSSHPrivateKeyFile(Connection *, value);
708 static void handleFTPSSLCCC(Connection *, value);
709 static void handleTimeoutMS(Connection *, value);
710 static void handleConnectTimeoutMS(Connection *, value);
711 static void handleHTTPTransferDecoding(Connection *, value);
712 static void handleHTTPContentDecoding(Connection *, value);
713 static void handleNewFilePerms(Connection *, value);
714 static void handleNewDirectoryPerms(Connection *, value);
715 static void handlePost301(Connection *, value);
716 static void handleSSHHostPublicKeyMD5(Connection *, value);
717 static void handleCopyPostFields(Connection *, value);
718 static void handleProxyTransferMode(Connection *, value);
719 static void handleSeekFunction(Connection *, value);
721 CURLOptionMapping implementedOptionMap[] =
723 {handleWriteFunction, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION},
724 {handleReadFunction, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION},
725 {handleInFileSize, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE},
726 {handleURL, "CURLOPT_URL", CURLOPT_URL},
727 {handleProxy, "CURLOPT_PROXY", CURLOPT_PROXY},
728 {handleProxyPort, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT},
729 {handleHTTPProxyTunnel, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL},
730 {handleVerbose, "CURLOPT_VERBOSE", CURLOPT_VERBOSE},
731 {handleHeader, "CURLOPT_HEADER", CURLOPT_HEADER},
732 {handleNoProgress, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS},
733 #if HAVE_DECL_CURLOPT_NOSIGNAL
734 {handleNoSignal, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL},
735 #else
736 {handleNoSignal, "CURLOPT_NOSIGNAL", 0},
737 #endif
738 {handleNoBody, "CURLOPT_NOBODY", CURLOPT_NOBODY},
739 {handleFailOnError, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR},
740 {handleUpload, "CURLOPT_UPLOAD", CURLOPT_UPLOAD},
741 {handlePost, "CURLOPT_POST", CURLOPT_POST},
742 {handleFTPListOnly, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY},
743 {handleFTPAppend, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND},
744 {handleNETRC, "CURLOPT_NETRC", CURLOPT_NETRC},
745 #if HAVE_DECL_CURLOPT_ENCODING
746 {handleEncoding, "CURLOPT_ENCODING", CURLOPT_ENCODING},
747 #else
748 {handleEncoding, "CURLOPT_ENCODING", 0},
749 #endif
750 {handleFollowLocation, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION},
751 {handleTransferText, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT},
752 {handlePut, "CURLOPT_PUT", CURLOPT_PUT},
753 {handleUserPwd, "CURLOPT_USERPWD", CURLOPT_USERPWD},
754 {handleProxyUserPwd, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD},
755 {handleRange, "CURLOPT_RANGE", CURLOPT_RANGE},
756 {handleErrorBuffer, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER},
757 {handleTimeout, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT},
758 {handlePostFields, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS},
759 {handlePostFieldSize, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE},
760 {handleReferer, "CURLOPT_REFERER", CURLOPT_REFERER},
761 {handleUserAgent, "CURLOPT_USERAGENT", CURLOPT_USERAGENT},
762 {handleFTPPort, "CURLOPT_FTPPORT", CURLOPT_FTPPORT},
763 {handleLowSpeedLimit, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT},
764 {handleLowSpeedTime, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME},
765 {handleResumeFrom, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM},
766 {handleCookie, "CURLOPT_COOKIE", CURLOPT_COOKIE},
767 {handleHTTPHeader, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER},
768 {handleHTTPPost, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST},
769 {handleSSLCert, "CURLOPT_SSLCERT", CURLOPT_SSLCERT},
770 {handleSSLCertType, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE},
771 {handleSSLCertPasswd, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD},
772 {handleSSLKey, "CURLOPT_SSLKEY", CURLOPT_SSLKEY},
773 {handleSSLKeyType, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE},
774 {handleSSLKeyPasswd, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD},
775 {handleSSLEngine, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE},
776 {handleSSLEngineDefault, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT},
777 {handleCRLF, "CURLOPT_CRLF", CURLOPT_CRLF},
778 {handleQuote, "CURLOPT_QUOTE", CURLOPT_QUOTE},
779 {handlePostQuote, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE},
780 {handleHeaderFunction, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION},
781 {handleCookieFile, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE},
782 {handleSSLVersion, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION},
783 {handleTimeCondition, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION},
784 {handleTimeValue, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE},
785 {handleCustomRequest, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST},
786 {handleInterface, "CURLOPT_INTERFACE", CURLOPT_INTERFACE},
787 {handleKRB4Level, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL},
788 {handleProgressFunction, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION},
789 {handleSSLVerifyPeer, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER},
790 {handleCAInfo, "CURLOPT_CAINFO", CURLOPT_CAINFO},
791 {handleCAPath, "CURLOPT_CAPATH", CURLOPT_CAPATH},
792 {handleFileTime, "CURLOPT_FILETIME", CURLOPT_FILETIME},
793 {handleMaxRedirs, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS},
794 {handleMaxConnects, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS},
795 {handleClosePolicy, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY},
796 {handleFreshConnect, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT},
797 {handleForbidReuse, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE},
798 {handleRandomFile, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE},
799 {handleEGDSocket, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET},
800 {handleConnectTimeout, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT},
801 {handleHTTPGet, "CURLOPT_HTTPGET", CURLOPT_HTTPGET},
802 {handleSSLVerifyHost, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST},
803 {handleCookieJar, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR},
804 {handleSSLCipherList, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST},
805 {handleHTTPVersion, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION},
806 {handleFTPUseEPSV, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV},
807 {handleDNSCacheTimeout, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT},
808 {handleDNSUseGlobalCache, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE},
809 {handleDebugFunction, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION},
810 #if HAVE_DECL_CURLOPT_PRIVATE
811 {handlePrivate, "CURLOPT_PRIVATE", CURLOPT_PRIVATE},
812 #else
813 {handlePrivate, "CURLOPT_PRIVATE", 0},
814 #endif
815 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
816 {handleHTTP200Aliases, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES},
817 #else
818 {handleHTTP200Aliases, "CURLOPT_HTTP200ALIASES", 0},
819 #endif
820 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
821 {handleUnrestrictedAuth, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH},
822 #else
823 {handleUnrestrictedAuth, "CURLOPT_UNRESTRICTED_AUTH", 0},
824 #endif
825 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
826 {handleFTPUseEPRT, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT},
827 #else
828 {handleFTPUseEPRT, "CURLOPT_FTP_USE_EPRT", 0},
829 #endif
830 #if HAVE_DECL_CURLOPT_HTTPAUTH
831 {handleHTTPAuth, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH},
832 #else
833 {handleHTTPAuth, "CURLOPT_HTTPAUTH", 0},
834 #endif
835 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
836 {handleFTPCreateMissingDirs, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS},
837 #else
838 {handleFTPCreateMissingDirs, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
839 #endif
840 #if HAVE_DECL_CURLOPT_PROXYAUTH
841 {handleProxyAuth, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH},
842 #else
843 {handleProxyAuth, "CURLOPT_PROXYAUTH", 0},
844 #endif
845 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
846 {handleFTPResponseTimeout, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT},
847 #else
848 {handleFTPResponseTimeout, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
849 #endif
850 #if HAVE_DECL_CURLOPT_IPRESOLVE
851 {handleIPResolve, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE},
852 #else
853 {handleIPResolve, "CURLOPT_IPRESOLVE", 0},
854 #endif
855 #if HAVE_DECL_CURLOPT_MAXFILESIZE
856 {handleMaxFileSize, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE},
857 #else
858 {handleMaxFileSize, "CURLOPT_MAXFILESIZE", 0},
859 #endif
860 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
861 {handleInFileSizeLarge, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE},
862 #else
863 {handleInFileSizeLarge, "CURLOPT_INFILESIZE_LARGE", 0},
864 #endif
865 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
866 {handleResumeFromLarge, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE},
867 #else
868 {handleResumeFromLarge, "CURLOPT_RESUME_FROM_LARGE", 0},
869 #endif
870 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
871 {handleMaxFileSizeLarge, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE},
872 #else
873 {handleMaxFileSizeLarge, "CURLOPT_MAXFILESIZE_LARGE", 0},
874 #endif
875 #if HAVE_DECL_CURLOPT_NETRC_FILE
876 {handleNETRCFile, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE},
877 #else
878 {handleNETRCFile, "CURLOPT_NETRC_FILE", 0},
879 #endif
880 #if HAVE_DECL_CURLOPT_FTP_SSL
881 {handleFTPSSL, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL},
882 #else
883 {handleFTPSSL, "CURLOPT_FTP_SSL", 0},
884 #endif
885 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
886 {handlePostFieldSizeLarge, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE},
887 #else
888 {handlePostFieldSizeLarge, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
889 #endif
890 #if HAVE_DECL_CURLOPT_TCP_NODELAY
891 {handleTCPNoDelay, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY},
892 #else
893 {handleTCPNoDelay, "CURLOPT_TCP_NODELAY", 0},
894 #endif
895 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
896 {handleFTPSSLAuth, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH},
897 #else
898 {handleFTPSSLAuth, "CURLOPT_FTPSSLAUTH", 0},
899 #endif
900 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
901 {handleIOCTLFunction, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION},
902 #else
903 {handleIOCTLFunction, "CURLOPT_IOCTLFUNCTION", 0},
904 #endif
905 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
906 {handleFTPAccount, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT},
907 #else
908 {handleFTPAccount, "CURLOPT_FTP_ACCOUNT", 0},
909 #endif
910 #if HAVE_DECL_CURLOPT_COOKIELIST
911 {handleCookieList, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST},
912 #else
913 {handleCookieList, "CURLOPT_COOKIELIST", 0},
914 #endif
915 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
916 {handleIgnoreContentLength, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH},
917 #else
918 {handleIgnoreContentLength, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
919 #endif
920 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
921 {handleFTPSkipPASVIP, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP},
922 #else
923 {handleFTPSkipPASVIP, "CURLOPT_FTP_SKIP_PASV_IP", 0},
924 #endif
925 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
926 {handleFTPFileMethod, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD},
927 #else
928 {handleFTPFileMethod, "CURLOPT_FTP_FILEMETHOD", 0},
929 #endif
930 #if HAVE_DECL_CURLOPT_LOCALPORT
931 {handleLocalPort, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT},
932 #else
933 {handleLocalPort, "CURLOPT_LOCALPORT", 0},
934 #endif
935 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
936 {handleLocalPortRange, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE},
937 #else
938 {handleLocalPortRange, "CURLOPT_LOCALPORTRANGE", 0},
939 #endif
940 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
941 {handleConnectOnly, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY},
942 #else
943 {handleConnectOnly, "CURLOPT_CONNECT_ONLY", 0},
944 #endif
945 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
946 {handleMaxSendSpeedLarge, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE},
947 #else
948 {handleMaxSendSpeedLarge, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
949 #endif
950 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
951 {handleMaxRecvSpeedLarge, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE},
952 #else
953 {handleMaxRecvSpeedLarge, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
954 #endif
955 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
956 {handleFTPAlternativeToUser, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER},
957 #else
958 {handleFTPAlternativeToUser, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
959 #endif
960 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
961 {handleSSLSessionIdCache, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE},
962 #else
963 {handleSSLSessionIdCache, "CURLOPT_SSL_SESSIONID_CACHE", 0},
964 #endif
965 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
966 {handleSSHAuthTypes, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES},
967 #else
968 {handleSSHAuthTypes, "CURLOPT_SSH_AUTH_TYPES", 0},
969 #endif
970 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
971 {handleSSHPublicKeyFile, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE},
972 #else
973 {handleSSHPublicKeyFile, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
974 #endif
975 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
976 {handleSSHPrivateKeyFile, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE},
977 #else
978 {handleSSHPrivateKeyFile, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
979 #endif
980 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
981 {handleFTPSSLCCC, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC},
982 #else
983 {handleFTPSSLCCC, "CURLOPT_FTP_SSL_CCC", 0},
984 #endif
985 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
986 {handleTimeoutMS, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS},
987 #else
988 {handleTimeoutMS, "CURLOPT_TIMEOUT_MS", 0},
989 #endif
990 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
991 {handleConnectTimeoutMS, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS},
992 #else
993 {handleConnectTimeoutMS, "CURLOPT_CONNECTTIMEOUT_MS", 0},
994 #endif
995 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
996 {handleHTTPTransferDecoding, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING},
997 #else
998 {handleHTTPTransferDecoding, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
999 #endif
1000 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1001 {handleHTTPContentDecoding, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING},
1002 #else
1003 {handleHTTPContentDecoding, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1004 #endif
1005 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1006 {handleNewFilePerms, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS},
1007 #else
1008 {handleNewFilePerms, "CURLOPT_NEW_FILE_PERMS", 0},
1009 #endif
1010 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1011 {handleNewDirectoryPerms, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS},
1012 #else
1013 {handleNewDirectoryPerms, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1014 #endif
1015 #if HAVE_DECL_CURLOPT_POST301
1016 {handlePost301, "CURLOPT_POST301", CURLOPT_POST301},
1017 #else
1018 {handlePost301, "CURLOPT_POST301", 0},
1019 #endif
1020 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1021 {handleSSHHostPublicKeyMD5, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5},
1022 #else
1023 {handleSSHHostPublicKeyMD5, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1024 #endif
1025 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1026 {handleCopyPostFields, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS},
1027 #else
1028 {handleCopyPostFields, "CURLOPT_COPYPOSTFIELDS", 0},
1029 #endif
1030 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1031 {handleProxyTransferMode, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE},
1032 #else
1033 {handleProxyTransferMode, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1034 #endif
1035 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1036 {handleSeekFunction, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION},
1037 #else
1038 {handleSeekFunction, "CURLOPT_SEEKFUNCTION", 0},
1039 #endif
1042 static char *findOption(CURLOptionMapping optionMap[],
1043 CURLoption option)
1045 return optionMap[option].name;
1048 static void free_curl_slist(struct curl_slist *slist)
1050 struct curl_slist *item;
1052 if (slist == NULL)
1053 return;
1055 item = slist;
1057 while (item != NULL)
1059 free(item->data);
1060 item->data = NULL;
1061 item = item->next;
1064 curl_slist_free_all(slist);
1067 static void raiseError(Connection *conn, CURLcode code)
1069 CAMLparam0();
1070 CAMLlocal1(exceptionData);
1071 value *exception;
1072 char *errorString = "Unknown Error";
1073 int i;
1075 for (i = 0; errorMap[i].name != NULL; i++)
1077 if (errorMap[i].error == code)
1079 errorString = errorMap[i].name;
1080 break;
1084 exceptionData = alloc(3, 0);
1086 Field(exceptionData, 0) = Val_int(code);
1087 Field(exceptionData, 1) = Val_int(code);
1088 Field(exceptionData, 2) = copy_string(errorString);
1090 if (conn != NULL && conn->errorBuffer != NULL)
1092 Field(Field(conn->ocamlValues, OcamlErrorBuffer), 0) =
1093 copy_string(conn->errorBuffer);
1096 exception = caml_named_value("CurlException");
1098 if (exception == NULL)
1099 failwith(errorString);
1101 raise_with_arg(*exception, exceptionData);
1103 CAMLreturn0;
1106 static Connection *newConnection(void)
1108 Connection *connection;
1109 int i;
1111 connection = (Connection *)malloc(sizeof(Connection));
1113 enter_blocking_section();
1114 connection->connection = curl_easy_init();
1115 leave_blocking_section();
1117 connection->next = NULL;
1118 connection->prev = NULL;
1120 if (connectionList.tail == NULL)
1122 connectionList.tail = connection;
1123 connectionList.head = connection;
1125 else
1127 connection->prev = connectionList.head;
1128 connectionList.head->next = connection;
1129 connectionList.head = connection;
1132 connection->ocamlValues = alloc(OcamlValuesSize, 0);
1133 for (i = 0; i < OcamlValuesSize; i++)
1134 Store_field(connection->ocamlValues, i, Val_unit);
1136 register_global_root(&connection->ocamlValues);
1138 connection->url = NULL;
1139 connection->proxy = NULL;
1140 connection->userPwd = NULL;
1141 connection->proxyUserPwd = NULL;
1142 connection->range = NULL;
1143 connection->errorBuffer = NULL;
1144 connection->postFields = NULL;
1145 connection->postFieldSize = -1;
1146 connection->referer = NULL;
1147 connection->userAgent = NULL;
1148 connection->ftpPort = NULL;
1149 connection->cookie = NULL;
1150 connection->httpHeader = NULL;
1151 connection->httpPostFirst = NULL;
1152 connection->httpPostLast = NULL;
1153 connection->httpPostStrings = NULL;
1154 connection->sslCert = NULL;
1155 connection->sslCertType = NULL;
1156 connection->sslCertPasswd = NULL;
1157 connection->sslKey = NULL;
1158 connection->sslKeyType = NULL;
1159 connection->sslKeyPasswd = NULL;
1160 connection->sslEngine = NULL;
1161 connection->quote = NULL;
1162 connection->postQuote = NULL;
1163 connection->cookieFile = NULL;
1164 connection->customRequest = NULL;
1165 connection->interface = NULL;
1166 connection->caInfo = NULL;
1167 connection->caPath = NULL;
1168 connection->randomFile = NULL;
1169 connection->egdSocket = NULL;
1170 connection->cookieJar = NULL;
1171 connection->sslCipherList = NULL;
1172 connection->private = NULL;
1173 connection->http200Aliases = NULL;
1174 connection->netrcFile = NULL;
1175 connection->ftpaccount = NULL;
1176 connection->cookielist = NULL;
1177 connection->ftpAlternativeToUser = NULL;
1178 connection->sshPublicKeyFile = NULL;
1179 connection->sshPrivateKeyFile = NULL;
1180 connection->copyPostFields = NULL;
1182 return connection;
1185 static Connection *duplicateConnection(Connection *original)
1187 Connection *connection;
1188 int i;
1190 connection = (Connection *)malloc(sizeof(Connection));
1192 enter_blocking_section();
1193 connection->connection = curl_easy_duphandle(original->connection);
1194 leave_blocking_section();
1196 connection->next = NULL;
1197 connection->prev = NULL;
1199 if (connectionList.tail == NULL)
1201 connectionList.tail = connection;
1202 connectionList.head = connection;
1204 else
1206 connection->prev = connectionList.head;
1207 connectionList.head->next = connection;
1208 connectionList.head = connection;
1211 connection->ocamlValues = alloc(OcamlValuesSize, 0);
1212 for (i = 0; i < OcamlValuesSize; i++)
1213 Store_field(connection->ocamlValues, i, Val_unit);
1215 register_global_root(&connection->ocamlValues);
1217 Store_field(connection->ocamlValues, OcamlWriteCallback,
1218 Field(original->ocamlValues, OcamlWriteCallback));
1219 Store_field(connection->ocamlValues, OcamlReadCallback,
1220 Field(original->ocamlValues, OcamlReadCallback));
1221 Store_field(connection->ocamlValues, OcamlErrorBuffer,
1222 Field(original->ocamlValues, OcamlErrorBuffer));
1223 Store_field(connection->ocamlValues, OcamlPostFields,
1224 Field(original->ocamlValues, OcamlPostFields));
1225 Store_field(connection->ocamlValues, OcamlHTTPHeader,
1226 Field(original->ocamlValues, OcamlHTTPHeader));
1227 Store_field(connection->ocamlValues, OcamlQuote,
1228 Field(original->ocamlValues, OcamlQuote));
1229 Store_field(connection->ocamlValues, OcamlPostQuote,
1230 Field(original->ocamlValues, OcamlPostQuote));
1231 Store_field(connection->ocamlValues, OcamlHeaderCallback,
1232 Field(original->ocamlValues, OcamlHeaderCallback));
1233 Store_field(connection->ocamlValues, OcamlProgressCallback,
1234 Field(original->ocamlValues, OcamlProgressCallback));
1235 Store_field(connection->ocamlValues, OcamlPasswdCallback,
1236 Field(original->ocamlValues, OcamlPasswdCallback));
1237 Store_field(connection->ocamlValues, OcamlDebugCallback,
1238 Field(original->ocamlValues, OcamlDebugCallback));
1239 Store_field(connection->ocamlValues, OcamlHTTP200Aliases,
1240 Field(original->ocamlValues, OcamlHTTP200Aliases));
1241 Store_field(connection->ocamlValues, OcamlIOCTLCallback,
1242 Field(original->ocamlValues, OcamlIOCTLCallback));
1243 Store_field(connection->ocamlValues, OcamlSeekFunctionCallback,
1244 Field(original->ocamlValues, OcamlSeekFunctionCallback));
1246 connection->url = NULL;
1247 connection->proxy = NULL;
1248 connection->userPwd = NULL;
1249 connection->proxyUserPwd = NULL;
1250 connection->range = NULL;
1251 connection->errorBuffer = NULL;
1252 connection->postFields = NULL;
1253 connection->postFieldSize = -1;
1254 connection->referer = NULL;
1255 connection->userAgent = NULL;
1256 connection->ftpPort = NULL;
1257 connection->cookie = NULL;
1258 connection->httpHeader = NULL;
1259 connection->httpPostFirst = NULL;
1260 connection->httpPostLast = NULL;
1261 connection->httpPostStrings = NULL;
1262 connection->sslCert = NULL;
1263 connection->sslCertType = NULL;
1264 connection->sslCertPasswd = NULL;
1265 connection->sslKey = NULL;
1266 connection->sslKeyType = NULL;
1267 connection->sslKeyPasswd = NULL;
1268 connection->sslEngine = NULL;
1269 connection->quote = NULL;
1270 connection->postQuote = NULL;
1271 connection->cookieFile = NULL;
1272 connection->customRequest = NULL;
1273 connection->interface = NULL;
1274 connection->caInfo = NULL;
1275 connection->caPath = NULL;
1276 connection->randomFile = NULL;
1277 connection->egdSocket = NULL;
1278 connection->cookieJar = NULL;
1279 connection->sslCipherList = NULL;
1280 connection->private = NULL;
1281 connection->http200Aliases = NULL;
1282 connection->netrcFile = NULL;
1283 connection->ftpaccount = NULL;
1284 connection->cookielist = NULL;
1285 connection->sshPublicKeyFile = NULL;
1286 connection->sshPrivateKeyFile = NULL;
1287 connection->copyPostFields = NULL;
1289 if (Field(original->ocamlValues, OcamlURL) != Val_unit)
1290 handleURL(connection, Field(original->ocamlValues,
1291 OcamlURL));
1292 if (Field(original->ocamlValues, OcamlProxy) != Val_unit)
1293 handleProxy(connection, Field(original->ocamlValues,
1294 OcamlProxy));
1295 if (Field(original->ocamlValues, OcamlUserPWD) != Val_unit)
1296 handleUserPwd(connection, Field(original->ocamlValues,
1297 OcamlUserPWD));
1298 if (Field(original->ocamlValues, OcamlProxyUserPWD) != Val_unit)
1299 handleProxyUserPwd(connection, Field(original->ocamlValues,
1300 OcamlProxyUserPWD));
1301 if (Field(original->ocamlValues, OcamlRange) != Val_unit)
1302 handleRange(connection, Field(original->ocamlValues,
1303 OcamlRange));
1304 if (Field(original->ocamlValues, OcamlErrorBuffer) != Val_unit)
1305 handleErrorBuffer(connection, Field(original->ocamlValues,
1306 OcamlErrorBuffer));
1307 if (Field(original->ocamlValues, OcamlPostFields) != Val_unit)
1308 handlePostFields(connection, Field(original->ocamlValues,
1309 OcamlPostFields));
1310 if (Field(original->ocamlValues, OcamlReferer) != Val_unit)
1311 handleReferer(connection, Field(original->ocamlValues,
1312 OcamlReferer));
1313 if (Field(original->ocamlValues, OcamlUserAgent) != Val_unit)
1314 handleUserAgent(connection, Field(original->ocamlValues,
1315 OcamlUserAgent));
1316 if (Field(original->ocamlValues, OcamlFTPPort) != Val_unit)
1317 handleFTPPort(connection, Field(original->ocamlValues,
1318 OcamlFTPPort));
1319 if (Field(original->ocamlValues, OcamlCookie) != Val_unit)
1320 handleCookie(connection, Field(original->ocamlValues,
1321 OcamlCookie));
1322 if (Field(original->ocamlValues, OcamlHTTPHeader) != Val_unit)
1323 handleHTTPHeader(connection, Field(original->ocamlValues,
1324 OcamlHTTPHeader));
1325 if (Field(original->ocamlValues, OcamlHTTPPost) != Val_unit)
1326 handleHTTPPost(connection, Field(original->ocamlValues,
1327 OcamlHTTPPost));
1328 if (Field(original->ocamlValues, OcamlSSLCert) != Val_unit)
1329 handleSSLCert(connection, Field(original->ocamlValues,
1330 OcamlSSLCert));
1331 if (Field(original->ocamlValues, OcamlSSLCertType) != Val_unit)
1332 handleSSLCertType(connection, Field(original->ocamlValues,
1333 OcamlSSLCertType));
1334 if (Field(original->ocamlValues, OcamlSSLCertPasswd) != Val_unit)
1335 handleSSLCertPasswd(connection, Field(original->ocamlValues,
1336 OcamlSSLCertPasswd));
1337 if (Field(original->ocamlValues, OcamlSSLKey) != Val_unit)
1338 handleSSLKey(connection, Field(original->ocamlValues,
1339 OcamlSSLKey));
1340 if (Field(original->ocamlValues, OcamlSSLKeyType) != Val_unit)
1341 handleSSLKeyType(connection, Field(original->ocamlValues,
1342 OcamlSSLKeyType));
1343 if (Field(original->ocamlValues, OcamlSSLKeyPasswd) != Val_unit)
1344 handleSSLKeyPasswd(connection, Field(original->ocamlValues,
1345 OcamlSSLKeyPasswd));
1346 if (Field(original->ocamlValues, OcamlSSLEngine) != Val_unit)
1347 handleSSLEngine(connection, Field(original->ocamlValues,
1348 OcamlSSLEngine));
1349 if (Field(original->ocamlValues, OcamlQuote) != Val_unit)
1350 handleQuote(connection, Field(original->ocamlValues,
1351 OcamlQuote));
1352 if (Field(original->ocamlValues, OcamlPostQuote) != Val_unit)
1353 handlePostQuote(connection, Field(original->ocamlValues,
1354 OcamlPostQuote));
1355 if (Field(original->ocamlValues, OcamlCookieFile) != Val_unit)
1356 handleCookieFile(connection, Field(original->ocamlValues,
1357 OcamlCookieFile));
1358 if (Field(original->ocamlValues, OcamlCustomRequest) != Val_unit)
1359 handleCustomRequest(connection, Field(original->ocamlValues,
1360 OcamlCustomRequest));
1361 if (Field(original->ocamlValues, OcamlInterface) != Val_unit)
1362 handleInterface(connection, Field(original->ocamlValues,
1363 OcamlInterface));
1364 if (Field(original->ocamlValues, OcamlCAInfo) != Val_unit)
1365 handleCAInfo(connection, Field(original->ocamlValues,
1366 OcamlCAInfo));
1367 if (Field(original->ocamlValues, OcamlCAPath) != Val_unit)
1368 handleCAPath(connection, Field(original->ocamlValues,
1369 OcamlCAPath));
1370 if (Field(original->ocamlValues, OcamlRandomFile) != Val_unit)
1371 handleRandomFile(connection, Field(original->ocamlValues,
1372 OcamlRandomFile));
1373 if (Field(original->ocamlValues, OcamlEGDSocket) != Val_unit)
1374 handleEGDSocket(connection, Field(original->ocamlValues,
1375 OcamlEGDSocket));
1376 if (Field(original->ocamlValues, OcamlCookieJar) != Val_unit)
1377 handleCookieJar(connection, Field(original->ocamlValues,
1378 OcamlCookieJar));
1379 if (Field(original->ocamlValues, OcamlSSLCipherList) != Val_unit)
1380 handleSSLCipherList(connection, Field(original->ocamlValues,
1381 OcamlSSLCipherList));
1382 if (Field(original->ocamlValues, OcamlPrivate) != Val_unit)
1383 handlePrivate(connection, Field(original->ocamlValues,
1384 OcamlPrivate));
1385 if (Field(original->ocamlValues, OcamlHTTP200Aliases) != Val_unit)
1386 handleHTTP200Aliases(connection, Field(original->ocamlValues,
1387 OcamlHTTP200Aliases));
1388 if (Field(original->ocamlValues, OcamlNETRCFile) != Val_unit)
1389 handleNETRCFile(connection, Field(original->ocamlValues,
1390 OcamlNETRCFile));
1391 if (Field(original->ocamlValues, OcamlFTPAccount) != Val_unit)
1392 handleFTPAccount(connection, Field(original->ocamlValues,
1393 OcamlFTPAccount));
1394 if (Field(original->ocamlValues, OcamlCookieList) != Val_unit)
1395 handleCookieList(connection, Field(original->ocamlValues,
1396 OcamlCookieList));
1397 if (Field(original->ocamlValues, OcamlFTPAlternativeToUser) != Val_unit)
1398 handleFTPAlternativeToUser(connection,
1399 Field(original->ocamlValues,
1400 OcamlFTPAlternativeToUser));
1401 if (Field(original->ocamlValues, OcamlSSHPublicKeyFile) != Val_unit)
1402 handleSSHPublicKeyFile(connection,
1403 Field(original->ocamlValues,
1404 OcamlSSHPublicKeyFile));
1405 if (Field(original->ocamlValues, OcamlSSHPrivateKeyFile) != Val_unit)
1406 handleSSHPrivateKeyFile(connection,
1407 Field(original->ocamlValues,
1408 OcamlSSHPrivateKeyFile));
1409 if (Field(original->ocamlValues, OcamlCopyPostFields) != Val_unit)
1410 handleCopyPostFields(connection,
1411 Field(original->ocamlValues,
1412 OcamlCopyPostFields));
1414 return connection;
1417 static void removeConnection(Connection *connection)
1419 enter_blocking_section();
1420 curl_easy_cleanup(connection->connection);
1421 leave_blocking_section();
1423 if (connectionList.tail == connection)
1424 connectionList.tail = connectionList.tail->next;
1425 if (connectionList.head == connection)
1426 connectionList.head = connectionList.head->prev;
1428 if (connection->next != NULL)
1429 connection->next->prev = connection->prev;
1430 if (connection->prev != NULL)
1431 connection->prev->next = connection->next;
1433 remove_global_root(&connection->ocamlValues);
1435 if (connection->url != NULL)
1436 free(connection->url);
1437 if (connection->proxy != NULL)
1438 free(connection->proxy);
1439 if (connection->userPwd != NULL)
1440 free(connection->userPwd);
1441 if (connection->proxyUserPwd != NULL)
1442 free(connection->proxyUserPwd);
1443 if (connection->range != NULL)
1444 free(connection->range);
1445 if (connection->errorBuffer != NULL)
1446 free(connection->range);
1447 if (connection->postFields != NULL)
1448 free(connection->postFields);
1449 if (connection->referer != NULL)
1450 free(connection->referer);
1451 if (connection->userAgent != NULL)
1452 free(connection->userAgent);
1453 if (connection->ftpPort != NULL)
1454 free(connection->ftpPort);
1455 if (connection->cookie != NULL)
1456 free(connection->cookie);
1457 if (connection->httpHeader != NULL)
1458 free_curl_slist(connection->httpHeader);
1459 if (connection->httpPostFirst != NULL)
1460 curl_formfree(connection->httpPostFirst);
1461 if (connection->httpPostStrings != NULL)
1462 free_curl_slist(connection->httpPostStrings);
1463 if (connection->sslCert != NULL)
1464 free(connection->sslCert);
1465 if (connection->sslCertType != NULL)
1466 free(connection->sslCertType);
1467 if (connection->sslCertPasswd != NULL)
1468 free(connection->sslCertPasswd);
1469 if (connection->sslKey != NULL)
1470 free(connection->sslKey);
1471 if (connection->sslKeyType != NULL)
1472 free(connection->sslKeyType);
1473 if (connection->sslKeyPasswd != NULL)
1474 free(connection->sslKeyPasswd);
1475 if (connection->sslEngine != NULL)
1476 free(connection->sslEngine);
1477 if (connection->quote != NULL)
1478 free_curl_slist(connection->quote);
1479 if (connection->postQuote != NULL)
1480 free_curl_slist(connection->postQuote);
1481 if (connection->cookieFile != NULL)
1482 free(connection->cookieFile);
1483 if (connection->customRequest != NULL)
1484 free(connection->customRequest);
1485 if (connection->interface != NULL)
1486 free(connection->interface);
1487 if (connection->caInfo != NULL)
1488 free(connection->caInfo);
1489 if (connection->caPath != NULL)
1490 free(connection->caPath);
1491 if (connection->randomFile != NULL)
1492 free(connection->randomFile);
1493 if (connection->egdSocket != NULL)
1494 free(connection->egdSocket);
1495 if (connection->cookieJar != NULL)
1496 free(connection->cookieJar);
1497 if (connection->sslCipherList != NULL)
1498 free(connection->sslCipherList);
1499 if (connection->private != NULL)
1500 free(connection->private);
1501 if (connection->http200Aliases != NULL)
1502 free_curl_slist(connection->http200Aliases);
1503 if (connection->netrcFile != NULL)
1504 free(connection->netrcFile);
1505 if (connection->ftpaccount != NULL)
1506 free(connection->ftpaccount);
1507 if (connection->cookielist != NULL)
1508 free(connection->cookielist);
1509 if (connection->ftpAlternativeToUser != NULL)
1510 free(connection->ftpAlternativeToUser);
1511 if (connection->sshPublicKeyFile != NULL)
1512 free(connection->sshPublicKeyFile);
1513 if (connection->sshPrivateKeyFile != NULL)
1514 free(connection->sshPrivateKeyFile);
1515 if (connection->copyPostFields != NULL)
1516 free(connection->copyPostFields);
1518 free(connection);
1521 static void checkConnection(Connection *connection)
1523 Connection *listIter;
1525 listIter = connectionList.tail;
1527 while (listIter != NULL)
1529 if (listIter == connection)
1530 return;
1532 listIter = listIter->next;
1535 failwith("Invalid Connection");
1538 static Connection* findConnection(CURL* h)
1540 Connection *listIter;
1542 listIter = connectionList.tail;
1544 while (listIter != NULL)
1546 if (listIter->connection == h)
1547 return listIter;
1549 listIter = listIter->next;
1552 failwith("Unknown handle");
1555 #define WRAP_DATA_CALLBACK(f) \
1556 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1558 size_t result;\
1559 leave_blocking_section();\
1560 result = f##_nolock(ptr,size,nmemb,data);\
1561 enter_blocking_section();\
1562 return result;\
1565 static size_t writeFunction_nolock(char *ptr, size_t size, size_t nmemb, void *data)
1567 CAMLparam0();
1568 CAMLlocal2(result, str);
1569 Connection *conn = (Connection *)data;
1570 int i;
1572 checkConnection(conn);
1574 str = alloc_string(size*nmemb);
1576 for (i = 0; i < size*nmemb; i++)
1577 Byte(str, i) = ptr[i];
1579 result = callback(Field(conn->ocamlValues, OcamlWriteCallback), str);
1581 CAMLreturnT(size_t, Int_val(result));
1584 WRAP_DATA_CALLBACK(writeFunction)
1586 static size_t readFunction_nolock(void *ptr, size_t size, size_t nmemb, void *data)
1588 CAMLparam0();
1589 CAMLlocal1(result);
1590 Connection *conn = (Connection *)data;
1591 int length;
1593 checkConnection(conn);
1595 result = callback(Field(conn->ocamlValues, OcamlReadCallback),
1596 Val_int(size*nmemb));
1598 length = string_length(result);
1600 if (length >= size*nmemb)
1601 length = size*nmemb;
1603 memcpy(ptr, String_val(result), length);
1605 CAMLreturnT(size_t,length);
1608 WRAP_DATA_CALLBACK(readFunction)
1610 static size_t headerFunction_nolock(char *ptr, size_t size, size_t nmemb, void *data)
1612 CAMLparam0();
1613 CAMLlocal2(result,str);
1614 Connection *conn = (Connection *)data;
1615 int i;
1617 checkConnection(conn);
1619 str = alloc_string(size*nmemb);
1621 for (i = 0; i < size*nmemb; i++)
1622 Byte(str, i) = ptr[i];
1624 result = callback(Field(conn->ocamlValues, OcamlHeaderCallback), str);
1626 CAMLreturnT(size_t, Int_val(result));
1629 WRAP_DATA_CALLBACK(headerFunction)
1631 static int progressFunction_nolock(void *data,
1632 double dlTotal,
1633 double dlNow,
1634 double ulTotal,
1635 double ulNow)
1637 CAMLparam0();
1638 CAMLlocal1(result);
1639 CAMLlocalN(callbackData, 4);
1640 Connection *conn = (Connection *)data;
1642 checkConnection(conn);
1644 callbackData[0] = copy_double(dlTotal);
1645 callbackData[1] = copy_double(dlNow);
1646 callbackData[2] = copy_double(ulTotal);
1647 callbackData[3] = copy_double(ulNow);
1649 result = callbackN(Field(conn->ocamlValues, OcamlProgressCallback),
1650 4, callbackData);
1652 CAMLreturnT(int, Bool_val(result));
1655 static int progressFunction(void *data,
1656 double dlTotal,
1657 double dlNow,
1658 double ulTotal,
1659 double ulNow)
1661 int r;
1662 leave_blocking_section();
1663 r = progressFunction_nolock(data,dlTotal,dlNow,ulTotal,ulNow);
1664 enter_blocking_section();
1665 return r;
1668 static int passwdFunction_nolock(void *data,
1669 char *prompt,
1670 char *buffer,
1671 int bufferLength)
1673 CAMLparam0();
1674 CAMLlocal2(ocamlPasswd, ocamlPrompt);
1675 int length;
1676 Connection *conn = (Connection *)data;
1678 checkConnection(conn);
1680 ocamlPrompt = copy_string(prompt);
1682 ocamlPasswd = callback2(Field(conn->ocamlValues, OcamlPasswdCallback),
1683 ocamlPrompt,
1684 Val_long(bufferLength));
1686 if (Wosize_val(ocamlPasswd) != 2)
1688 return 1;
1691 length = string_length(Field(ocamlPasswd, 1));
1692 if (length > bufferLength - 1)
1693 length = bufferLength - 1;
1695 memcpy(buffer, String_val(Field(ocamlPasswd, 0)), length);
1697 buffer[length] = 0;
1699 CAMLreturnT(int, !(Bool_val(Field(ocamlPasswd, 0))));
1702 static int passwdFunction(void *data,
1703 char *prompt,
1704 char *buffer,
1705 int bufferLength)
1707 int r;
1708 leave_blocking_section();
1709 r = passwdFunction_nolock(data,prompt,buffer,bufferLength);
1710 enter_blocking_section();
1711 return r;
1714 static int debugFunction_nolock(CURL *debugConnection,
1715 curl_infotype infoType,
1716 char *buffer,
1717 size_t bufferLength,
1718 void *data)
1720 CAMLparam0();
1721 CAMLlocal3(camlDebugConnection, camlInfoType, camlMessage);
1722 int i;
1723 Connection *conn = (Connection *)data;
1725 checkConnection(conn);
1727 camlDebugConnection = (value)conn;
1728 camlInfoType = Val_long(infoType);
1729 camlMessage = alloc_string(bufferLength);
1731 for (i = 0; i < bufferLength; i++)
1732 Byte(camlMessage, i) = buffer[i];
1734 callback3(Field(conn->ocamlValues, OcamlDebugCallback),
1735 camlDebugConnection,
1736 camlInfoType,
1737 camlMessage);
1739 CAMLreturnT(int, 0);
1742 static int debugFunction(CURL *debugConnection,
1743 curl_infotype infoType,
1744 char *buffer,
1745 size_t bufferLength,
1746 void *data)
1748 int r;
1749 leave_blocking_section();
1750 r = debugFunction_nolock(debugConnection, infoType, buffer, bufferLength, data);
1751 enter_blocking_section();
1752 return r;
1755 static curlioerr ioctlFunction_nolock(CURL *ioctl,
1756 int cmd,
1757 void *data)
1759 CAMLparam0();
1760 CAMLlocal3(camlResult, camlConnection, camlCmd);
1761 Connection *conn = (Connection *)data;
1762 curlioerr result = CURLIOE_OK;
1764 checkConnection(conn);
1766 if (cmd == CURLIOCMD_NOP)
1767 camlCmd = Val_long(0);
1768 else if (cmd == CURLIOCMD_RESTARTREAD)
1769 camlCmd = Val_long(1);
1770 else
1771 failwith("Invalid IOCTL Cmd!");
1773 camlConnection = alloc(1, Abstract_tag);
1774 Store_field(camlConnection, 0, (value)conn);
1776 camlResult = callback2(Field(conn->ocamlValues, OcamlIOCTLCallback),
1777 camlConnection,
1778 camlCmd);
1780 switch (Long_val(camlResult))
1782 case 0: /* CURLIOE_OK */
1783 result = CURLIOE_OK;
1784 break;
1786 case 1: /* CURLIOE_UNKNOWNCMD */
1787 result = CURLIOE_UNKNOWNCMD;
1788 break;
1790 case 2: /* CURLIOE_FAILRESTART */
1791 result = CURLIOE_FAILRESTART;
1792 break;
1794 default: /* Incorrect return value, but let's handle it */
1795 result = CURLIOE_FAILRESTART;
1796 break;
1799 CAMLreturnT(curlioerr, result);
1802 static curlioerr ioctlFunction(CURL *ioctl,
1803 int cmd,
1804 void *data)
1806 curlioerr r;
1807 leave_blocking_section();
1808 r = ioctlFunction_nolock(ioctl, cmd, data);
1809 enter_blocking_section();
1810 return r;
1813 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1814 static int seekFunction_nolock(void *data,
1815 curl_off_t offset,
1816 int origin)
1818 CAMLparam0();
1819 CAMLlocal3(camlResult, camlOffset, camlOrigin);
1820 Connection *conn = (Connection *)data;
1821 int result = 0;
1823 camlOffset = copy_int64(offset);
1825 if (SEEK_SET == origin)
1826 camlOrigin = Val_long(0);
1827 else if (SEEK_CUR == origin)
1828 camlOrigin = Val_long(1);
1829 else if (SEEK_END == origin)
1830 camlOrigin = Val_long(2);
1831 else
1832 camlOrigin = Val_long(0);
1834 camlResult = callback2(Field(conn->ocamlValues,
1835 OcamlSeekFunctionCallback),
1836 camlOffset,
1837 camlOrigin);
1839 result = Int_val(camlResult);
1841 CAMLreturnT(int, result);
1844 static int seekFunction(void *data,
1845 curl_off_t offset,
1846 int origin)
1848 int r;
1849 leave_blocking_section();
1850 r = seekFunction_nolock(data,offset,origin);
1851 enter_blocking_section();
1852 return r;
1855 #endif
1858 ** curl_global_init helper function
1861 CAMLprim value helper_curl_global_init(value initOption)
1863 CAMLparam1(initOption);
1865 switch (Long_val(initOption))
1867 case 0: /* CURLINIT_GLOBALALL */
1868 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL)));
1869 break;
1871 case 1: /* CURLINIT_GLOBALSSL */
1872 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL)));
1873 break;
1875 case 2: /* CURLINIT_GLOBALWIN32 */
1876 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32)));
1877 break;
1879 case 3: /* CURLINIT_GLOBALNOTHING */
1880 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING)));
1881 break;
1883 default:
1884 failwith("Invalid Initialization Option");
1885 break;
1888 CAMLreturn(Val_unit);
1892 ** curl_global_cleanup helper function
1895 CAMLprim void helper_curl_global_cleanup(void)
1897 CAMLparam0();
1899 curl_global_cleanup();
1901 CAMLreturn0;
1905 ** curl_easy_init helper function
1908 CAMLprim value helper_curl_easy_init(void)
1910 CAMLparam0();
1911 CAMLlocal1(result);
1913 Connection *conn = newConnection();
1915 result = alloc(1, Abstract_tag);
1916 Store_field(result, 0, (value)conn);
1918 CAMLreturn(result);
1922 ** curl_easy_setopt helper utility functions
1925 static void handleWriteFunction(Connection *conn, value option)
1927 CAMLparam1(option);
1928 CURLcode result = CURLE_OK;
1930 if (Tag_val(option) == Closure_tag)
1931 Store_field(conn->ocamlValues, OcamlWriteCallback, option);
1932 else
1933 failwith("Not a proper closure");
1935 result = curl_easy_setopt(conn->connection,
1936 CURLOPT_WRITEFUNCTION,
1937 writeFunction);
1939 if (result != CURLE_OK)
1940 raiseError(conn, result);
1942 result = curl_easy_setopt(conn->connection,
1943 CURLOPT_WRITEDATA,
1944 conn);
1946 if (result != CURLE_OK)
1947 raiseError(conn, result);
1949 CAMLreturn0;
1952 static void handleReadFunction(Connection *conn, value option)
1954 CAMLparam1(option);
1955 CURLcode result = CURLE_OK;
1957 if (Tag_val(option) == Closure_tag)
1958 Store_field(conn->ocamlValues, OcamlReadCallback, option);
1959 else
1960 failwith("Not a proper closure");
1962 result = curl_easy_setopt(conn->connection,
1963 CURLOPT_READFUNCTION,
1964 readFunction);
1966 if (result != CURLE_OK)
1967 raiseError(conn, result);
1969 result = curl_easy_setopt(conn->connection,
1970 CURLOPT_READDATA,
1971 conn);
1973 if (result != CURLE_OK)
1974 raiseError(conn, result);
1976 CAMLreturn0;
1979 static void handleURL(Connection *conn, value option)
1981 CAMLparam1(option);
1982 CURLcode result = CURLE_OK;
1984 Store_field(conn->ocamlValues, OcamlURL, option);
1986 if (conn->url != NULL)
1987 free(conn->url);
1989 conn->url = strdup(String_val(option));
1991 result = curl_easy_setopt(conn->connection,
1992 CURLOPT_URL,
1993 conn->url);
1995 if (result != CURLE_OK)
1996 raiseError(conn, result);
1998 CAMLreturn0;
2001 static void handleInFileSize(Connection *conn, value option)
2003 CAMLparam1(option);
2004 CURLcode result = CURLE_OK;
2006 result = curl_easy_setopt(conn->connection,
2007 CURLOPT_INFILESIZE,
2008 Long_val(option));
2010 if (result != CURLE_OK)
2011 raiseError(conn, result);
2013 CAMLreturn0;
2016 static void handleProxy(Connection *conn, value option)
2018 CAMLparam1(option);
2019 CURLcode result = CURLE_OK;
2021 Store_field(conn->ocamlValues, OcamlProxy, option);
2023 if (conn->proxy != NULL)
2024 free(conn->proxy);
2026 conn->proxy = strdup(String_val(option));
2028 result = curl_easy_setopt(conn->connection,
2029 CURLOPT_PROXY,
2030 conn->proxy);
2032 if (result != CURLE_OK)
2033 raiseError(conn, result);
2035 CAMLreturn0;
2038 static void handleProxyPort(Connection *conn, value option)
2040 CAMLparam1(option);
2041 CURLcode result = CURLE_OK;
2043 result = curl_easy_setopt(conn->connection,
2044 CURLOPT_PROXYPORT,
2045 Long_val(option));
2047 if (result != CURLE_OK)
2048 raiseError(conn, result);
2050 CAMLreturn0;
2053 static void handleHTTPProxyTunnel(Connection *conn, value option)
2055 CAMLparam1(option);
2056 CURLcode result = CURLE_OK;
2058 result = curl_easy_setopt(conn->connection,
2059 CURLOPT_HTTPPROXYTUNNEL,
2060 Bool_val(option));
2062 if (result != CURLE_OK)
2063 raiseError(conn, result);
2065 CAMLreturn0;
2068 static void handleVerbose(Connection *conn, value option)
2070 CAMLparam1(option);
2071 CURLcode result = CURLE_OK;
2073 result = curl_easy_setopt(conn->connection,
2074 CURLOPT_VERBOSE,
2075 Bool_val(option));
2077 if (result != CURLE_OK)
2078 raiseError(conn, result);
2080 CAMLreturn0;
2083 static void handleHeader(Connection *conn, value option)
2085 CAMLparam1(option);
2086 CURLcode result = CURLE_OK;
2088 result = curl_easy_setopt(conn->connection,
2089 CURLOPT_HEADER,
2090 Bool_val(option));
2092 if (result != CURLE_OK)
2093 raiseError(conn, result);
2095 CAMLreturn0;
2098 static void handleNoProgress(Connection *conn, value option)
2100 CAMLparam1(option);
2101 CURLcode result = CURLE_OK;
2103 result = curl_easy_setopt(conn->connection,
2104 CURLOPT_NOPROGRESS,
2105 Bool_val(option));
2107 if (result != CURLE_OK)
2108 raiseError(conn, result);
2110 CAMLreturn0;
2113 static void handleNoSignal(Connection *conn, value option)
2115 #if HAVE_DECL_CURLOPT_NOSIGNAL
2116 CAMLparam1(option);
2117 CURLcode result = CURLE_OK;
2119 result = curl_easy_setopt(conn->connection,
2120 CURLOPT_NOSIGNAL,
2121 Bool_val(option));
2123 if (result != CURLE_OK)
2124 raiseError(conn, result);
2126 CAMLreturn0;
2127 #else
2128 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2129 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2130 #endif
2133 static void handleNoBody(Connection *conn, value option)
2135 CAMLparam1(option);
2136 CURLcode result = CURLE_OK;
2138 result = curl_easy_setopt(conn->connection,
2139 CURLOPT_NOBODY,
2140 Bool_val(option));
2142 if (result != CURLE_OK)
2143 raiseError(conn, result);
2145 CAMLreturn0;
2148 static void handleFailOnError(Connection *conn, value option)
2150 CAMLparam1(option);
2151 CURLcode result = CURLE_OK;
2153 result = curl_easy_setopt(conn->connection,
2154 CURLOPT_FAILONERROR,
2155 Bool_val(option));
2157 if (result != CURLE_OK)
2158 raiseError(conn, result);
2160 CAMLreturn0;
2163 static void handleUpload(Connection *conn, value option)
2165 CAMLparam1(option);
2166 CURLcode result = CURLE_OK;
2168 result = curl_easy_setopt(conn->connection,
2169 CURLOPT_UPLOAD,
2170 Bool_val(option));
2172 if (result != CURLE_OK)
2173 raiseError(conn, result);
2175 CAMLreturn0;
2178 static void handlePost(Connection *conn, value option)
2180 CAMLparam1(option);
2181 CURLcode result = CURLE_OK;
2183 result = curl_easy_setopt(conn->connection,
2184 CURLOPT_POST,
2185 Bool_val(option));
2187 if (result != CURLE_OK)
2188 raiseError(conn, result);
2190 CAMLreturn0;
2193 static void handleFTPListOnly(Connection *conn, value option)
2195 CAMLparam1(option);
2196 CURLcode result = CURLE_OK;
2198 result = curl_easy_setopt(conn->connection,
2199 CURLOPT_FTPLISTONLY,
2200 Bool_val(option));
2202 if (result != CURLE_OK)
2203 raiseError(conn, result);
2205 CAMLreturn0;
2208 static void handleFTPAppend(Connection *conn, value option)
2210 CAMLparam1(option);
2211 CURLcode result = CURLE_OK;
2213 result = curl_easy_setopt(conn->connection,
2214 CURLOPT_FTPAPPEND,
2215 Bool_val(option));
2217 if (result != CURLE_OK)
2218 raiseError(conn, result);
2220 CAMLreturn0;
2223 static void handleNETRC(Connection *conn, value option)
2225 CAMLparam1(option);
2226 CURLcode result = CURLE_OK;
2227 long netrc;
2229 switch (Long_val(option))
2231 case 0: /* CURL_NETRC_OPTIONAL */
2232 netrc = CURL_NETRC_OPTIONAL;
2233 break;
2235 case 1:/* CURL_NETRC_IGNORED */
2236 netrc = CURL_NETRC_IGNORED;
2237 break;
2239 case 2: /* CURL_NETRC_REQUIRED */
2240 netrc = CURL_NETRC_REQUIRED;
2241 break;
2243 default:
2244 failwith("Invalid NETRC Option");
2245 break;
2248 result = curl_easy_setopt(conn->connection,
2249 CURLOPT_NETRC,
2250 netrc);
2252 if (result != CURLE_OK)
2253 raiseError(conn, result);
2255 CAMLreturn0;
2258 static void handleEncoding(Connection *conn, value option)
2260 #if HAVE_DECL_CURLOPT_ENCODING
2261 CAMLparam1(option);
2262 CURLcode result = CURLE_OK;
2264 switch (Long_val(option))
2266 case 0: /* CURL_ENCODING_NONE */
2267 result = curl_easy_setopt(conn->connection,
2268 CURLOPT_ENCODING,
2269 "identity");
2270 break;
2272 case 1: /* CURL_ENCODING_DEFLATE */
2273 result = curl_easy_setopt(conn->connection,
2274 CURLOPT_ENCODING,
2275 "deflate");
2276 break;
2278 default:
2279 failwith("Invalid Encoding Option");
2280 break;
2283 if (result != CURLE_OK)
2284 raiseError(conn, result);
2286 CAMLreturn0;
2287 #else
2288 #warning "libcurl does not implement CURLOPT_ENCODING"
2289 failwith("libcurl does not implement CURLOPT_ENCODING");
2290 #endif
2293 static void handleFollowLocation(Connection *conn, value option)
2295 CAMLparam1(option);
2296 CURLcode result = CURLE_OK;
2298 result = curl_easy_setopt(conn->connection,
2299 CURLOPT_FOLLOWLOCATION,
2300 Bool_val(option));
2302 if (result != CURLE_OK)
2303 raiseError(conn, result);
2305 CAMLreturn0;
2308 static void handleTransferText(Connection *conn, value option)
2310 CAMLparam1(option);
2311 CURLcode result = CURLE_OK;
2313 result = curl_easy_setopt(conn->connection,
2314 CURLOPT_TRANSFERTEXT,
2315 Bool_val(option));
2317 if (result != CURLE_OK)
2318 raiseError(conn, result);
2320 CAMLreturn0;
2323 static void handlePut(Connection *conn, value option)
2325 CAMLparam1(option);
2326 CURLcode result = CURLE_OK;
2328 result = curl_easy_setopt(conn->connection,
2329 CURLOPT_PUT,
2330 Bool_val(option));
2332 if (result != CURLE_OK)
2333 raiseError(conn, result);
2335 CAMLreturn0;
2338 static void handleUserPwd(Connection *conn, value option)
2340 CAMLparam1(option);
2341 CURLcode result = CURLE_OK;
2343 Store_field(conn->ocamlValues, OcamlUserPWD, option);
2345 if (conn->userPwd != NULL)
2346 free(conn->userPwd);
2348 conn->userPwd = strdup(String_val(option));
2350 result = curl_easy_setopt(conn->connection,
2351 CURLOPT_USERPWD,
2352 conn->userPwd);
2354 if (result != CURLE_OK)
2355 raiseError(conn, result);
2357 CAMLreturn0;
2360 static void handleProxyUserPwd(Connection *conn, value option)
2362 CAMLparam1(option);
2363 CURLcode result = CURLE_OK;
2365 Store_field(conn->ocamlValues, OcamlProxyUserPWD, option);
2367 if (conn->proxyUserPwd != NULL)
2368 free(conn->proxyUserPwd);
2370 conn->proxyUserPwd = strdup(String_val(option));
2372 result = curl_easy_setopt(conn->connection,
2373 CURLOPT_PROXYUSERPWD,
2374 conn->proxyUserPwd);
2376 if (result != CURLE_OK)
2377 raiseError(conn, result);
2379 CAMLreturn0;
2382 static void handleRange(Connection *conn, value option)
2384 CAMLparam1(option);
2385 CURLcode result = CURLE_OK;
2387 Store_field(conn->ocamlValues, OcamlRange, option);
2389 if (conn->range != NULL)
2390 free(conn->range);
2392 conn->range = strdup(String_val(option));
2394 result = curl_easy_setopt(conn->connection,
2395 CURLOPT_RANGE,
2396 conn->range);
2398 if (result != CURLE_OK)
2399 raiseError(conn, result);
2401 CAMLreturn0;
2404 static void handleErrorBuffer(Connection *conn, value option)
2406 CAMLparam1(option);
2407 CURLcode result = CURLE_OK;
2409 Store_field(conn->ocamlValues, OcamlErrorBuffer, option);
2411 if (conn->errorBuffer != NULL)
2412 free(conn->errorBuffer);
2414 conn->errorBuffer = malloc(sizeof(char) * CURL_ERROR_SIZE);
2416 result = curl_easy_setopt(conn->connection,
2417 CURLOPT_ERRORBUFFER,
2418 conn->errorBuffer);
2420 if (result != CURLE_OK)
2421 raiseError(conn, result);
2423 CAMLreturn0;
2426 static void handleTimeout(Connection *conn, value option)
2428 CAMLparam1(option);
2429 CURLcode result = CURLE_OK;
2431 result = curl_easy_setopt(conn->connection,
2432 CURLOPT_TIMEOUT,
2433 Long_val(option));
2435 if (result != CURLE_OK)
2436 raiseError(conn, result);
2438 CAMLreturn0;
2441 static void handlePostFields(Connection *conn, value option)
2443 CAMLparam1(option);
2444 CURLcode result = CURLE_OK;
2446 Store_field(conn->ocamlValues, OcamlPostFields, option);
2448 if (conn->postFields != NULL)
2449 free(conn->postFields);
2451 conn->postFields = malloc(string_length(option)+1);
2452 memcpy(conn->postFields, String_val(option), string_length(option));
2454 result = curl_easy_setopt(conn->connection,
2455 CURLOPT_POSTFIELDS,
2456 conn->postFields);
2458 if (result != CURLE_OK)
2459 raiseError(conn, result);
2461 CAMLreturn0;
2464 static void handlePostFieldSize(Connection *conn, value option)
2466 CAMLparam1(option);
2467 CURLcode result = CURLE_OK;
2469 result = curl_easy_setopt(conn->connection,
2470 CURLOPT_POSTFIELDSIZE,
2471 Long_val(option));
2473 if (result != CURLE_OK)
2474 raiseError(conn, result);
2476 CAMLreturn0;
2479 static void handleReferer(Connection *conn, value option)
2481 CAMLparam1(option);
2482 CURLcode result = CURLE_OK;
2484 Store_field(conn->ocamlValues, OcamlReferer, option);
2486 if (conn->referer != NULL)
2487 free(conn->referer);
2489 conn->referer = strdup(String_val(option));
2491 result = curl_easy_setopt(conn->connection,
2492 CURLOPT_REFERER,
2493 conn->referer);
2495 if (result != CURLE_OK)
2496 raiseError(conn, result);
2498 CAMLreturn0;
2501 static void handleUserAgent(Connection *conn, value option)
2503 CAMLparam1(option);
2504 CURLcode result = CURLE_OK;
2506 Store_field(conn->ocamlValues, OcamlUserAgent, option);
2508 if (conn->userAgent != NULL)
2509 free(conn->userAgent);
2511 conn->userAgent = strdup(String_val(option));
2513 result = curl_easy_setopt(conn->connection,
2514 CURLOPT_USERAGENT,
2515 conn->userAgent);
2517 if (result != CURLE_OK)
2518 raiseError(conn, result);
2520 CAMLreturn0;
2523 static void handleFTPPort(Connection *conn, value option)
2525 CAMLparam1(option);
2526 CURLcode result = CURLE_OK;
2528 Store_field(conn->ocamlValues, OcamlFTPPort, option);
2530 if (conn->ftpPort != NULL)
2531 free(conn->ftpPort);
2533 conn->ftpPort = strdup(String_val(option));
2535 result = curl_easy_setopt(conn->connection,
2536 CURLOPT_FTPPORT,
2537 conn->ftpPort);
2539 if (result != CURLE_OK)
2540 raiseError(conn, result);
2542 CAMLreturn0;
2545 static void handleLowSpeedLimit(Connection *conn, value option)
2547 CAMLparam1(option);
2548 CURLcode result = CURLE_OK;
2550 result = curl_easy_setopt(conn->connection,
2551 CURLOPT_LOW_SPEED_LIMIT,
2552 Long_val(option));
2554 if (result != CURLE_OK)
2555 raiseError(conn, result);
2557 CAMLreturn0;
2560 static void handleLowSpeedTime(Connection *conn, value option)
2562 CAMLparam1(option);
2563 CURLcode result = CURLE_OK;
2565 result = curl_easy_setopt(conn->connection,
2566 CURLOPT_LOW_SPEED_TIME,
2567 Long_val(option));
2569 if (result != CURLE_OK)
2570 raiseError(conn, result);
2572 CAMLreturn0;
2575 static void handleResumeFrom(Connection *conn, value option)
2577 CAMLparam1(option);
2578 CURLcode result = CURLE_OK;
2580 result = curl_easy_setopt(conn->connection,
2581 CURLOPT_RESUME_FROM,
2582 Long_val(option));
2584 if (result != CURLE_OK)
2585 raiseError(conn, result);
2587 CAMLreturn0;
2590 static void handleCookie(Connection *conn, value option)
2592 CAMLparam1(option);
2593 CURLcode result = CURLE_OK;
2595 Store_field(conn->ocamlValues, OcamlCookie, option);
2597 if (conn->cookie != NULL)
2598 free(conn->cookie);
2600 conn->cookie = strdup(String_val(option));
2602 result = curl_easy_setopt(conn->connection,
2603 CURLOPT_COOKIE,
2604 conn->cookie);
2606 if (result != CURLE_OK)
2607 raiseError(conn, result);
2609 CAMLreturn0;
2612 static void handleHTTPHeader(Connection *conn, value option)
2614 CAMLparam1(option);
2615 CAMLlocal1(listIter);
2616 CURLcode result = CURLE_OK;
2617 char *str;
2619 Store_field(conn->ocamlValues, OcamlHTTPHeader, option);
2621 if (conn->httpHeader != NULL)
2622 free_curl_slist(conn->httpHeader);
2624 conn->httpHeader = NULL;
2626 listIter = option;
2628 while (!Is_long(listIter))
2630 if (Tag_val(Field(listIter, 0)) != String_tag)
2631 failwith("Not a string");
2633 str = strdup(String_val(Field(listIter, 0)));
2635 conn->httpHeader = curl_slist_append(conn->httpHeader, str);
2637 listIter = Field(listIter, 1);
2640 result = curl_easy_setopt(conn->connection,
2641 CURLOPT_HTTPHEADER,
2642 conn->httpHeader);
2644 if (result != CURLE_OK)
2645 raiseError(conn, result);
2647 CAMLreturn0;
2650 static void handleHTTPPost(Connection *conn, value option)
2652 CAMLparam1(option);
2653 CAMLlocal3(listIter, formItem, contentType);
2654 CURLcode result = CURLE_OK;
2655 char *str1, *str2, *str3, *str4;
2657 listIter = option;
2659 Store_field(conn->ocamlValues, OcamlHTTPPost, option);
2661 if (conn->httpPostFirst != NULL)
2662 curl_formfree(conn->httpPostFirst);
2664 conn->httpPostFirst = NULL;
2665 conn->httpPostLast = NULL;
2667 if (conn->httpPostStrings != NULL)
2668 free_curl_slist(conn->httpPostStrings);
2670 while (!Is_long(listIter))
2672 formItem = Field(listIter, 0);
2674 switch (Tag_val(formItem))
2676 case 0: /* CURLFORM_CONTENT */
2677 if (Wosize_val(formItem) < 3)
2679 failwith("Incorrect CURLFORM_CONTENT parameters");
2682 if (Is_long(Field(formItem, 2)) &&
2683 Long_val(Field(formItem, 2)) == 0)
2685 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2686 memcpy(str1,
2687 String_val(Field(formItem, 0)),
2688 string_length(Field(formItem, 0)));
2689 str1[string_length(Field(formItem, 0))] = 0;
2690 conn->httpPostStrings =
2691 curl_slist_append(conn->httpPostStrings, str1);
2693 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2694 memcpy(str2,
2695 String_val(Field(formItem, 1)),
2696 string_length(Field(formItem, 1)));
2697 str2[string_length(Field(formItem, 1))] = 0;
2698 conn->httpPostStrings =
2699 curl_slist_append(conn->httpPostStrings, str2);
2701 curl_formadd(&conn->httpPostFirst,
2702 &conn->httpPostLast,
2703 CURLFORM_PTRNAME,
2704 str1,
2705 CURLFORM_NAMELENGTH,
2706 string_length(Field(formItem, 0)),
2707 CURLFORM_PTRCONTENTS,
2708 str2,
2709 CURLFORM_CONTENTSLENGTH,
2710 string_length(Field(formItem, 1)),
2711 CURLFORM_END);
2713 else if (Is_block(Field(formItem, 2)))
2715 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2716 memcpy(str1,
2717 String_val(Field(formItem, 0)),
2718 string_length(Field(formItem, 0)));
2719 str1[string_length(Field(formItem, 0))] = 0;
2720 conn->httpPostStrings =
2721 curl_slist_append(conn->httpPostStrings, str1);
2723 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2724 memcpy(str2,
2725 String_val(Field(formItem, 1)),
2726 string_length(Field(formItem, 1)));
2727 str2[string_length(Field(formItem, 1))] = 0;
2728 conn->httpPostStrings =
2729 curl_slist_append(conn->httpPostStrings, str2);
2731 contentType = Field(formItem, 2);
2733 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2734 memcpy(str3,
2735 String_val(Field(contentType, 0)),
2736 string_length(Field(contentType, 0)));
2737 str3[string_length(Field(contentType, 0))] = 0;
2738 conn->httpPostStrings =
2739 curl_slist_append(conn->httpPostStrings, str3);
2741 curl_formadd(&conn->httpPostFirst,
2742 &conn->httpPostLast,
2743 CURLFORM_PTRNAME,
2744 str1,
2745 CURLFORM_NAMELENGTH,
2746 string_length(Field(formItem, 0)),
2747 CURLFORM_PTRCONTENTS,
2748 str2,
2749 CURLFORM_CONTENTSLENGTH,
2750 string_length(Field(formItem, 1)),
2751 CURLFORM_CONTENTTYPE,
2752 str3,
2753 CURLFORM_END);
2755 else
2757 failwith("Incorrect CURLFORM_CONTENT parameters");
2759 break;
2761 case 1: /* CURLFORM_FILECONTENT */
2762 if (Wosize_val(formItem) < 3)
2764 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2767 if (Is_long(Field(formItem, 2)) &&
2768 Long_val(Field(formItem, 2)) == 0)
2770 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2771 memcpy(str1,
2772 String_val(Field(formItem, 0)),
2773 string_length(Field(formItem, 0)));
2774 str1[string_length(Field(formItem, 0))] = 0;
2775 conn->httpPostStrings =
2776 curl_slist_append(conn->httpPostStrings, str1);
2778 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2779 memcpy(str2,
2780 String_val(Field(formItem, 1)),
2781 string_length(Field(formItem, 1)));
2782 str2[string_length(Field(formItem, 1))] = 0;
2783 conn->httpPostStrings =
2784 curl_slist_append(conn->httpPostStrings, str2);
2786 curl_formadd(&conn->httpPostFirst,
2787 &conn->httpPostLast,
2788 CURLFORM_PTRNAME,
2789 str1,
2790 CURLFORM_NAMELENGTH,
2791 string_length(Field(formItem, 0)),
2792 CURLFORM_FILECONTENT,
2793 str2,
2794 CURLFORM_END);
2796 else if (Is_block(Field(formItem, 2)))
2798 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2799 memcpy(str1,
2800 String_val(Field(formItem, 0)),
2801 string_length(Field(formItem, 0)));
2802 str1[string_length(Field(formItem, 0))] = 0;
2803 conn->httpPostStrings =
2804 curl_slist_append(conn->httpPostStrings, str1);
2806 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2807 memcpy(str2,
2808 String_val(Field(formItem, 1)),
2809 string_length(Field(formItem, 1)));
2810 str2[string_length(Field(formItem, 1))] = 0;
2811 conn->httpPostStrings =
2812 curl_slist_append(conn->httpPostStrings, str2);
2814 contentType = Field(formItem, 2);
2816 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2817 memcpy(str3,
2818 String_val(Field(contentType, 0)),
2819 string_length(Field(contentType, 0)));
2820 str3[string_length(Field(contentType, 0))] = 0;
2821 conn->httpPostStrings =
2822 curl_slist_append(conn->httpPostStrings, str3);
2824 curl_formadd(&conn->httpPostFirst,
2825 &conn->httpPostLast,
2826 CURLFORM_PTRNAME,
2827 str1,
2828 CURLFORM_NAMELENGTH,
2829 string_length(Field(formItem, 0)),
2830 CURLFORM_FILECONTENT,
2831 str2,
2832 CURLFORM_CONTENTTYPE,
2833 str3,
2834 CURLFORM_END);
2836 else
2838 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2840 break;
2842 case 2: /* CURLFORM_FILE */
2843 if (Wosize_val(formItem) < 3)
2845 failwith("Incorrect CURLFORM_FILE parameters");
2848 if (Is_long(Field(formItem, 2)) &&
2849 Long_val(Field(formItem, 2)) == 0)
2851 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2852 memcpy(str1,
2853 String_val(Field(formItem, 0)),
2854 string_length(Field(formItem, 0)));
2855 str1[string_length(Field(formItem, 0))] = 0;
2856 conn->httpPostStrings =
2857 curl_slist_append(conn->httpPostStrings, str1);
2859 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2860 memcpy(str2,
2861 String_val(Field(formItem, 1)),
2862 string_length(Field(formItem, 1)));
2863 str2[string_length(Field(formItem, 1))] = 0;
2864 conn->httpPostStrings =
2865 curl_slist_append(conn->httpPostStrings, str2);
2867 curl_formadd(&conn->httpPostFirst,
2868 &conn->httpPostLast,
2869 CURLFORM_PTRNAME,
2870 str1,
2871 CURLFORM_NAMELENGTH,
2872 string_length(Field(formItem, 0)),
2873 CURLFORM_FILE,
2874 str2,
2875 CURLFORM_END);
2877 else if (Is_block(Field(formItem, 2)))
2879 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2880 memcpy(str1,
2881 String_val(Field(formItem, 0)),
2882 string_length(Field(formItem, 0)));
2883 str1[string_length(Field(formItem, 0))] = 0;
2884 conn->httpPostStrings =
2885 curl_slist_append(conn->httpPostStrings, str1);
2887 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2888 memcpy(str2,
2889 String_val(Field(formItem, 1)),
2890 string_length(Field(formItem, 1)));
2891 str2[string_length(Field(formItem, 1))] = 0;
2892 conn->httpPostStrings =
2893 curl_slist_append(conn->httpPostStrings, str2);
2895 contentType = Field(formItem, 2);
2897 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2898 memcpy(str3,
2899 String_val(Field(contentType, 0)),
2900 string_length(Field(contentType, 0)));
2901 str3[string_length(Field(contentType, 0))] = 0;
2902 conn->httpPostStrings =
2903 curl_slist_append(conn->httpPostStrings, str3);
2905 curl_formadd(&conn->httpPostFirst,
2906 &conn->httpPostLast,
2907 CURLFORM_PTRNAME,
2908 str1,
2909 CURLFORM_NAMELENGTH,
2910 string_length(Field(formItem, 0)),
2911 CURLFORM_FILE,
2912 str2,
2913 CURLFORM_CONTENTTYPE,
2914 str3,
2915 CURLFORM_END);
2917 else
2919 failwith("Incorrect CURLFORM_FILE parameters");
2921 break;
2923 case 3: /* CURLFORM_BUFFER */
2924 if (Wosize_val(formItem) < 4)
2926 failwith("Incorrect CURLFORM_BUFFER parameters");
2929 if (Is_long(Field(formItem, 3)) &&
2930 Long_val(Field(formItem, 3)) == 0)
2932 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2933 memcpy(str1,
2934 String_val(Field(formItem, 0)),
2935 string_length(Field(formItem, 0)));
2936 str1[string_length(Field(formItem, 0))] = 0;
2937 conn->httpPostStrings =
2938 curl_slist_append(conn->httpPostStrings, str1);
2940 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2941 memcpy(str2,
2942 String_val(Field(formItem, 1)),
2943 string_length(Field(formItem, 1)));
2944 str2[string_length(Field(formItem, 1))] = 0;
2945 conn->httpPostStrings =
2946 curl_slist_append(conn->httpPostStrings, str2);
2948 str3 = (char *)malloc(string_length(Field(formItem, 2))+1);
2949 memcpy(str3,
2950 String_val(Field(formItem, 2)),
2951 string_length(Field(formItem, 2)));
2952 str3[string_length(Field(formItem, 2))] = 0;
2953 conn->httpPostStrings =
2954 curl_slist_append(conn->httpPostStrings, str3);
2956 curl_formadd(&conn->httpPostFirst,
2957 &conn->httpPostLast,
2958 CURLFORM_PTRNAME,
2959 str1,
2960 CURLFORM_NAMELENGTH,
2961 string_length(Field(formItem, 0)),
2962 CURLFORM_BUFFER,
2963 str2,
2964 CURLFORM_BUFFERPTR,
2965 str3,
2966 CURLFORM_BUFFERLENGTH,
2967 string_length(Field(formItem, 2)),
2968 CURLFORM_END);
2970 else if (Is_block(Field(formItem, 3)))
2972 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2973 memcpy(str1,
2974 String_val(Field(formItem, 0)),
2975 string_length(Field(formItem, 0)));
2976 str1[string_length(Field(formItem, 0))] = 0;
2977 conn->httpPostStrings =
2978 curl_slist_append(conn->httpPostStrings, str1);
2980 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2981 memcpy(str2,
2982 String_val(Field(formItem, 1)),
2983 string_length(Field(formItem, 1)));
2984 str2[string_length(Field(formItem, 1))] = 0;
2985 conn->httpPostStrings =
2986 curl_slist_append(conn->httpPostStrings, str2);
2988 str3 = (char *)malloc(string_length(Field(formItem, 2))+1);
2989 memcpy(str3,
2990 String_val(Field(formItem, 2)),
2991 string_length(Field(formItem, 2)));
2992 str3[string_length(Field(formItem, 2))] = 0;
2993 conn->httpPostStrings =
2994 curl_slist_append(conn->httpPostStrings, str3);
2996 contentType = Field(formItem, 3);
2998 str4 = (char *)malloc(string_length(Field(contentType, 0))+1);
2999 memcpy(str4,
3000 String_val(Field(contentType, 0)),
3001 string_length(Field(contentType, 0)));
3002 str4[string_length(Field(contentType, 0))] = 0;
3003 conn->httpPostStrings =
3004 curl_slist_append(conn->httpPostStrings, str4);
3006 curl_formadd(&conn->httpPostFirst,
3007 &conn->httpPostLast,
3008 CURLFORM_PTRNAME,
3009 str1,
3010 CURLFORM_NAMELENGTH,
3011 string_length(Field(formItem, 0)),
3012 CURLFORM_BUFFER,
3013 str2,
3014 CURLFORM_BUFFERPTR,
3015 str3,
3016 CURLFORM_BUFFERLENGTH,
3017 string_length(Field(formItem, 2)),
3018 CURLFORM_CONTENTTYPE,
3019 str4,
3020 CURLFORM_END);
3022 else
3024 failwith("Incorrect CURLFORM_BUFFER parameters");
3026 break;
3029 listIter = Field(listIter, 1);
3032 result = curl_easy_setopt(conn->connection,
3033 CURLOPT_HTTPPOST,
3034 conn->httpPostFirst);
3036 if (result != CURLE_OK)
3037 raiseError(conn, result);
3039 CAMLreturn0;
3042 static void handleSSLCert(Connection *conn, value option)
3044 CAMLparam1(option);
3045 CURLcode result = CURLE_OK;
3047 Store_field(conn->ocamlValues, OcamlSSLCert, option);
3049 if (conn->sslCert != NULL)
3050 free(conn->sslCert);
3052 conn->sslCert = strdup(String_val(option));
3054 result = curl_easy_setopt(conn->connection,
3055 CURLOPT_SSLCERT,
3056 conn->sslCert);
3058 if (result != CURLE_OK)
3059 raiseError(conn, result);
3061 CAMLreturn0;
3064 static void handleSSLCertType(Connection *conn, value option)
3066 CAMLparam1(option);
3067 CURLcode result = CURLE_OK;
3069 Store_field(conn->ocamlValues, OcamlSSLCertType, option);
3071 if (conn->sslCertType != NULL)
3072 free(conn->sslCertType);
3074 conn->sslCertType = strdup(String_val(option));
3076 result = curl_easy_setopt(conn->connection,
3077 CURLOPT_SSLCERTTYPE,
3078 conn->sslCertType);
3080 if (result != CURLE_OK)
3081 raiseError(conn, result);
3083 CAMLreturn0;
3086 static void handleSSLCertPasswd(Connection *conn, value option)
3088 CAMLparam1(option);
3089 CURLcode result = CURLE_OK;
3091 Store_field(conn->ocamlValues, OcamlSSLCertPasswd, option);
3093 if (conn->sslCertPasswd != NULL)
3094 free(conn->sslCertPasswd);
3096 conn->sslCertPasswd = strdup(String_val(option));
3098 result = curl_easy_setopt(conn->connection,
3099 CURLOPT_SSLCERTPASSWD,
3100 conn->sslCertPasswd);
3102 if (result != CURLE_OK)
3103 raiseError(conn, result);
3105 CAMLreturn0;
3108 static void handleSSLKey(Connection *conn, value option)
3110 CAMLparam1(option);
3111 CURLcode result = CURLE_OK;
3113 Store_field(conn->ocamlValues, OcamlSSLKey, option);
3115 if (conn->sslKey != NULL)
3116 free(conn->sslKey);
3118 conn->sslKey = strdup(String_val(option));
3120 result = curl_easy_setopt(conn->connection,
3121 CURLOPT_SSLKEY,
3122 conn->sslKey);
3124 if (result != CURLE_OK)
3125 raiseError(conn, result);
3127 CAMLreturn0;
3130 static void handleSSLKeyType(Connection *conn, value option)
3132 CAMLparam1(option);
3133 CURLcode result = CURLE_OK;
3135 Store_field(conn->ocamlValues, OcamlSSLKeyType, option);
3137 if (conn->sslKeyType != NULL)
3138 free(conn->sslKeyType);
3140 conn->sslKeyType = strdup(String_val(option));
3142 result = curl_easy_setopt(conn->connection,
3143 CURLOPT_SSLKEYTYPE,
3144 conn->sslKeyType);
3146 if (result != CURLE_OK)
3147 raiseError(conn, result);
3149 CAMLreturn0;
3152 static void handleSSLKeyPasswd(Connection *conn, value option)
3154 CAMLparam1(option);
3155 CURLcode result = CURLE_OK;
3157 Store_field(conn->ocamlValues, OcamlSSLKeyPasswd, option);
3159 if (conn->sslKeyPasswd != NULL)
3160 free(conn->sslKeyPasswd);
3162 conn->sslKeyPasswd = strdup(String_val(option));
3164 result = curl_easy_setopt(conn->connection,
3165 CURLOPT_SSLKEYPASSWD,
3166 conn->sslKeyPasswd);
3168 if (result != CURLE_OK)
3169 raiseError(conn, result);
3171 CAMLreturn0;
3174 static void handleSSLEngine(Connection *conn, value option)
3176 CAMLparam1(option);
3177 CURLcode result = CURLE_OK;
3179 Store_field(conn->ocamlValues, OcamlSSLEngine, option);
3181 if (conn->sslEngine != NULL)
3182 free(conn->sslEngine);
3184 conn->sslEngine = strdup(String_val(option));
3186 result = curl_easy_setopt(conn->connection,
3187 CURLOPT_SSLENGINE,
3188 conn->sslEngine);
3190 if (result != CURLE_OK)
3191 raiseError(conn, result);
3193 CAMLreturn0;
3196 static void handleSSLEngineDefault(Connection *conn, value option)
3198 CAMLparam1(option);
3199 CURLcode result = CURLE_OK;
3201 result = curl_easy_setopt(conn->connection,
3202 CURLOPT_SSLENGINE_DEFAULT,
3203 Bool_val(option));
3205 if (result != CURLE_OK)
3206 raiseError(conn, result);
3208 CAMLreturn0;
3211 static void handleCRLF(Connection *conn, value option)
3213 CAMLparam1(option);
3214 CURLcode result = CURLE_OK;
3216 result = curl_easy_setopt(conn->connection,
3217 CURLOPT_CRLF,
3218 Bool_val(option));
3220 if (result != CURLE_OK)
3221 raiseError(conn, result);
3223 CAMLreturn0;
3226 static void handleQuote(Connection *conn, value option)
3228 CAMLparam1(option);
3229 CAMLlocal1(listIter);
3230 CURLcode result = CURLE_OK;
3231 char *str;
3233 Store_field(conn->ocamlValues, OcamlQuote, option);
3235 if (conn->quote != NULL)
3236 free_curl_slist(conn->quote);
3238 conn->quote = NULL;
3240 listIter = option;
3242 while (!Is_long(listIter))
3244 if (Tag_val(Field(listIter, 0)) != String_tag)
3245 failwith("Not a string");
3247 str = strdup(String_val(Field(listIter, 0)));
3249 conn->quote = curl_slist_append(conn->quote, str);
3251 listIter = Field(listIter, 1);
3254 result = curl_easy_setopt(conn->connection,
3255 CURLOPT_QUOTE,
3256 conn->quote);
3258 if (result != CURLE_OK)
3259 raiseError(conn, result);
3261 CAMLreturn0;
3264 static void handlePostQuote(Connection *conn, value option)
3266 CAMLparam1(option);
3267 CAMLlocal1(listIter);
3268 CURLcode result = CURLE_OK;
3269 char *str;
3271 Store_field(conn->ocamlValues, OcamlPostQuote, option);
3273 if (conn->postQuote != NULL)
3274 free_curl_slist(conn->postQuote);
3276 conn->postQuote = NULL;
3278 listIter = option;
3280 while (!Is_long(listIter))
3282 if (Tag_val(Field(listIter, 0)) != String_tag)
3283 failwith("Not a string");
3285 str = strdup(String_val(Field(listIter, 0)));
3287 conn->postQuote = curl_slist_append(conn->postQuote, str);
3289 listIter = Field(listIter, 1);
3292 result = curl_easy_setopt(conn->connection,
3293 CURLOPT_POSTQUOTE,
3294 conn->postQuote);
3296 if (result != CURLE_OK)
3297 raiseError(conn, result);
3299 CAMLreturn0;
3302 static void handleHeaderFunction(Connection *conn, value option)
3304 CAMLparam1(option);
3305 CURLcode result = CURLE_OK;
3307 if (Tag_val(option) == Closure_tag)
3308 Store_field(conn->ocamlValues, OcamlHeaderCallback, option);
3309 else
3310 failwith("Not a proper closure");
3312 result = curl_easy_setopt(conn->connection,
3313 CURLOPT_HEADERFUNCTION,
3314 headerFunction);
3316 if (result != CURLE_OK)
3317 raiseError(conn, result);
3319 result = curl_easy_setopt(conn->connection,
3320 CURLOPT_WRITEHEADER,
3321 conn);
3323 if (result != CURLE_OK)
3324 raiseError(conn, result);
3326 CAMLreturn0;
3329 static void handleCookieFile(Connection *conn, value option)
3331 CAMLparam1(option);
3332 CURLcode result = CURLE_OK;
3334 Store_field(conn->ocamlValues, OcamlCookieFile, option);
3336 if (conn->cookieFile != NULL)
3337 free(conn->cookieFile);
3339 conn->cookieFile = strdup(String_val(option));
3341 result = curl_easy_setopt(conn->connection,
3342 CURLOPT_COOKIEFILE,
3343 conn->cookieFile);
3345 if (result != CURLE_OK)
3346 raiseError(conn, result);
3348 CAMLreturn0;
3351 static void handleSSLVersion(Connection *conn, value option)
3353 CAMLparam1(option);
3354 CURLcode result = CURLE_OK;
3356 result = curl_easy_setopt(conn->connection,
3357 CURLOPT_SSLVERSION,
3358 Long_val(option));
3360 if (result != CURLE_OK)
3361 raiseError(conn, result);
3363 CAMLreturn0;
3366 static void handleTimeCondition(Connection *conn, value option)
3368 CAMLparam1(option);
3369 CURLcode result = CURLE_OK;
3371 switch (Long_val(option))
3373 case 0: /* TIMECOND_IFMODSINCE */
3374 result = curl_easy_setopt(conn->connection,
3375 CURLOPT_TIMECONDITION,
3376 CURL_TIMECOND_IFMODSINCE);
3377 break;
3379 case 1: /* TIMECOND_IFUNMODSINCE */
3380 result = curl_easy_setopt(conn->connection,
3381 CURLOPT_TIMECONDITION,
3382 CURL_TIMECOND_IFUNMODSINCE);
3383 break;
3385 default:
3386 failwith("Invalid TIMECOND Option");
3387 break;
3390 if (result != CURLE_OK)
3391 raiseError(conn, result);
3393 CAMLreturn0;
3396 static void handleTimeValue(Connection *conn, value option)
3398 CAMLparam1(option);
3399 CURLcode result = CURLE_OK;
3401 result = curl_easy_setopt(conn->connection,
3402 CURLOPT_TIMEVALUE,
3403 Int32_val(option));
3405 if (result != CURLE_OK)
3406 raiseError(conn, result);
3408 CAMLreturn0;
3411 static void handleCustomRequest(Connection *conn, value option)
3413 CAMLparam1(option);
3414 CURLcode result = CURLE_OK;
3416 Store_field(conn->ocamlValues, OcamlCustomRequest, option);
3418 if (conn->customRequest != NULL)
3419 free(conn->customRequest);
3421 conn->customRequest = strdup(String_val(option));
3423 result = curl_easy_setopt(conn->connection,
3424 CURLOPT_CUSTOMREQUEST,
3425 conn->customRequest);
3427 if (result != CURLE_OK)
3428 raiseError(conn, result);
3430 CAMLreturn0;
3433 static void handleInterface(Connection *conn, value option)
3435 CAMLparam1(option);
3436 CURLcode result = CURLE_OK;
3438 Store_field(conn->ocamlValues, OcamlInterface, option);
3440 if (conn->interface != NULL)
3441 free(conn->interface);
3443 conn->interface = strdup(String_val(option));
3445 result = curl_easy_setopt(conn->connection,
3446 CURLOPT_INTERFACE,
3447 conn->interface);
3449 if (result != CURLE_OK)
3450 raiseError(conn, result);
3452 CAMLreturn0;
3455 static void handleKRB4Level(Connection *conn, value option)
3457 CAMLparam1(option);
3458 CURLcode result = CURLE_OK;
3460 switch (Long_val(option))
3462 case 0: /* KRB4_NONE */
3463 result = curl_easy_setopt(conn->connection,
3464 CURLOPT_KRB4LEVEL,
3465 NULL);
3466 break;
3468 case 1: /* KRB4_CLEAR */
3469 result = curl_easy_setopt(conn->connection,
3470 CURLOPT_KRB4LEVEL,
3471 "clear");
3472 break;
3474 case 2: /* KRB4_SAFE */
3475 result = curl_easy_setopt(conn->connection,
3476 CURLOPT_KRB4LEVEL,
3477 "safe");
3478 break;
3480 case 3: /* KRB4_CONFIDENTIAL */
3481 result = curl_easy_setopt(conn->connection,
3482 CURLOPT_KRB4LEVEL,
3483 "confidential");
3484 break;
3486 case 4: /* KRB4_PRIVATE */
3487 result = curl_easy_setopt(conn->connection,
3488 CURLOPT_KRB4LEVEL,
3489 "private");
3490 break;
3492 default:
3493 failwith("Invalid KRB4 Option");
3494 break;
3497 if (result != CURLE_OK)
3498 raiseError(conn, result);
3500 CAMLreturn0;
3503 static void handleProgressFunction(Connection *conn, value option)
3505 CAMLparam1(option);
3506 CURLcode result = CURLE_OK;
3508 if (Tag_val(option) == Closure_tag)
3509 Store_field(conn->ocamlValues, OcamlProgressCallback, option);
3510 else
3511 failwith("Not a proper closure");
3513 result = curl_easy_setopt(conn->connection,
3514 CURLOPT_PROGRESSFUNCTION,
3515 progressFunction);
3516 if (result != CURLE_OK)
3517 raiseError(conn, result);
3519 result = curl_easy_setopt(conn->connection,
3520 CURLOPT_PROGRESSDATA,
3521 conn);
3523 if (result != CURLE_OK)
3524 raiseError(conn, result);
3526 CAMLreturn0;
3529 static void handleSSLVerifyPeer(Connection *conn, value option)
3531 CAMLparam1(option);
3532 CURLcode result = CURLE_OK;
3534 result = curl_easy_setopt(conn->connection,
3535 CURLOPT_SSL_VERIFYPEER,
3536 Bool_val(option));
3538 if (result != CURLE_OK)
3539 raiseError(conn, result);
3541 CAMLreturn0;
3544 static void handleCAInfo(Connection *conn, value option)
3546 CAMLparam1(option);
3547 CURLcode result = CURLE_OK;
3549 Store_field(conn->ocamlValues, OcamlCAInfo, option);
3551 if (conn->caInfo != NULL)
3552 free(conn->caInfo);
3554 conn->caInfo = strdup(String_val(option));
3556 result = curl_easy_setopt(conn->connection,
3557 CURLOPT_CAINFO,
3558 conn->caInfo);
3560 if (result != CURLE_OK)
3561 raiseError(conn, result);
3563 CAMLreturn0;
3566 static void handleCAPath(Connection *conn, value option)
3568 CAMLparam1(option);
3569 CURLcode result = CURLE_OK;
3571 Store_field(conn->ocamlValues, OcamlCAPath, option);
3573 if (conn->caPath != NULL)
3574 free(conn->caPath);
3576 conn->caPath = strdup(String_val(option));
3578 result = curl_easy_setopt(conn->connection,
3579 CURLOPT_CAPATH,
3580 conn->caPath);
3582 if (result != CURLE_OK)
3583 raiseError(conn, result);
3585 CAMLreturn0;
3588 static void handleFileTime(Connection *conn, value option)
3590 CAMLparam1(option);
3591 CURLcode result = CURLE_OK;
3593 result = curl_easy_setopt(conn->connection,
3594 CURLOPT_FILETIME,
3595 Bool_val(option));
3597 if (result != CURLE_OK)
3598 raiseError(conn, result);
3600 CAMLreturn0;
3603 static void handleMaxRedirs(Connection *conn, value option)
3605 CAMLparam1(option);
3606 CURLcode result = CURLE_OK;
3608 result = curl_easy_setopt(conn->connection,
3609 CURLOPT_MAXREDIRS,
3610 Long_val(option));
3612 if (result != CURLE_OK)
3613 raiseError(conn, result);
3615 CAMLreturn0;
3618 static void handleMaxConnects(Connection *conn, value option)
3620 CAMLparam1(option);
3621 CURLcode result = CURLE_OK;
3623 result = curl_easy_setopt(conn->connection,
3624 CURLOPT_MAXCONNECTS,
3625 Long_val(option));
3627 if (result != CURLE_OK)
3628 raiseError(conn, result);
3630 CAMLreturn0;
3633 static void handleClosePolicy(Connection *conn, value option)
3635 CAMLparam1(option);
3636 CURLcode result = CURLE_OK;
3638 switch (Long_val(option))
3640 case 0: /* CLOSEPOLICY_OLDEST */
3641 result = curl_easy_setopt(conn->connection,
3642 CURLOPT_CLOSEPOLICY,
3643 CURLCLOSEPOLICY_OLDEST);
3644 break;
3646 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3647 result = curl_easy_setopt(conn->connection,
3648 CURLOPT_CLOSEPOLICY,
3649 CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
3650 break;
3652 default:
3653 failwith("Invalid CLOSEPOLICY Option");
3654 break;
3657 if (result != CURLE_OK)
3658 raiseError(conn, result);
3660 CAMLreturn0;
3663 static void handleFreshConnect(Connection *conn, value option)
3665 CAMLparam1(option);
3666 CURLcode result = CURLE_OK;
3668 result = curl_easy_setopt(conn->connection,
3669 CURLOPT_FRESH_CONNECT,
3670 Bool_val(option));
3672 if (result != CURLE_OK)
3673 raiseError(conn, result);
3675 CAMLreturn0;
3678 static void handleForbidReuse(Connection *conn, value option)
3680 CAMLparam1(option);
3681 CURLcode result = CURLE_OK;
3683 result = curl_easy_setopt(conn->connection,
3684 CURLOPT_FORBID_REUSE,
3685 Bool_val(option));
3687 if (result != CURLE_OK)
3688 raiseError(conn, result);
3690 CAMLreturn0;
3693 static void handleRandomFile(Connection *conn, value option)
3695 CAMLparam1(option);
3696 CURLcode result = CURLE_OK;
3698 Store_field(conn->ocamlValues, OcamlRandomFile, option);
3700 if (conn->randomFile != NULL)
3701 free(conn->randomFile);
3703 conn->randomFile = strdup(String_val(option));
3705 result = curl_easy_setopt(conn->connection,
3706 CURLOPT_RANDOM_FILE,
3707 conn->randomFile);
3709 if (result != CURLE_OK)
3710 raiseError(conn, result);
3712 CAMLreturn0;
3715 static void handleEGDSocket(Connection *conn, value option)
3717 CAMLparam1(option);
3718 CURLcode result = CURLE_OK;
3720 Store_field(conn->ocamlValues, OcamlEGDSocket, option);
3722 if (conn->egdSocket != NULL)
3723 free(conn->egdSocket);
3725 conn->egdSocket = strdup(String_val(option));
3727 result = curl_easy_setopt(conn->connection,
3728 CURLOPT_EGDSOCKET,
3729 conn->egdSocket);
3731 if (result != CURLE_OK)
3732 raiseError(conn, result);
3734 CAMLreturn0;
3737 static void handleConnectTimeout(Connection *conn, value option)
3739 CAMLparam1(option);
3740 CURLcode result = CURLE_OK;
3742 result = curl_easy_setopt(conn->connection,
3743 CURLOPT_CONNECTTIMEOUT,
3744 Long_val(option));
3746 if (result != CURLE_OK)
3747 raiseError(conn, result);
3749 CAMLreturn0;
3752 static void handleHTTPGet(Connection *conn, value option)
3754 CAMLparam1(option);
3755 CURLcode result = CURLE_OK;
3757 result = curl_easy_setopt(conn->connection,
3758 CURLOPT_HTTPGET,
3759 Bool_val(option));
3761 if (result != CURLE_OK)
3762 raiseError(conn, result);
3764 CAMLreturn0;
3767 static void handleSSLVerifyHost(Connection *conn, value option)
3769 CAMLparam1(option);
3770 CURLcode result = CURLE_OK;
3772 switch (Long_val(option))
3774 case 0: /* SSLVERIFYHOST_EXISTENCE */
3775 result = curl_easy_setopt(conn->connection,
3776 CURLOPT_SSL_VERIFYHOST,
3778 break;
3780 case 1: /* SSLVERIFYHOST_HOSTNAME */
3781 result = curl_easy_setopt(conn->connection,
3782 CURLOPT_SSL_VERIFYHOST,
3784 break;
3786 default:
3787 failwith("Invalid SSLVERIFYHOST Option");
3788 break;
3791 if (result != CURLE_OK)
3792 raiseError(conn, result);
3794 CAMLreturn0;
3797 static void handleCookieJar(Connection *conn, value option)
3799 CAMLparam1(option);
3800 CURLcode result = CURLE_OK;
3802 Store_field(conn->ocamlValues, OcamlCookieJar, option);
3804 if (conn->cookieJar != NULL)
3805 free(conn->cookieJar);
3807 conn->cookieJar = strdup(String_val(option));
3809 result = curl_easy_setopt(conn->connection,
3810 CURLOPT_COOKIEJAR,
3811 conn->cookieJar);
3813 if (result != CURLE_OK)
3814 raiseError(conn, result);
3816 CAMLreturn0;
3819 static void handleSSLCipherList(Connection *conn, value option)
3821 CAMLparam1(option);
3822 CURLcode result = CURLE_OK;
3824 Store_field(conn->ocamlValues, OcamlSSLCipherList, option);
3826 if (conn->sslCipherList != NULL)
3827 free(conn->sslCipherList);
3829 conn->sslCipherList = strdup(String_val(option));
3831 result = curl_easy_setopt(conn->connection,
3832 CURLOPT_SSL_CIPHER_LIST,
3833 conn->sslCipherList);
3835 if (result != CURLE_OK)
3836 raiseError(conn, result);
3838 CAMLreturn0;
3841 static void handleHTTPVersion(Connection *conn, value option)
3843 CAMLparam1(option);
3844 CURLcode result = CURLE_OK;
3846 switch (Long_val(option))
3848 case 0: /* HTTP_VERSION_NONE */
3849 result = curl_easy_setopt(conn->connection,
3850 CURLOPT_HTTP_VERSION,
3851 CURL_HTTP_VERSION_NONE);
3852 break;
3854 case 1: /* HTTP_VERSION_1_0 */
3855 result = curl_easy_setopt(conn->connection,
3856 CURLOPT_HTTP_VERSION,
3857 CURL_HTTP_VERSION_1_0);
3858 break;
3860 case 2: /* HTTP_VERSION_1_1 */
3861 result = curl_easy_setopt(conn->connection,
3862 CURLOPT_HTTP_VERSION,
3863 CURL_HTTP_VERSION_1_1);
3864 break;
3866 default:
3867 failwith("Invalid HTTP_VERSION Option");
3868 break;
3871 if (result != CURLE_OK)
3872 raiseError(conn, result);
3874 CAMLreturn0;
3877 static void handleFTPUseEPSV(Connection *conn, value option)
3879 CAMLparam1(option);
3880 CURLcode result = CURLE_OK;
3882 result = curl_easy_setopt(conn->connection,
3883 CURLOPT_FTP_USE_EPSV,
3884 Bool_val(option));
3886 if (result != CURLE_OK)
3887 raiseError(conn, result);
3889 CAMLreturn0;
3892 static void handleDNSCacheTimeout(Connection *conn, value option)
3894 CAMLparam1(option);
3895 CURLcode result = CURLE_OK;
3897 result = curl_easy_setopt(conn->connection,
3898 CURLOPT_DNS_CACHE_TIMEOUT,
3899 Long_val(option));
3901 if (result != CURLE_OK)
3902 raiseError(conn, result);
3904 CAMLreturn0;
3907 static void handleDNSUseGlobalCache(Connection *conn, value option)
3909 CAMLparam1(option);
3910 CURLcode result = CURLE_OK;
3912 result = curl_easy_setopt(conn->connection,
3913 CURLOPT_DNS_USE_GLOBAL_CACHE,
3914 Bool_val(option));
3916 if (result != CURLE_OK)
3917 raiseError(conn, result);
3919 CAMLreturn0;
3922 static void handleDebugFunction(Connection *conn, value option)
3924 CAMLparam1(option);
3925 CURLcode result = CURLE_OK;
3927 if (Tag_val(option) == Closure_tag)
3928 Store_field(conn->ocamlValues, OcamlDebugCallback, option);
3929 else
3930 failwith("Not a proper closure");
3932 result = curl_easy_setopt(conn->connection,
3933 CURLOPT_DEBUGFUNCTION,
3934 debugFunction);
3935 if (result != CURLE_OK)
3936 raiseError(conn, result);
3938 result = curl_easy_setopt(conn->connection,
3939 CURLOPT_DEBUGDATA,
3940 conn);
3942 if (result != CURLE_OK)
3943 raiseError(conn, result);
3945 CAMLreturn0;
3948 static void handlePrivate(Connection *conn, value option)
3950 #if HAVE_DECL_CURLOPT_PRIVATE
3951 CAMLparam1(option);
3952 CURLcode result = CURLE_OK;
3954 Store_field(conn->ocamlValues, OcamlPrivate, option);
3956 if (conn->private != NULL)
3957 free(conn->private);
3959 conn->private = strdup(String_val(option));
3961 result = curl_easy_setopt(conn->connection,
3962 CURLOPT_PRIVATE,
3963 conn->private);
3965 if (result != CURLE_OK)
3966 raiseError(conn, result);
3968 CAMLreturn0;
3969 #else
3970 #warning "libcurl does not implement CURLOPT_PRIVATE"
3971 failwith("libcurl does not implement CURLOPT_PRIVATE");
3972 #endif
3975 static void handleHTTP200Aliases(Connection *conn, value option)
3977 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3978 CAMLparam1(option);
3979 CAMLlocal1(listIter);
3980 CURLcode result = CURLE_OK;
3981 char *str;
3983 Store_field(conn->ocamlValues, OcamlHTTP200Aliases, option);
3985 if (conn->http200Aliases != NULL)
3986 free_curl_slist(conn->http200Aliases);
3988 conn->http200Aliases = NULL;
3990 listIter = option;
3992 while (!Is_long(listIter))
3994 if (Tag_val(Field(listIter, 0)) != String_tag)
3995 failwith("Not a string");
3997 str = strdup(String_val(Field(listIter, 0)));
3999 conn->http200Aliases = curl_slist_append(conn->http200Aliases, str);
4001 listIter = Field(listIter, 1);
4004 result = curl_easy_setopt(conn->connection,
4005 CURLOPT_HTTP200ALIASES,
4006 conn->http200Aliases);
4008 if (result != CURLE_OK)
4009 raiseError(conn, result);
4011 CAMLreturn0;
4012 #else
4013 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
4014 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
4015 #endif
4018 static void handleUnrestrictedAuth(Connection *conn, value option)
4020 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
4021 CAMLparam1(option);
4022 CURLcode result = CURLE_OK;
4024 result = curl_easy_setopt(conn->connection,
4025 CURLOPT_UNRESTRICTED_AUTH,
4026 Bool_val(option));
4028 if (result != CURLE_OK)
4029 raiseError(conn, result);
4031 CAMLreturn0;
4032 #else
4033 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4034 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4035 #endif
4038 static void handleFTPUseEPRT(Connection *conn, value option)
4040 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4041 CAMLparam1(option);
4042 CURLcode result = CURLE_OK;
4044 result = curl_easy_setopt(conn->connection,
4045 CURLOPT_FTP_USE_EPRT,
4046 Bool_val(option));
4048 if (result != CURLE_OK)
4049 raiseError(conn, result);
4051 CAMLreturn0;
4052 #else
4053 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4054 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4055 #endif
4058 static void handleHTTPAuth(Connection *conn, value option)
4060 #if HAVE_DECL_CURLOPT_HTTPAUTH
4061 CAMLparam1(option);
4062 CAMLlocal1(listIter);
4063 CURLcode result = CURLE_OK;
4064 long auth = CURLAUTH_NONE;
4066 listIter = option;
4068 while (!Is_long(listIter))
4070 switch (Long_val(Field(listIter, 0)))
4072 case 0: /* CURLAUTH_BASIC */
4073 auth |= CURLAUTH_BASIC;
4074 break;
4076 case 1: /* CURLAUTH_DIGEST */
4077 auth |= CURLAUTH_DIGEST;
4078 break;
4080 case 2: /* CURLAUTH_GSSNEGOTIATE */
4081 auth |= CURLAUTH_GSSNEGOTIATE;
4082 break;
4084 case 3: /* CURLAUTH_NTLM */
4085 auth |= CURLAUTH_NTLM;
4086 break;
4088 case 4: /* CURLAUTH_ANY */
4089 auth |= CURLAUTH_ANY;
4090 break;
4092 case 5: /* CURLAUTH_ANYSAFE */
4093 auth |= CURLAUTH_ANYSAFE;
4094 break;
4096 default:
4097 failwith("Invalid HTTPAUTH Value");
4098 break;
4101 listIter = Field(listIter, 1);
4104 result = curl_easy_setopt(conn->connection,
4105 CURLOPT_HTTPAUTH,
4106 auth);
4108 if (result != CURLE_OK)
4109 raiseError(conn, result);
4111 CAMLreturn0;
4112 #else
4113 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4114 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4115 #endif
4118 static void handleFTPCreateMissingDirs(Connection *conn, value option)
4120 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4121 CAMLparam1(option);
4122 CURLcode result = CURLE_OK;
4124 result = curl_easy_setopt(conn->connection,
4125 CURLOPT_FTP_CREATE_MISSING_DIRS,
4126 Bool_val(option));
4128 if (result != CURLE_OK)
4129 raiseError(conn, result);
4131 CAMLreturn0;
4132 #else
4133 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4134 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4135 #endif
4138 static void handleProxyAuth(Connection *conn, value option)
4140 #if HAVE_DECL_CURLOPT_PROXYAUTH
4141 CAMLparam1(option);
4142 CAMLlocal1(listIter);
4143 CURLcode result = CURLE_OK;
4144 long auth = CURLAUTH_NONE;
4146 listIter = option;
4148 while (!Is_long(listIter))
4150 switch (Long_val(Field(listIter, 0)))
4152 case 0: /* CURLAUTH_BASIC */
4153 auth |= CURLAUTH_BASIC;
4154 break;
4156 case 1: /* CURLAUTH_DIGEST */
4157 auth |= CURLAUTH_DIGEST;
4158 break;
4160 case 2: /* CURLAUTH_GSSNEGOTIATE */
4161 auth |= CURLAUTH_GSSNEGOTIATE;
4162 break;
4164 case 3: /* CURLAUTH_NTLM */
4165 auth |= CURLAUTH_NTLM;
4166 break;
4168 case 4: /* CURLAUTH_ANY */
4169 auth |= CURLAUTH_ANY;
4170 break;
4172 case 5: /* CURLAUTH_ANYSAFE */
4173 auth |= CURLAUTH_ANYSAFE;
4174 break;
4176 default:
4177 failwith("Invalid HTTPAUTH Value");
4178 break;
4181 listIter = Field(listIter, 1);
4184 result = curl_easy_setopt(conn->connection,
4185 CURLOPT_PROXYAUTH,
4186 auth);
4188 if (result != CURLE_OK)
4189 raiseError(conn, result);
4191 CAMLreturn0;
4192 #else
4193 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4194 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4195 #endif
4198 static void handleFTPResponseTimeout(Connection *conn, value option)
4200 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4201 CAMLparam1(option);
4202 CURLcode result = CURLE_OK;
4204 result = curl_easy_setopt(conn->connection,
4205 CURLOPT_FTP_RESPONSE_TIMEOUT,
4206 Long_val(option));
4208 if (result != CURLE_OK)
4209 raiseError(conn, result);
4211 CAMLreturn0;
4212 #else
4213 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4214 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4215 #endif
4218 static void handleIPResolve(Connection *conn, value option)
4220 #if HAVE_DECL_CURLOPT_IPRESOLVE
4221 CAMLparam1(option);
4222 CURLcode result = CURLE_OK;
4224 switch (Long_val(option))
4226 case 0: /* CURL_IPRESOLVE_WHATEVER */
4227 result = curl_easy_setopt(conn->connection,
4228 CURLOPT_IPRESOLVE,
4229 CURL_IPRESOLVE_WHATEVER);
4230 break;
4232 case 1: /* CURL_IPRESOLVE_V4 */
4233 result = curl_easy_setopt(conn->connection,
4234 CURLOPT_IPRESOLVE,
4235 CURL_IPRESOLVE_V4);
4236 break;
4238 case 2: /* CURL_IPRESOLVE_V6 */
4239 result = curl_easy_setopt(conn->connection,
4240 CURLOPT_IPRESOLVE,
4241 CURL_IPRESOLVE_V6);
4242 break;
4244 default:
4245 failwith("Invalid IPRESOLVE Value");
4246 break;
4249 if (result != CURLE_OK)
4250 raiseError(conn, result);
4252 CAMLreturn0;
4253 #else
4254 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4255 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4256 #endif
4259 static void handleMaxFileSize(Connection *conn, value option)
4261 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4262 CAMLparam1(option);
4263 CURLcode result = CURLE_OK;
4265 result = curl_easy_setopt(conn->connection,
4266 CURLOPT_MAXFILESIZE,
4267 Int32_val(option));
4269 if (result != CURLE_OK)
4270 raiseError(conn, result);
4272 CAMLreturn0;
4273 #else
4274 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4275 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4276 #endif
4279 static void handleInFileSizeLarge(Connection *conn, value option)
4281 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4282 CAMLparam1(option);
4283 CURLcode result = CURLE_OK;
4285 result = curl_easy_setopt(conn->connection,
4286 CURLOPT_INFILESIZE_LARGE,
4287 Int64_val(option));
4289 if (result != CURLE_OK)
4290 raiseError(conn, result);
4292 CAMLreturn0;
4293 #else
4294 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4295 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4296 #endif
4299 static void handleResumeFromLarge(Connection *conn, value option)
4301 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4302 CAMLparam1(option);
4303 CURLcode result = CURLE_OK;
4305 result = curl_easy_setopt(conn->connection,
4306 CURLOPT_RESUME_FROM_LARGE,
4307 Int64_val(option));
4309 if (result != CURLE_OK)
4310 raiseError(conn, result);
4312 CAMLreturn0;
4313 #else
4314 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4315 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4316 #endif
4319 static void handleMaxFileSizeLarge(Connection *conn, value option)
4321 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4322 CAMLparam1(option);
4323 CURLcode result = CURLE_OK;
4325 result = curl_easy_setopt(conn->connection,
4326 CURLOPT_MAXFILESIZE_LARGE,
4327 Int64_val(option));
4329 if (result != CURLE_OK)
4330 raiseError(conn, result);
4332 CAMLreturn0;
4333 #else
4334 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4335 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4336 #endif
4339 static void handleNETRCFile(Connection *conn, value option)
4341 #if HAVE_DECL_CURLOPT_NETRC_FILE
4342 CAMLparam1(option);
4343 CURLcode result = CURLE_OK;
4345 Store_field(conn->ocamlValues, OcamlNETRCFile, option);
4347 if (conn->netrcFile != NULL)
4348 free(conn->netrcFile);
4350 conn->netrcFile = strdup(String_val(option));
4352 result = curl_easy_setopt(conn->connection,
4353 CURLOPT_NETRC_FILE,
4354 conn->netrcFile);
4356 if (result != CURLE_OK)
4357 raiseError(conn, result);
4359 CAMLreturn0;
4360 #else
4361 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4362 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4363 #endif
4366 static void handleFTPSSL(Connection *conn, value option)
4368 #if HAVE_DECL_CURLOPT_FTP_SSL
4369 CAMLparam1(option);
4370 CURLcode result = CURLE_OK;
4372 switch (Long_val(option))
4374 case 0: /* CURLFTPSSL_NONE */
4375 result = curl_easy_setopt(conn->connection,
4376 CURLOPT_FTP_SSL,
4377 CURLFTPSSL_NONE);
4378 break;
4380 case 1: /* CURLFTPSSL_TRY */
4381 result = curl_easy_setopt(conn->connection,
4382 CURLOPT_FTP_SSL,
4383 CURLFTPSSL_TRY);
4384 break;
4386 case 2: /* CURLFTPSSL_CONTROL */
4387 result = curl_easy_setopt(conn->connection,
4388 CURLOPT_FTP_SSL,
4389 CURLFTPSSL_CONTROL);
4390 break;
4392 case 3: /* CURLFTPSSL_ALL */
4393 result = curl_easy_setopt(conn->connection,
4394 CURLOPT_FTP_SSL,
4395 CURLFTPSSL_ALL);
4396 break;
4398 default:
4399 failwith("Invalid FTP_SSL Value");
4400 break;
4403 if (result != CURLE_OK)
4404 raiseError(conn, result);
4406 CAMLreturn0;
4407 #else
4408 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4409 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4410 #endif
4413 static void handlePostFieldSizeLarge(Connection *conn, value option)
4415 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4416 CAMLparam1(option);
4417 CURLcode result = CURLE_OK;
4419 result = curl_easy_setopt(conn->connection,
4420 CURLOPT_POSTFIELDSIZE_LARGE,
4421 Int64_val(option));
4423 if (result != CURLE_OK)
4424 raiseError(conn, result);
4426 CAMLreturn0;
4427 #else
4428 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4429 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4430 #endif
4433 static void handleTCPNoDelay(Connection *conn, value option)
4435 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4436 CAMLparam1(option);
4437 CURLcode result = CURLE_OK;
4439 result = curl_easy_setopt(conn->connection,
4440 CURLOPT_TCP_NODELAY,
4441 Bool_val(option));
4443 if (result != CURLE_OK)
4444 raiseError(conn, result);
4446 CAMLreturn0;
4447 #else
4448 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4449 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4450 #endif
4453 static void handleFTPSSLAuth(Connection *conn, value option)
4455 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4456 CAMLparam1(option);
4457 CURLcode result = CURLE_OK;
4459 switch (Long_val(option))
4461 case 0: /* CURLFTPAUTH_DEFAULT */
4462 result = curl_easy_setopt(conn->connection,
4463 CURLOPT_FTPSSLAUTH,
4464 CURLFTPAUTH_DEFAULT);
4465 break;
4467 case 1: /* CURLFTPAUTH_SSL */
4468 result = curl_easy_setopt(conn->connection,
4469 CURLOPT_FTPSSLAUTH,
4470 CURLFTPAUTH_SSL);
4471 break;
4473 case 2: /* CURLFTPAUTH_TLS */
4474 result = curl_easy_setopt(conn->connection,
4475 CURLOPT_FTPSSLAUTH,
4476 CURLFTPAUTH_TLS);
4477 break;
4479 default:
4480 failwith("Invalid FTPSSLAUTH value");
4481 break;
4484 if (result != CURLE_OK)
4485 raiseError(conn, result);
4487 CAMLreturn0;
4488 #else
4489 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4490 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4491 #endif
4494 static void handleIOCTLFunction(Connection *conn, value option)
4496 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4497 CAMLparam1(option);
4498 CURLcode result = CURLE_OK;
4500 if (Tag_val(option) == Closure_tag)
4501 Store_field(conn->ocamlValues, OcamlIOCTLCallback, option);
4502 else
4503 failwith("Not a proper closure");
4505 result = curl_easy_setopt(conn->connection,
4506 CURLOPT_IOCTLFUNCTION,
4507 ioctlFunction);
4508 if (result != CURLE_OK)
4509 raiseError(conn, result);
4511 result = curl_easy_setopt(conn->connection,
4512 CURLOPT_DEBUGDATA,
4513 conn);
4515 if (result != CURLE_OK)
4516 raiseError(conn, result);
4518 CAMLreturn0;
4519 #else
4520 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4521 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4522 #endif
4525 static void handleFTPAccount(Connection *conn, value option)
4527 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4528 CAMLparam1(option);
4529 CURLcode result = CURLE_OK;
4531 Store_field(conn->ocamlValues, OcamlFTPAccount, option);
4533 if (conn->ftpaccount != NULL)
4534 free(conn->ftpaccount);
4536 conn->ftpaccount = strdup(String_val(option));
4538 result = curl_easy_setopt(conn->connection,
4539 CURLOPT_FTP_ACCOUNT,
4540 conn->ftpaccount);
4542 if (result != CURLE_OK)
4543 raiseError(conn, result);
4545 CAMLreturn0;
4546 #else
4547 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4548 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4549 #endif
4552 static void handleCookieList(Connection *conn, value option)
4554 #if HAVE_DECL_CURLOPT_COOKIELIST
4555 CAMLparam1(option);
4556 CURLcode result = CURLE_OK;
4558 Store_field(conn->ocamlValues, OcamlCookieList, option);
4560 if (conn->cookielist != NULL)
4561 free(conn->cookielist);
4563 conn->cookielist = strdup(String_val(option));
4565 result = curl_easy_setopt(conn->connection,
4566 CURLOPT_COOKIELIST,
4567 conn->cookielist);
4569 if (result != CURLE_OK)
4570 raiseError(conn, result);
4572 CAMLreturn0;
4573 #else
4574 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4575 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4576 #endif
4579 static void handleIgnoreContentLength(Connection *conn, value option)
4581 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4582 CAMLparam1(option);
4583 CURLcode result = CURLE_OK;
4585 result = curl_easy_setopt(conn->connection,
4586 CURLOPT_IGNORE_CONTENT_LENGTH,
4587 Bool_val(option));
4589 if (result != CURLE_OK)
4590 raiseError(conn, result);
4592 CAMLreturn0;
4593 #else
4594 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4595 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4596 #endif
4599 static void handleFTPSkipPASVIP(Connection *conn, value option)
4601 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4602 CAMLparam1(option);
4603 CURLcode result = CURLE_OK;
4605 result = curl_easy_setopt(conn->connection,
4606 CURLOPT_FTP_SKIP_PASV_IP,
4607 Bool_val(option));
4609 if (result != CURLE_OK)
4610 raiseError(conn, result);
4612 CAMLreturn0;
4613 #else
4614 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4615 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4616 #endif
4619 static void handleFTPFileMethod(Connection *conn, value option)
4621 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4622 CAMLparam1(option);
4623 CURLcode result = CURLE_OK;
4625 switch (Long_val(option))
4627 case 0: /* CURLFTPMETHOD_DEFAULT */
4628 result = curl_easy_setopt(conn->connection,
4629 CURLOPT_FTP_FILEMETHOD,
4630 CURLFTPMETHOD_DEFAULT);
4631 break;
4633 case 1: /* CURLFTMETHOD_MULTICWD */
4634 result = curl_easy_setopt(conn->connection,
4635 CURLOPT_FTP_FILEMETHOD,
4636 CURLFTPMETHOD_MULTICWD);
4637 break;
4639 case 2: /* CURLFTPMETHOD_NOCWD */
4640 result = curl_easy_setopt(conn->connection,
4641 CURLOPT_FTP_FILEMETHOD,
4642 CURLFTPMETHOD_NOCWD);
4643 break;
4645 case 3: /* CURLFTPMETHOD_SINGLECWD */
4646 result = curl_easy_setopt(conn->connection,
4647 CURLOPT_FTP_FILEMETHOD,
4648 CURLFTPMETHOD_SINGLECWD);
4650 default:
4651 failwith("Invalid FTP_FILEMETHOD value");
4652 break;
4655 if (result != CURLE_OK)
4656 raiseError(conn, result);
4658 CAMLreturn0;
4659 #else
4660 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4661 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4662 #endif
4665 static void handleLocalPort(Connection *conn, value option)
4667 #if HAVE_DECL_CURLOPT_LOCALPORT
4668 CAMLparam1(option);
4669 CURLcode result = CURLE_OK;
4671 result = curl_easy_setopt(conn->connection,
4672 CURLOPT_LOCALPORT,
4673 Long_val(option));
4675 if (result != CURLE_OK)
4676 raiseError(conn, result);
4678 CAMLreturn0;
4679 #else
4680 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4681 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4682 #endif
4685 static void handleLocalPortRange(Connection *conn, value option)
4687 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4688 CAMLparam1(option);
4689 CURLcode result = CURLE_OK;
4691 result = curl_easy_setopt(conn->connection,
4692 CURLOPT_LOCALPORTRANGE,
4693 Long_val(option));
4695 if (result != CURLE_OK)
4696 raiseError(conn, result);
4698 CAMLreturn0;
4699 #else
4700 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4701 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4702 #endif
4705 static void handleConnectOnly(Connection *conn, value option)
4707 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4708 CAMLparam1(option);
4709 CURLcode result = CURLE_OK;
4711 result = curl_easy_setopt(conn->connection,
4712 CURLOPT_CONNECT_ONLY,
4713 Bool_val(option));
4715 if (result != CURLE_OK)
4716 raiseError(conn, result);
4718 CAMLreturn0;
4719 #else
4720 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4721 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4722 #endif
4725 static void handleMaxSendSpeedLarge(Connection *conn, value option)
4727 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4728 CAMLparam1(option);
4729 CURLcode result = CURLE_OK;
4731 result = curl_easy_setopt(conn->connection,
4732 CURLOPT_MAX_SEND_SPEED_LARGE,
4733 Int64_val(option));
4735 if (result != CURLE_OK)
4736 raiseError(conn, result);
4738 CAMLreturn0;
4739 #else
4740 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4741 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4742 #endif
4745 static void handleMaxRecvSpeedLarge(Connection *conn, value option)
4747 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4748 CAMLparam1(option);
4749 CURLcode result = CURLE_OK;
4751 result = curl_easy_setopt(conn->connection,
4752 CURLOPT_MAX_RECV_SPEED_LARGE,
4753 Int64_val(option));
4755 if (result != CURLE_OK)
4756 raiseError(conn, result);
4758 CAMLreturn0;
4759 #else
4760 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4761 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4762 #endif
4765 static void handleFTPAlternativeToUser(Connection *conn, value option)
4767 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4768 CAMLparam1(option);
4769 CURLcode result = CURLE_OK;
4771 Store_field(conn->ocamlValues, OcamlFTPAlternativeToUser, option);
4773 if (conn->ftpAlternativeToUser != NULL)
4774 free(conn->ftpAlternativeToUser);
4776 conn->ftpAlternativeToUser = strdup(String_val(option));
4778 result = curl_easy_setopt(conn->connection,
4779 CURLOPT_FTP_ALTERNATIVE_TO_USER,
4780 conn->ftpAlternativeToUser);
4782 if (result != CURLE_OK)
4783 raiseError(conn, result);
4785 CAMLreturn0;
4786 #else
4787 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4788 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4789 #endif
4792 static void handleSSLSessionIdCache(Connection *conn, value option)
4794 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4795 CAMLparam1(option);
4796 CURLcode result = CURLE_OK;
4798 result = curl_easy_setopt(conn->connection,
4799 CURLOPT_SSL_SESSIONID_CACHE,
4800 Bool_val(option));
4802 if (result != CURLE_OK)
4803 raiseError(conn, result);
4805 CAMLreturn0;
4806 #else
4807 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4808 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4809 #endif
4812 static void handleSSHAuthTypes(Connection *conn, value option)
4814 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4815 CAMLparam1(option);
4816 CAMLlocal1(listIter);
4817 CURLcode result = CURLE_OK;
4818 long authTypes = CURLSSH_AUTH_NONE;
4820 listIter = option;
4822 while (!Is_long(listIter))
4824 switch (Long_val(Field(listIter, 0)))
4826 case 0: /* CURLSSH_AUTH_ANY */
4827 authTypes |= CURLSSH_AUTH_ANY;
4828 break;
4830 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4831 authTypes |= CURLSSH_AUTH_PUBLICKEY;
4832 break;
4834 case 2: /* CURLSSH_AUTH_PASSWORD */
4835 authTypes |= CURLSSH_AUTH_PASSWORD;
4836 break;
4838 case 3: /* CURLSSH_AUTH_HOST */
4839 authTypes |= CURLSSH_AUTH_HOST;
4840 break;
4842 case 4: /* CURLSSH_AUTH_KEYBOARD */
4843 authTypes |= CURLSSH_AUTH_KEYBOARD;
4844 break;
4846 default:
4847 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4848 break;
4851 listIter = Field(listIter, 1);
4854 result = curl_easy_setopt(conn->connection,
4855 CURLOPT_SSH_AUTH_TYPES,
4856 authTypes);
4858 if (result != CURLE_OK)
4859 raiseError(conn, result);
4861 CAMLreturn0;
4862 #else
4863 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4864 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4865 #endif
4868 static void handleSSHPublicKeyFile(Connection *conn, value option)
4870 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4871 CAMLparam1(option);
4872 CURLcode result = CURLE_OK;
4874 Store_field(conn->ocamlValues, OcamlSSHPublicKeyFile, option);
4876 if (conn->sshPublicKeyFile != NULL)
4877 free(conn->sshPublicKeyFile);
4879 conn->sshPublicKeyFile = strdup(String_val(option));
4881 result = curl_easy_setopt(conn->connection,
4882 CURLOPT_SSH_PUBLIC_KEYFILE,
4883 conn->sshPublicKeyFile);
4885 if (result != CURLE_OK)
4886 raiseError(conn, result);
4888 CAMLreturn0;
4889 #else
4890 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4891 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4892 #endif
4895 static void handleSSHPrivateKeyFile(Connection *conn, value option)
4897 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4898 CAMLparam1(option);
4899 CURLcode result = CURLE_OK;
4901 Store_field(conn->ocamlValues, OcamlSSHPrivateKeyFile, option);
4903 if (conn->sshPrivateKeyFile != NULL)
4904 free(conn->sshPrivateKeyFile);
4906 conn->sshPrivateKeyFile = strdup(String_val(option));
4908 result = curl_easy_setopt(conn->connection,
4909 CURLOPT_SSH_PRIVATE_KEYFILE,
4910 conn->sshPrivateKeyFile);
4912 if (result != CURLE_OK)
4913 raiseError(conn, result);
4915 CAMLreturn0;
4916 #else
4917 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4918 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4919 #endif
4922 static void handleFTPSSLCCC(Connection *conn, value option)
4924 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4925 CAMLparam1(option);
4926 CURLcode result = CURLE_OK;
4928 switch (Long_val(option))
4930 case 0: /* CURLFTPSSL_CCC_NONE */
4931 result = curl_easy_setopt(conn->connection,
4932 CURLOPT_FTP_SSL_CCC,
4933 CURLFTPSSL_CCC_NONE);
4934 break;
4936 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4937 result = curl_easy_setopt(conn->connection,
4938 CURLOPT_FTP_SSL_CCC,
4939 CURLFTPSSL_CCC_PASSIVE);
4940 break;
4942 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4943 result = curl_easy_setopt(conn->connection,
4944 CURLOPT_FTP_SSL_CCC,
4945 CURLFTPSSL_CCC_ACTIVE);
4946 break;
4948 default:
4949 failwith("Invalid FTPSSL_CCC value");
4950 break;
4953 if (result != CURLE_OK)
4954 raiseError(conn, result);
4956 CAMLreturn0;
4957 #else
4958 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4959 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4960 #endif
4963 static void handleTimeoutMS(Connection *conn, value option)
4965 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4966 CAMLparam1(option);
4967 CURLcode result = CURLE_OK;
4969 result = curl_easy_setopt(conn->connection,
4970 CURLOPT_TIMEOUT_MS,
4971 Long_val(option));
4973 if (result != CURLE_OK)
4974 raiseError(conn, result);
4976 CAMLreturn0;
4977 #else
4978 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4979 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4980 #endif
4983 static void handleConnectTimeoutMS(Connection *conn, value option)
4985 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4986 CAMLparam1(option);
4987 CURLcode result = CURLE_OK;
4989 result = curl_easy_setopt(conn->connection,
4990 CURLOPT_CONNECTTIMEOUT_MS,
4991 Long_val(option));
4993 if (result != CURLE_OK)
4994 raiseError(conn, result);
4996 CAMLreturn0;
4997 #else
4998 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4999 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
5000 #endif
5003 static void handleHTTPTransferDecoding(Connection *conn, value option)
5005 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
5006 CAMLparam1(option);
5007 CURLcode result = CURLE_OK;
5009 result = curl_easy_setopt(conn->connection,
5010 CURLOPT_HTTP_TRANSFER_DECODING,
5011 Bool_val(option));
5013 if (result != CURLE_OK)
5014 raiseError(conn, result);
5016 CAMLreturn0;
5017 #else
5018 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
5019 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
5020 #endif
5023 static void handleHTTPContentDecoding(Connection *conn, value option)
5025 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
5026 CAMLparam1(option);
5027 CURLcode result = CURLE_OK;
5029 result = curl_easy_setopt(conn->connection,
5030 CURLOPT_HTTP_CONTENT_DECODING,
5031 Bool_val(option));
5033 if (result != CURLE_OK)
5034 raiseError(conn, result);
5036 CAMLreturn0;
5037 #else
5038 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5039 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5040 #endif
5043 static void handleNewFilePerms(Connection *conn, value option)
5045 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5046 CAMLparam1(option);
5047 CURLcode result = CURLE_OK;
5049 result = curl_easy_setopt(conn->connection,
5050 CURLOPT_NEW_FILE_PERMS,
5051 Long_val(option));
5053 if (result != CURLE_OK)
5054 raiseError(conn, result);
5056 CAMLreturn0;
5057 #else
5058 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5059 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5060 #endif
5063 static void handleNewDirectoryPerms(Connection *conn, value option)
5065 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5066 CAMLparam1(option);
5067 CURLcode result = CURLE_OK;
5069 result = curl_easy_setopt(conn->connection,
5070 CURLOPT_NEW_DIRECTORY_PERMS,
5071 Long_val(option));
5073 if (result != CURLE_OK)
5074 raiseError(conn, result);
5076 CAMLreturn0;
5077 #else
5078 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5079 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5080 #endif
5083 static void handlePost301(Connection *conn, value option)
5085 #if HAVE_DECL_CURLOPT_POST301
5086 CAMLparam1(option);
5087 CURLcode result = CURLE_OK;
5089 result = curl_easy_setopt(conn->connection,
5090 CURLOPT_POST301,
5091 Bool_val(option));
5093 if (result != CURLE_OK)
5094 raiseError(conn, result);
5096 CAMLreturn0;
5097 #else
5098 #warning "libcurl does not implement CURLOPT_POST301"
5099 failwith("libcurl does not implement CURLOPT_POST301");
5100 #endif
5103 static void handleSSHHostPublicKeyMD5(Connection *conn, value option)
5105 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5106 CAMLparam1(option);
5107 CURLcode result = CURLE_OK;
5109 Store_field(conn->ocamlValues, OcamlSSHHostPublicKeyMD5, option);
5111 if (conn->sshHostPublicKeyMD5 != NULL)
5112 free(conn->sshHostPublicKeyMD5);
5114 conn->sshHostPublicKeyMD5 = strdup(String_val(option));
5116 result = curl_easy_setopt(conn->connection,
5117 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
5118 conn->sshHostPublicKeyMD5);
5120 if (result != CURLE_OK)
5121 raiseError(conn, result);
5123 CAMLreturn0;
5124 #else
5125 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5126 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5127 #endif
5130 static void handleCopyPostFields(Connection *conn, value option)
5132 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5133 CAMLparam1(option);
5134 CURLcode result = CURLE_OK;
5136 Store_field(conn->ocamlValues, OcamlCopyPostFields, option);
5138 if (conn->copyPostFields != NULL)
5139 free(conn->copyPostFields);
5141 conn->copyPostFields = strdup(String_val(option));
5143 result = curl_easy_setopt(conn->connection,
5144 CURLOPT_COPYPOSTFIELDS,
5145 conn->copyPostFields);
5147 if (result != CURLE_OK)
5148 raiseError(conn, result);
5150 CAMLreturn0;
5151 #else
5152 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5153 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5154 #endif
5157 static void handleProxyTransferMode(Connection *conn, value option)
5159 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5160 CAMLparam1(option);
5161 CURLcode result = CURLE_OK;
5163 result = curl_easy_setopt(conn->connection,
5164 CURLOPT_PROXY_TRANSFER_MODE,
5165 Bool_val(option));
5167 if (result != CURLE_OK)
5168 raiseError(conn, result);
5170 CAMLreturn0;
5171 #else
5172 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5173 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5174 #endif
5177 static void handleSeekFunction(Connection *conn, value option)
5179 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5180 CAMLparam1(option);
5181 CURLcode result = CURLE_OK;
5183 if (Tag_val(option) == Closure_tag)
5184 Store_field(conn->ocamlValues, OcamlSeekFunctionCallback, option);
5185 else
5186 failwith("Not a proper closure");
5188 result = curl_easy_setopt(conn->connection,
5189 CURLOPT_SEEKFUNCTION,
5190 seekFunction);
5192 if (result != CURLE_OK)
5193 raiseError(conn, result);
5195 result = curl_easy_setopt(conn->connection,
5196 CURLOPT_SEEKDATA,
5197 conn);
5199 if (result != CURLE_OK)
5200 raiseError(conn, result);
5202 CAMLreturn0;
5203 #else
5204 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5205 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5206 #endif
5210 ** curl_easy_setopt helper function
5213 CAMLprim void helper_curl_easy_setopt(value conn, value option)
5215 CAMLparam2(conn, option);
5216 CAMLlocal1(data);
5217 Connection *connection = Connection_val(conn);
5219 checkConnection(connection);
5221 if (Is_long(option))
5223 char error[128];
5225 sprintf(error, "Unimplemented Option: %s",
5226 findOption(unimplementedOptionMap,
5227 (CURLoption)(Long_val(option))));
5229 failwith(error);
5232 if (!Is_block(option))
5233 failwith("Not a block");
5235 if (Wosize_val(option) < 1)
5236 failwith("Insufficient data in block");
5238 data = Field(option, 0);
5240 if (Tag_val(option) < sizeof(implementedOptionMap)/sizeof(CURLOptionMapping))
5241 (*implementedOptionMap[Tag_val(option)].optionHandler)(connection,
5242 data);
5243 else
5244 failwith("Invalid CURLOPT Option");
5246 CAMLreturn0;
5250 ** curl_easy_perform helper function
5253 CAMLprim void helper_curl_easy_perform(value conn)
5255 CAMLparam1(conn);
5256 CURLcode result = CURLE_OK;
5257 Connection *connection = Connection_val(conn);
5259 checkConnection(connection);
5261 enter_blocking_section();
5262 result = curl_easy_perform(connection->connection);
5263 leave_blocking_section();
5265 if (result != CURLE_OK)
5266 raiseError(connection, result);
5268 CAMLreturn0;
5272 ** curl_easy_cleanup helper function
5275 CAMLprim void helper_curl_easy_cleanup(value conn)
5277 CAMLparam1(conn);
5278 Connection *connection = Connection_val(conn);
5280 checkConnection(connection);
5282 removeConnection(connection);
5284 CAMLreturn0;
5288 ** curl_easy_duphandle helper function
5291 CAMLprim value helper_curl_easy_duphandle(value conn)
5293 CAMLparam1(conn);
5294 CAMLlocal1(result);
5295 Connection *connection = Connection_val(conn);
5297 checkConnection(connection);
5299 result = alloc(1, Abstract_tag);
5300 Field(result, 0) = (value)duplicateConnection(connection);
5302 CAMLreturn(result);
5306 ** curl_easy_getinfo helper function
5309 enum GetInfoResultType {
5310 StringValue, LongValue, DoubleValue, StringListValue
5313 value convertStringList(struct curl_slist *slist)
5315 CAMLparam0();
5316 CAMLlocal3(result, current, next);
5317 struct curl_slist *p = slist;
5319 result = Val_int(0);
5320 current = Val_int(0);
5321 next = Val_int(0);
5323 while (p != NULL)
5325 next = alloc_tuple(2);
5326 Field(next, 0) = copy_string(p->data);
5327 Field(next, 1) = Val_int(0);
5329 if (result == Val_int(0))
5330 result = next;
5332 if (current != Val_int(0))
5333 Field(current, 1) = next;
5335 current = next;
5337 p = p->next;
5340 curl_slist_free_all(slist);
5342 CAMLreturn(result);
5345 CAMLprim value helper_curl_easy_getinfo(value conn, value option)
5347 CAMLparam2(conn, option);
5348 CAMLlocal1(result);
5349 CURLcode curlResult;
5350 Connection *connection = Connection_val(conn);
5351 enum GetInfoResultType resultType;
5352 char *strValue = NULL;
5353 double doubleValue;
5354 long longValue;
5355 struct curl_slist *stringListValue = NULL;
5357 checkConnection(connection);
5359 switch(Long_val(option))
5361 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5362 case 0: /* CURLINFO_EFFECTIVE_URL */
5363 resultType = StringValue;
5365 curlResult = curl_easy_getinfo(connection->connection,
5366 CURLINFO_EFFECTIVE_URL,
5367 &strValue);
5368 break;
5369 #else
5370 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5371 #endif
5373 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5374 case 1: /* CURLINFO_HTTP_CODE */
5375 case 2: /* CURLINFO_RESPONSE_CODE */
5376 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5377 resultType = LongValue;
5379 curlResult = curl_easy_getinfo(connection->connection,
5380 CURLINFO_RESPONSE_CODE,
5381 &longValue);
5382 #else
5383 resultType = LongValue;
5385 curlResult = curl_easy_getinfo(connection->connection,
5386 CURLINFO_HTTP_CODE,
5387 &longValue);
5388 #endif
5389 break;
5390 #endif
5392 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5393 case 3: /* CURLINFO_TOTAL_TIME */
5394 resultType = DoubleValue;
5396 curlResult = curl_easy_getinfo(connection->connection,
5397 CURLINFO_TOTAL_TIME,
5398 &doubleValue);
5399 break;
5400 #endif
5402 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5403 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5404 resultType = DoubleValue;
5406 curlResult = curl_easy_getinfo(connection->connection,
5407 CURLINFO_NAMELOOKUP_TIME,
5408 &doubleValue);
5409 break;
5410 #endif
5412 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5413 case 5: /* CURLINFO_CONNECT_TIME */
5414 resultType = DoubleValue;
5416 curlResult = curl_easy_getinfo(connection->connection,
5417 CURLINFO_CONNECT_TIME,
5418 &doubleValue);
5419 break;
5420 #endif
5422 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5423 case 6: /* CURLINFO_PRETRANSFER_TIME */
5424 resultType = DoubleValue;
5426 curlResult = curl_easy_getinfo(connection->connection,
5427 CURLINFO_PRETRANSFER_TIME,
5428 &doubleValue);
5429 break;
5430 #endif
5432 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5433 case 7: /* CURLINFO_SIZE_UPLOAD */
5434 resultType = DoubleValue;
5436 curlResult = curl_easy_getinfo(connection->connection,
5437 CURLINFO_SIZE_UPLOAD,
5438 &doubleValue);
5439 break;
5440 #endif
5442 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5443 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5444 resultType = DoubleValue;
5446 curlResult = curl_easy_getinfo(connection->connection,
5447 CURLINFO_SIZE_DOWNLOAD,
5448 &doubleValue);
5449 break;
5450 #endif
5452 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5453 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5454 resultType = DoubleValue;
5456 curlResult = curl_easy_getinfo(connection->connection,
5457 CURLINFO_SPEED_DOWNLOAD,
5458 &doubleValue);
5459 break;
5460 #endif
5462 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5463 case 10: /* CURLINFO_SPEED_UPLOAD */
5464 resultType = DoubleValue;
5466 curlResult = curl_easy_getinfo(connection->connection,
5467 CURLINFO_SPEED_UPLOAD,
5468 &doubleValue);
5469 break;
5471 #endif
5473 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5474 case 11: /* CURLINFO_HEADER_SIZE */
5475 resultType = LongValue;
5477 curlResult = curl_easy_getinfo(connection->connection,
5478 CURLINFO_HEADER_SIZE,
5479 &longValue);
5480 break;
5481 #endif
5483 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5484 case 12: /* CURLINFO_REQUEST_SIZE */
5485 resultType = LongValue;
5487 curlResult = curl_easy_getinfo(connection->connection,
5488 CURLINFO_REQUEST_SIZE,
5489 &longValue);
5490 break;
5491 #endif
5493 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5494 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5495 resultType = LongValue;
5497 curlResult = curl_easy_getinfo(connection->connection,
5498 CURLINFO_SSL_VERIFYRESULT,
5499 &longValue);
5500 break;
5501 #endif
5503 #if HAVE_DECL_CURLINFO_FILETIME
5504 case 14: /* CURLINFO_FILETIME */
5505 resultType = DoubleValue;
5507 curlResult = curl_easy_getinfo(connection->connection,
5508 CURLINFO_FILETIME,
5509 &doubleValue);
5510 break;
5511 #endif
5513 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5514 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5515 resultType = DoubleValue;
5517 curlResult = curl_easy_getinfo(connection->connection,
5518 CURLINFO_CONTENT_LENGTH_DOWNLOAD,
5519 &doubleValue);
5520 break;
5521 #endif
5523 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5524 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5525 resultType = DoubleValue;
5527 curlResult = curl_easy_getinfo(connection->connection,
5528 CURLINFO_CONTENT_LENGTH_UPLOAD,
5529 &doubleValue);
5530 break;
5531 #endif
5533 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5534 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5535 resultType = DoubleValue;
5537 curlResult = curl_easy_getinfo(connection->connection,
5538 CURLINFO_STARTTRANSFER_TIME,
5539 &doubleValue);
5540 break;
5541 #endif
5543 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5544 case 18: /* CURLINFO_CONTENT_TYPE */
5545 resultType = StringValue;
5547 curlResult = curl_easy_getinfo(connection->connection,
5548 CURLINFO_CONTENT_TYPE,
5549 &strValue);
5550 break;
5551 #endif
5553 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5554 case 19: /* CURLINFO_REDIRECT_TIME */
5555 resultType = DoubleValue;
5557 curlResult = curl_easy_getinfo(connection->connection,
5558 CURLINFO_REDIRECT_TIME,
5559 &doubleValue);
5560 break;
5561 #endif
5563 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5564 case 20: /* CURLINFO_REDIRECT_COUNT */
5565 resultType = LongValue;
5567 curlResult = curl_easy_getinfo(connection->connection,
5568 CURLINFO_REDIRECT_COUNT,
5569 &longValue);
5570 break;
5571 #endif
5573 #if HAVE_DECL_CURLINFO_PRIVATE
5574 case 21: /* CURLINFO_PRIVATE */
5575 resultType = StringValue;
5577 curlResult = curl_easy_getinfo(connection->connection,
5578 CURLINFO_PRIVATE,
5579 &strValue);
5580 break;
5581 #endif
5583 #if HAVE_DECL_CURLINFO_HTTP_CONNECT_CODE
5584 case 22: /* CURLINFO_HTTP_CONNECT_CODE */
5585 resultType = LongValue;
5587 curlResult = curl_easy_getinfo(connection->connection,
5588 CURLINFO_HTTP_CONNECT_CODE,
5589 &longValue);
5590 break;
5591 #endif
5593 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5594 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5595 resultType = LongValue;
5597 curlResult = curl_easy_getinfo(connection->connection,
5598 CURLINFO_HTTPAUTH_AVAIL,
5599 &longValue);
5600 break;
5601 #endif
5603 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5604 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5605 resultType = LongValue;
5607 curlResult = curl_easy_getinfo(connection->connection,
5608 CURLINFO_PROXYAUTH_AVAIL,
5609 &longValue);
5610 break;
5611 #endif
5613 #if HAVE_DECL_CURLINFO_OS_ERRNO
5614 case 25: /* CURLINFO_OS_ERRNO */
5615 resultType = LongValue;
5617 curlResult = curl_easy_getinfo(connection->connection,
5618 CURLINFO_OS_ERRNO,
5619 &longValue);
5620 break;
5621 #endif
5623 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5624 case 26: /* CURLINFO_NUM_CONNECTS */
5625 resultType = LongValue;
5627 curlResult = curl_easy_getinfo(connection->connection,
5628 CURLINFO_NUM_CONNECTS,
5629 &longValue);
5630 break;
5631 #endif
5633 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5634 case 27: /* CURLINFO_SSL_ENGINES */
5635 resultType = StringListValue;
5637 curlResult = curl_easy_getinfo(connection->connection,
5638 CURLINFO_SSL_ENGINES,
5639 &stringListValue);
5640 break;
5641 #endif
5643 #if HAVE_DECL_CURLINFO_COOKIELIST
5644 case 28: /* CURLINFO_COOKIELIST */
5645 resultType = StringListValue;
5647 curlResult = curl_easy_getinfo(connection->connection,
5648 CURLINFO_COOKIELIST,
5649 &stringListValue);
5650 break;
5651 #endif
5653 #if HAVE_DECL_CURLINFO_LASTSOCKET
5654 case 29: /* CURLINFO_LASTSOCKET */
5655 resultType = LongValue;
5657 curlResult = curl_easy_getinfo(connection->connection,
5658 CURLINFO_LASTSOCKET,
5659 &longValue);
5660 break;
5661 #endif
5663 default:
5664 failwith("Invalid CURLINFO Option");
5665 break;
5668 if (curlResult != CURLE_OK)
5669 raiseError(connection, curlResult);
5671 switch (resultType)
5673 case StringValue:
5674 result = alloc(1, StringValue);
5675 Field(result, 0) = copy_string(strValue);
5676 break;
5678 case LongValue:
5679 result = alloc(1, LongValue);
5680 Field(result, 0) = Val_long(longValue);
5681 break;
5683 case DoubleValue:
5684 result = alloc(1, DoubleValue);
5685 Field(result, 0) = copy_double(doubleValue);
5686 break;
5688 case StringListValue:
5689 result = alloc(1, StringListValue);
5690 Field(result, 0) = convertStringList(stringListValue);
5691 break;
5694 CAMLreturn(result);
5698 ** curl_escape helper function
5701 CAMLprim value helper_curl_escape(value str)
5703 CAMLparam1(str);
5704 CAMLlocal1(result);
5705 char *curlResult;
5707 curlResult = curl_escape(String_val(str), string_length(str));
5708 result = copy_string(curlResult);
5709 free(curlResult);
5711 CAMLreturn(result);
5715 ** curl_unescape helper function
5718 CAMLprim value helper_curl_unescape(value str)
5720 CAMLparam1(str);
5721 CAMLlocal1(result);
5722 char *curlResult;
5724 curlResult = curl_unescape(String_val(str), string_length(str));
5725 result = copy_string(curlResult);
5726 free(curlResult);
5728 CAMLreturn(result);
5732 ** curl_getdate helper function
5735 CAMLprim value helper_curl_getdate(value str, value now)
5737 CAMLparam2(str, now);
5738 CAMLlocal1(result);
5739 time_t curlResult;
5740 time_t curlNow;
5742 curlNow = (time_t)Double_val(now);
5743 curlResult = curl_getdate(String_val(str), &curlNow);
5744 result = copy_double((double)curlResult);
5746 CAMLreturn(result);
5750 ** curl_version helper function
5753 CAMLprim value helper_curl_version(void)
5755 CAMLparam0();
5756 CAMLlocal1(result);
5757 char *str;
5759 str = curl_version();
5760 result = copy_string(str);
5762 CAMLreturn(result);
5766 * Curl multi stack support
5768 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5769 * Other exported functions are prefixed with caml_curlm_, some of them
5770 * can/should be decomposed into smaller parts.
5773 #define CURLM_val(v) ((CURLM*)v)
5774 #define Val_CURLM(h) ((value)h)
5776 CAMLprim value caml_curl_multi_init(value unit)
5778 CAMLparam1(unit);
5779 CURLM* h;
5781 h = curl_multi_init();
5783 if (!h)
5784 failwith("caml_curl_multi_init");
5786 CAMLreturn(Val_CURLM(h));
5789 CAMLprim value caml_curl_multi_cleanup(value handle)
5791 CAMLparam1(handle);
5793 if (CURLM_OK != curl_multi_cleanup(CURLM_val(handle)))
5794 failwith("caml_curl_multi_cleanup");
5796 CAMLreturn(Val_unit);
5799 static CURL* curlm_remove_finished(CURLM* multi_handle)
5801 int msgs_in_queue = 0;
5803 while (1)
5805 CURLMsg* msg = curl_multi_info_read(multi_handle, &msgs_in_queue);
5806 if (NULL == msg) return NULL;
5807 if (CURLMSG_DONE == msg->msg)
5809 CURL* easy_handle = msg->easy_handle;
5810 if (CURLM_OK != curl_multi_remove_handle(multi_handle, easy_handle))
5812 //failwith("curlm_remove_finished");
5814 return easy_handle;
5819 CAMLprim value caml_curlm_remove_finished(value v_multi)
5821 CAMLparam1(v_multi);
5822 CAMLlocal1(v_easy);
5823 CURL* handle;
5824 CURLM* multi_handle;
5826 multi_handle = CURLM_val(v_multi);
5828 caml_enter_blocking_section();
5829 handle = curlm_remove_finished(multi_handle);
5830 caml_leave_blocking_section();
5832 if (NULL == handle)
5834 CAMLreturn(Val_none);
5836 else
5838 /* not good */
5839 v_easy = alloc(1, Abstract_tag);
5840 Store_field(v_easy, 0, (value)findConnection(handle));
5841 CAMLreturn(Val_some(v_easy));
5845 static int curlm_wait_data(CURLM* multi_handle)
5847 struct timeval timeout;
5849 fd_set fdread;
5850 fd_set fdwrite;
5851 fd_set fdexcep;
5852 int maxfd;
5854 FD_ZERO(&fdread);
5855 FD_ZERO(&fdwrite);
5856 FD_ZERO(&fdexcep);
5858 /* set a suitable timeout */
5859 timeout.tv_sec = 1;
5860 timeout.tv_usec = 0;
5862 /* get file descriptors from the transfers */
5863 CURLMcode ret = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
5865 if (ret == CURLM_OK && maxfd >= 0)
5867 int rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
5868 if (-1 != rc) return 0;
5869 //printf("select error\n");
5871 else
5873 //printf("curl_multi_fdset error\n");
5875 return 1;
5878 CAMLprim value caml_curlm_wait_data(value v_multi)
5880 CAMLparam1(v_multi);
5881 int ret;
5882 CURLM* h;
5884 h = CURLM_val(v_multi);
5886 caml_enter_blocking_section();
5887 ret = curlm_wait_data(h);
5888 caml_leave_blocking_section();
5890 CAMLreturn(Val_bool(0 == ret));
5893 CAMLprim value caml_curl_multi_add_handle(value v_multi, value v_easy)
5895 CAMLparam2(v_multi,v_easy);
5897 if (CURLM_OK != curl_multi_add_handle(CURLM_val(v_multi), Connection_val(v_easy)->connection))
5898 failwith("caml_curl_multi_add_handle");
5900 CAMLreturn(Val_unit);
5903 CAMLprim value caml_curl_multi_perform_all(value v_multi)
5905 CAMLparam1(v_multi);
5906 CURLM* h;
5907 int still_running = 0;
5909 h = CURLM_val(v_multi);
5911 caml_enter_blocking_section();
5912 while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(h, &still_running));
5913 caml_leave_blocking_section();
5915 CAMLreturn(Val_int(still_running));