tweak code and Makefile for msvc build
[ocurl.git] / curl-helper.c
blob626ecaba7891ea0b31707ab157977d24405fa5b8
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 #if defined(_MSC_VER)
26 #ifdef interface
27 #undef interface
28 #endif
29 #endif
31 void leave_blocking_section(void);
32 void enter_blocking_section(void);
34 #define Val_none Val_int(0)
36 static __inline value
37 Val_some( value v )
39 CAMLparam1( v );
40 CAMLlocal1( some );
41 some = caml_alloc(1, 0);
42 Store_field( some, 0, v );
43 CAMLreturn( some );
46 typedef struct Connection Connection;
47 typedef struct ConnectionList ConnectionList;
49 #define Connection_val(v) ((Connection *)Field(v, 0))
51 enum OcamlValues
53 OcamlWriteCallback,
54 OcamlReadCallback,
55 OcamlErrorBuffer,
56 OcamlPostFields,
57 OcamlHTTPHeader,
58 OcamlHTTPPost,
59 OcamlQuote,
60 OcamlPostQuote,
61 OcamlHeaderCallback,
62 OcamlProgressCallback,
63 OcamlDebugCallback,
64 OcamlHTTP200Aliases,
65 OcamlIOCTLCallback,
66 OcamlSeekFunctionCallback,
68 OcamlURL,
69 OcamlProxy,
70 OcamlUserPWD,
71 OcamlProxyUserPWD,
72 OcamlRange,
73 OcamlReferer,
74 OcamlUserAgent,
75 OcamlFTPPort,
76 OcamlCookie,
77 OcamlHTTPPostStrings,
78 OcamlSSLCert,
79 OcamlSSLCertType,
80 OcamlSSLCertPasswd,
81 OcamlSSLKey,
82 OcamlSSLKeyType,
83 OcamlSSLKeyPasswd,
84 OcamlSSLEngine,
85 OcamlCookieFile,
86 OcamlCustomRequest,
87 OcamlInterface,
88 OcamlCAInfo,
89 OcamlCAPath,
90 OcamlRandomFile,
91 OcamlEGDSocket,
92 OcamlCookieJar,
93 OcamlSSLCipherList,
94 OcamlPrivate,
95 OcamlNETRCFile,
96 OcamlFTPAccount,
97 OcamlCookieList,
98 OcamlFTPAlternativeToUser,
99 OcamlSSHPublicKeyFile,
100 OcamlSSHPrivateKeyFile,
101 OcamlSSHHostPublicKeyMD5,
102 OcamlCopyPostFields,
104 /* Not used, last for size */
105 OcamlValuesSize
108 struct Connection
110 CURL *connection;
111 Connection *next;
112 Connection *prev;
114 value ocamlValues;
116 char *url;
117 char *proxy;
118 char *userPwd;
119 char *proxyUserPwd;
120 char *range;
121 char *errorBuffer;
122 char *postFields;
123 int postFieldSize;
124 char *referer;
125 char *userAgent;
126 char *ftpPort;
127 char *cookie;
128 struct curl_slist *httpHeader;
129 struct curl_httppost *httpPostFirst;
130 struct curl_httppost *httpPostLast;
131 struct curl_slist *httpPostStrings;
132 char *sslCert;
133 char *sslCertType;
134 char *sslCertPasswd;
135 char *sslKey;
136 char *sslKeyType;
137 char *sslKeyPasswd;
138 char *sslEngine;
139 struct curl_slist *quote;
140 struct curl_slist *postQuote;
141 char *cookieFile;
142 char *customRequest;
143 char *interface;
144 char *caInfo;
145 char *caPath;
146 char *randomFile;
147 char *egdSocket;
148 char *cookieJar;
149 char *sslCipherList;
150 char *private;
151 struct curl_slist *http200Aliases;
152 char *netrcFile;
153 char *ftpaccount;
154 char *cookielist;
155 char *ftpAlternativeToUser;
156 char *sshPublicKeyFile;
157 char *sshPrivateKeyFile;
158 char *sshHostPublicKeyMD5;
159 char *copyPostFields;
162 struct ConnectionList
164 Connection *head;
165 Connection *tail;
168 static ConnectionList connectionList = {NULL, NULL};
170 typedef struct CURLErrorMapping CURLErrorMapping;
172 struct CURLErrorMapping
174 char *name;
175 CURLcode error;
178 CURLErrorMapping errorMap[] =
180 #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL
181 {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL},
182 #else
183 {"CURLE_UNSUPPORTED_PROTOCOL", -1},
184 #endif
185 #if HAVE_DECL_CURLE_FAILED_INIT
186 {"CURLE_FAILED_INIT", CURLE_FAILED_INIT},
187 #else
188 {"CURLE_FAILED_INIT", -1},
189 #endif
190 #if HAVE_DECL_CURLE_URL_MALFORMAT
191 {"CURLE_URL_MALFORMAT", CURLE_URL_MALFORMAT},
192 #else
193 {"CURLE_URL_MALFORMAT", -1},
194 #endif
195 #if HAVE_DECL_CURLE_URL_MALFORMAT_USER
196 {"CURLE_URL_MALFORMAT_USER", CURLE_URL_MALFORMAT_USER},
197 #else
198 {"CURLE_URL_MALFORMAT_USER", -1},
199 #endif
200 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_PROXY
201 {"CURLE_COULDNT_RESOLVE_PROXY", CURLE_COULDNT_RESOLVE_PROXY},
202 #else
203 {"CURLE_COULDNT_RESOLVE_PROXY", -1},
204 #endif
205 #if HAVE_DECL_CURLE_COULDNT_RESOLVE_HOST
206 {"CURLE_COULDNT_RESOLVE_HOST", CURLE_COULDNT_RESOLVE_HOST},
207 #else
208 {"CURLE_COULDNT_RESOLVE_HOST", -1},
209 #endif
210 #if HAVE_DECL_CURLE_COULDNT_CONNECT
211 {"CURLE_COULDNT_CONNECT", CURLE_COULDNT_CONNECT},
212 #else
213 {"CURLE_COULDNT_CONNECT", -1},
214 #endif
215 #if HAVE_DECL_CURLE_FTP_WEIRD_SERVER_REPLY
216 {"CURLE_FTP_WEIRD_SERVER_REPLY", CURLE_FTP_WEIRD_SERVER_REPLY},
217 #else
218 {"CURLE_FTP_WEIRD_SERVER_REPLY", -1},
219 #endif
220 #if HAVE_DECL_CURLE_FTP_ACCESS_DENIED
221 {"CURLE_FTP_ACCESS_DENIED", CURLE_FTP_ACCESS_DENIED},
222 #else
223 {"CURLE_FTP_ACCESS_DENIED", -1},
224 #endif
225 #if HAVE_DECL_CURLE_FTP_USER_PASSWORD_INCORRECT
226 {"CURLE_FTP_USER_PASSWORD_INCORRECT", CURLE_FTP_USER_PASSWORD_INCORRECT},
227 #else
228 {"CURLE_FTP_USER_PASSWORD_INCORRECT", -1},
229 #endif
230 #if HAVE_DECL_CURLE_FTP_WEIRD_PASS_REPLY
231 {"CURLE_FTP_WEIRD_PASS_REPLY", CURLE_FTP_WEIRD_PASS_REPLY},
232 #else
233 {"CURLE_FTP_WEIRD_PASS_REPLY", -1},
234 #endif
235 #if HAVE_DECL_CURLE_FTP_WEIRD_USER_REPLY
236 {"CURLE_FTP_WEIRD_USER_REPLY", CURLE_FTP_WEIRD_USER_REPLY},
237 #else
238 {"CURLE_FTP_WEIRD_USER_REPLY", -1},
239 #endif
240 #if HAVE_DECL_CURLE_FTP_WEIRD_PASV_REPLY
241 {"CURLE_FTP_WEIRD_PASV_REPLY", CURLE_FTP_WEIRD_PASV_REPLY},
242 #else
243 {"CURLE_FTP_WEIRD_PASV_REPLY", -1},
244 #endif
245 #if HAVE_DECL_CURLE_FTP_WEIRD_227_FORMAT
246 {"CURLE_FTP_WEIRD_227_FORMAT", CURLE_FTP_WEIRD_227_FORMAT},
247 #else
248 {"CURLE_FTP_WEIRD_227_FORMAT", -1},
249 #endif
250 #if HAVE_DECL_CURLE_FTP_CANT_GET_HOST
251 {"CURLE_FTP_CANT_GET_HOST", CURLE_FTP_CANT_GET_HOST},
252 #else
253 {"CURLE_FTP_CANT_GET_HOST", -1},
254 #endif
255 #if HAVE_DECL_CURLE_FTP_CANT_RECONNECT
256 {"CURLE_FTP_CANT_RECONNECT", CURLE_FTP_CANT_RECONNECT},
257 #else
258 {"CURLE_FTP_CANT_RECONNECT", -1},
259 #endif
260 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_BINARY
261 {"CURLE_FTP_COULDNT_SET_BINARY", CURLE_FTP_COULDNT_SET_BINARY},
262 #else
263 {"CURLE_FTP_COULDNT_SET_BINARY", -1},
264 #endif
265 #if HAVE_DECL_CURLE_PARTIAL_FILE
266 {"CURLE_PARTIAL_FILE", CURLE_PARTIAL_FILE},
267 #else
268 {"CURLE_PARTIAL_FILE", -1},
269 #endif
270 #if HAVE_DECL_CURLE_FTP_COULDNT_RETR_FILE
271 {"CURLE_FTP_COULDNT_RETR_FILE", CURLE_FTP_COULDNT_RETR_FILE},
272 #else
273 {"CURLE_FTP_COULDNT_RETR_FILE", -1},
274 #endif
275 #if HAVE_DECL_CURLE_FTP_WRITE_ERROR
276 {"CURLE_FTP_WRITE_ERROR", CURLE_FTP_WRITE_ERROR},
277 #else
278 {"CURLE_FTP_WRITE_ERROR", -1},
279 #endif
280 #if HAVE_DECL_CURLE_FTP_QUOTE_ERROR
281 {"CURLE_FTP_QUOTE_ERROR", CURLE_FTP_QUOTE_ERROR},
282 #else
283 {"CURLE_FTP_QUOTE_ERROR", -1},
284 #endif
285 #if HAVE_DECL_CURLE_HTTP_NOT_FOUND
286 {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND},
287 #else
288 {"CURLE_HTTP_NOT_FOUND", -1},
289 #endif
290 #if HAVE_DECL_CURLE_WRITE_ERROR
291 {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR},
292 #else
293 {"CURLE_WRITE_ERROR", -1},
294 #endif
295 #if HAVE_DECL_CURLE_MALFORMAT_USER
296 {"CURLE_MALFORMAT_USER", CURLE_MALFORMAT_USER},
297 #else
298 {"CURLE_MALFORMAT_USER", -1},
299 #endif
300 #if HAVE_DECL_CURLE_FTP_COULDNT_STOR_FILE
301 {"CURLE_FTP_COULDNT_STOR_FILE", CURLE_FTP_COULDNT_STOR_FILE},
302 #else
303 {"CURLE_FTP_COULDNT_STOR_FILE", -1},
304 #endif
305 #if HAVE_DECL_CURLE_READ_ERROR
306 {"CURLE_READ_ERROR", CURLE_READ_ERROR},
307 #else
308 {"CURLE_READ_ERROR", -1},
309 #endif
310 #if HAVE_DECL_CURLE_OUT_OF_MEMORY
311 {"CURLE_OUT_OF_MEMORY", CURLE_OUT_OF_MEMORY},
312 #else
313 {"CURLE_OUT_OF_MEMORY", -1},
314 #endif
315 #if HAVE_DECL_CURLE_OPERATION_TIMEOUTED
316 {"CURLE_OPERATION_TIMEOUTED", CURLE_OPERATION_TIMEOUTED},
317 #else
318 {"CURLE_OPERATION_TIMEOUTED", -1},
319 #endif
320 #if HAVE_DECL_CURLE_FTP_COULDNT_SET_ASCII
321 {"CURLE_FTP_COULDNT_SET_ASCII", CURLE_FTP_COULDNT_SET_ASCII},
322 #else
323 {"CURLE_FTP_COULDNT_SET_ASCII", -1},
324 #endif
325 #if HAVE_DECL_CURLE_FTP_PORT_FAILED
326 {"CURLE_FTP_PORT_FAILED", CURLE_FTP_PORT_FAILED},
327 #else
328 {"CURLE_FTP_PORT_FAILED", -1},
329 #endif
330 #if HAVE_DECL_CURLE_FTP_COULDNT_USE_REST
331 {"CURLE_FTP_COULDNT_USE_REST", CURLE_FTP_COULDNT_USE_REST},
332 #else
333 {"CURLE_FTP_COULDNT_USE_REST", -1},
334 #endif
335 #if HAVE_DECL_CURLE_FTP_COULDNT_GET_SIZE
336 {"CURLE_FTP_COULDNT_GET_SIZE", CURLE_FTP_COULDNT_GET_SIZE},
337 #else
338 {"CURLE_FTP_COULDNT_GET_SIZE", -1},
339 #endif
340 #if HAVE_DECL_CURLE_HTTP_RANGE_ERROR
341 {"CURLE_HTTP_RANGE_ERROR", CURLE_HTTP_RANGE_ERROR},
342 #else
343 {"CURLE_HTTP_RANGE_ERROR", -1},
344 #endif
345 #if HAVE_DECL_CURLE_HTTP_POST_ERROR
346 {"CURLE_HTTP_POST_ERROR", CURLE_HTTP_POST_ERROR},
347 #else
348 {"CURLE_HTTP_POST_ERROR", -1},
349 #endif
350 #if HAVE_DECL_CURLE_SSL_CONNECT_ERROR
351 {"CURLE_SSL_CONNECT_ERROR", CURLE_SSL_CONNECT_ERROR},
352 #else
353 {"CURLE_SSL_CONNECT_ERROR", -1},
354 #endif
355 #if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME
356 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME},
357 #else
358 {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1},
359 #endif
360 #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE
361 {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE},
362 #else
363 {"CURLE_FILE_COULDNT_READ_FILE", -1},
364 #endif
365 #if HAVE_DECL_CURLE_LDAP_CANNOT_BIND
366 {"CURLE_LDAP_CANNOT_BIND", CURLE_LDAP_CANNOT_BIND},
367 #else
368 {"CURLE_LDAP_CANNOT_BIND", -1},
369 #endif
370 #if HAVE_DECL_CURLE_LDAP_SEARCH_FAILED
371 {"CURLE_LDAP_SEARCH_FAILED", CURLE_LDAP_SEARCH_FAILED},
372 #else
373 {"CURLE_LDAP_SEARCH_FAILED", -1},
374 #endif
375 #if HAVE_DECL_CURLE_LIBRARY_NOT_FOUND
376 {"CURLE_LIBRARY_NOT_FOUND", CURLE_LIBRARY_NOT_FOUND},
377 #else
378 {"CURLE_LIBRARY_NOT_FOUND", -1},
379 #endif
380 #if HAVE_DECL_CURLE_FUNCTION_NOT_FOUND
381 {"CURLE_FUNCTION_NOT_FOUND", CURLE_FUNCTION_NOT_FOUND},
382 #else
383 {"CURLE_FUNCTION_NOT_FOUND", -1},
384 #endif
385 #if HAVE_DECL_CURLE_ABORTED_BY_CALLBACK
386 {"CURLE_ABORTED_BY_CALLBACK", CURLE_ABORTED_BY_CALLBACK},
387 #else
388 {"CURLE_ABORTED_BY_CALLBACK", -1},
389 #endif
390 #if HAVE_DECL_CURLE_BAD_FUNCTION_ARGUMENT
391 {"CURLE_BAD_FUNCTION_ARGUMENT", CURLE_BAD_FUNCTION_ARGUMENT},
392 #else
393 {"CURLE_BAD_FUNCTION_ARGUMENT", -1},
394 #endif
395 #if HAVE_DECL_CURLE_BAD_CALLING_ORDER
396 {"CURLE_BAD_CALLING_ORDER", CURLE_BAD_CALLING_ORDER},
397 #else
398 {"CURLE_BAD_CALLING_ORDER", -1},
399 #endif
400 #if HAVE_DECL_CURLE_HTTP_PORT_FAILED
401 {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED},
402 #else
403 {"CURLE_HTTP_PORT_FAILED", -1},
404 #endif
405 #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED
406 {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED},
407 #else
408 {"CURLE_BAD_PASSWORD_ENTERED", -1},
409 #endif
410 #if HAVE_DECL_CURLE_TOO_MANY_REDIRECTS
411 {"CURLE_TOO_MANY_REDIRECTS", CURLE_TOO_MANY_REDIRECTS},
412 #else
413 {"CURLE_TOO_MANY_REDIRECTS", -1},
414 #endif
415 #if HAVE_DECL_CURLE_UNKNOWN_TELNET_OPTION
416 {"CURLE_UNKNOWN_TELNET_OPTION", CURLE_UNKNOWN_TELNET_OPTION},
417 #else
418 {"CURLE_UNKNOWN_TELNET_OPTION", -1},
419 #endif
420 #if HAVE_DECL_CURLE_TELNET_OPTION_SYNTAX
421 {"CURLE_TELNET_OPTION_SYNTAX", CURLE_TELNET_OPTION_SYNTAX},
422 #else
423 {"CURLE_TELNET_OPTION_SYNTAX", -1},
424 #endif
425 #if HAVE_DECL_CURLE_SSL_PEER_CERTIFICATE
426 {"CURLE_SSL_PEER_CERTIFICATE", CURLE_SSL_PEER_CERTIFICATE},
427 #else
428 {"CURLE_SSL_PEER_CERTIFICATE", -1},
429 #endif
430 #if HAVE_DECL_CURLE_GOT_NOTHING
431 {"CURLE_GOT_NOTHING", CURLE_GOT_NOTHING},
432 #else
433 {"CURLE_GOT_NOTHING", -1},
434 #endif
435 #if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND
436 {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND},
437 #else
438 {"CURLE_SSL_ENGINE_NOT_FOUND", -1},
439 #endif
440 #if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED
441 {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED},
442 #else
443 {"CURLE_SSL_ENGINE_SET_FAILED", -1},
444 #endif
445 #if HAVE_DECL_CURLE_SEND_ERROR
446 {"CURLE_SEND_ERROR", CURLE_SEND_ERROR},
447 #else
448 {"CURLE_SEND_ERROR", -1},
449 #endif
450 #if HAVE_DECL_CURLE_RECV_ERROR
451 {"CURLE_RECV_ERROR", CURLE_RECV_ERROR},
452 #else
453 {"CURLE_RECV_ERROR", -1},
454 #endif
455 #if HAVE_DECL_CURLE_SHARE_IN_USE
456 {"CURLE_SHARE_IN_USE", CURLE_SHARE_IN_USE},
457 #else
458 {"CURLE_SHARE_IN_USE", -1},
459 #endif
460 #if HAVE_DECL_CURLE_SSL_CERTPROBLEM
461 {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM},
462 #else
463 {"CURLE_SSL_CERTPROBLEN", -1},
464 #endif
465 #if HAVE_DECL_CURLE_SSL_CIPHER
466 {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER},
467 #else
468 {"CURLE_SSL_CIPHER", -1},
469 #endif
470 #if HAVE_DECL_CURLE_SSL_CACERT
471 {"CURLE_SSL_CACERT", CURLE_SSL_CACERT},
472 #else
473 {"CURLE_SSL_CACERT", -1},
474 #endif
475 #if HAVE_DECL_CURLE_BAD_CONTENT_ENCODING
476 {"CURLE_BAD_CONTENT_ENCODING", CURLE_BAD_CONTENT_ENCODING},
477 #else
478 {"CURLE_BAD_CONTENT_ENCODING", -1},
479 #endif
480 #if HAVE_DECL_CURLE_LDAP_INVALID_URL
481 {"CURLE_LDAP_INVALID_URL", CURLE_LDAP_INVALID_URL},
482 #else
483 {"CURLE_LDAP_INVALID_URL", -1},
484 #endif
485 #if HAVE_DECL_CURLE_FILESIZE_EXCEEDED
486 {"CURLE_FILESIZE_EXCEEDED", CURLE_FILESIZE_EXCEEDED},
487 #else
488 {"CURLE_FILESIZE_EXCEEDED", -1},
489 #endif
490 #if HAVE_DECL_CURLE_FTP_SSL_FAILED
491 {"CURLE_FTP_SSL_FAILED", CURLE_FTP_SSL_FAILED},
492 #else
493 {"CURLE_FTP_SSL_FAILED", -1},
494 #endif
495 #if HAVE_DECL_CURLE_SEND_FAIL_REWIND
496 {"CURLE_SEND_FAIL_REWIND", CURLE_SEND_FAIL_REWIND},
497 #else
498 {"CURLE_SEND_FAIL_REWIND", -1},
499 #endif
500 #if HAVE_DECL_CURLE_SSL_ENGINE_INITFAILED
501 {"CURLE_SSL_ENGINE_INITFAILED", CURLE_SSL_ENGINE_INITFAILED},
502 #else
503 {"CURLE_SSL_ENGINE_INITFAILED", -1},
504 #endif
505 #if HAVE_DECL_CURLE_LOGIN_DENIED
506 {"CURLE_LOGIN_DENIED", CURLE_LOGIN_DENIED},
507 #else
508 {"CURLE_LOGIN_DENIED", -1},
509 #endif
510 #if HAVE_DECL_CURLE_TFTP_NOTFOUND
511 {"CURLE_TFTP_NOTFOUND", CURLE_TFTP_NOTFOUND},
512 #else
513 {"CURLE_TFTP_NOTFOUND", -1},
514 #endif
515 #if HAVE_DECL_CURLE_TFTP_PERM
516 {"CURLE_TFTP_PERM", CURLE_TFTP_PERM},
517 #else
518 {"CURLE_TFTP_PERM", -1},
519 #endif
520 #if HAVE_DECL_CURLE_REMOTE_DISK_FULL
521 {"CURLE_REMOTE_DISK_FULL", CURLE_REMOTE_DISK_FULL},
522 #else
523 {"CURLE_REMOTE_DISK_FULL", -1},
524 #endif
525 #if HAVE_DECL_CURLE_TFTP_ILLEGAL
526 {"CURLE_TFTP_ILLEGAL", CURLE_TFTP_ILLEGAL},
527 #else
528 {"CURLE_TFTP_ILLEGAL", -1},
529 #endif
530 #if HAVE_DECL_CURLE_TFTP_UNKNOWNID
531 {"CURLE_TFTP_UNKNOWNID", CURLE_TFTP_UNKNOWNID},
532 #else
533 {"CURLE_TFTP_UNKNOWNID", -1},
534 #endif
535 #if HAVE_DECL_CURLE_REMOTE_FILE_EXISTS
536 {"CURLE_REMOTE_FILE_EXISTS", CURLE_REMOTE_FILE_EXISTS},
537 #else
538 {"CURLE_REMOTE_FILE_EXISTS", -1},
539 #endif
540 #if HAVE_DECL_CURLE_TFTP_NOSUCHUSER
541 {"CURLE_TFTP_NOSUCHUSER", CURLE_TFTP_NOSUCHUSER},
542 #else
543 {"CURLE_TFTP_NOSUCHUSER", -1},
544 #endif
545 #if HAVE_DECL_CURLE_CONV_FAILED
546 {"CURLE_CONV_FAILED", CURLE_CONV_FAILED},
547 #else
548 {"CURLE_CONV_FAILED", -1},
549 #endif
550 #if HAVE_DECL_CURLE_CONV_REQUIRED
551 {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED},
552 #else
553 {"CURLE_CONV_REQUIRED", -1},
554 #endif
555 #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE
556 {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE},
557 #else
558 {"CURLE_SSL_CACERT_BADFILE", -1},
559 #endif
560 #if HAVE_DECL_CURLE_REMOTE_FILE_NOT_FOUND
561 {"CURLE_REMOTE_FILE_NOT_FOUND", CURLE_REMOTE_FILE_NOT_FOUND},
562 #else
563 {"CURLE_REMOTE_FILE_NOT_FOUND", -1},
564 #endif
565 #if HAVE_DECL_CURLE_SSH
566 {"CURLE_SSH", CURLE_SSH},
567 #else
568 {"CURLE_SSH", -1},
569 #endif
570 #if HAVE_DECL_CURLE_SSL_SHUTDOWN_FAILED
571 {"CURLE_SSL_SHUTDOWN_FAILED", CURLE_SSL_SHUTDOWN_FAILED},
572 #else
573 {"CURLE_SSL_SHUTDOWN_FAILED", -1},
574 #endif
575 #if HAVE_DECL_CURLE_AGAIN
576 {"CURLE_AGAIN", CURLE_AGAIN},
577 #else
578 {"CURLE_AGAIN", -1},
579 #endif
580 {"CURLE_OK", CURLE_OK},
581 {NULL, 0}
584 typedef struct CURLOptionMapping CURLOptionMapping;
586 struct CURLOptionMapping
588 void (*optionHandler)(Connection *, value);
589 char *name;
590 CURLoption option;
593 CURLOptionMapping unimplementedOptionMap[] =
595 {NULL, "CURLOPT_STDERR", CURLOPT_STDERR},
596 {NULL, NULL, 0}
599 static void handleWriteFunction(Connection *, value);
600 static void handleReadFunction(Connection *, value);
601 static void handleInFileSize(Connection *, value);
602 static void handleURL(Connection *, value);
603 static void handleProxy(Connection *, value);
604 static void handleProxyPort(Connection *, value);
605 static void handleHTTPProxyTunnel(Connection *, value);
606 static void handleVerbose(Connection *, value);
607 static void handleHeader(Connection *, value);
608 static void handleNoProgress(Connection *, value);
609 static void handleNoSignal(Connection *, value);
610 static void handleNoBody(Connection *, value);
611 static void handleFailOnError(Connection *, value);
612 static void handleUpload(Connection *, value);
613 static void handlePost(Connection *, value);
614 static void handleFTPListOnly(Connection *, value);
615 static void handleFTPAppend(Connection *, value);
616 static void handleNETRC(Connection *, value);
617 static void handleEncoding(Connection *, value);
618 static void handleFollowLocation(Connection *, value);
619 static void handleTransferText(Connection *, value);
620 static void handlePut(Connection *, value);
621 static void handleUserPwd(Connection *, value);
622 static void handleProxyUserPwd(Connection *, value);
623 static void handleRange(Connection *, value);
624 static void handleErrorBuffer(Connection *, value);
625 static void handleTimeout(Connection *, value);
626 static void handlePostFields(Connection *, value);
627 static void handlePostFieldSize(Connection *, value);
628 static void handleReferer(Connection *, value);
629 static void handleUserAgent(Connection *, value);
630 static void handleFTPPort(Connection *, value);
631 static void handleLowSpeedLimit(Connection *, value);
632 static void handleLowSpeedTime(Connection *, value);
633 static void handleResumeFrom(Connection *, value);
634 static void handleCookie(Connection *, value);
635 static void handleHTTPHeader(Connection *, value);
636 static void handleHTTPPost(Connection *, value);
637 static void handleSSLCert(Connection *, value);
638 static void handleSSLCertType(Connection *, value);
639 static void handleSSLCertPasswd(Connection *, value);
640 static void handleSSLKey(Connection *, value);
641 static void handleSSLKeyType(Connection *, value);
642 static void handleSSLKeyPasswd(Connection *, value);
643 static void handleSSLEngine(Connection *, value);
644 static void handleSSLEngineDefault(Connection *, value);
645 static void handleCRLF(Connection *, value);
646 static void handleQuote(Connection *, value);
647 static void handlePostQuote(Connection *, value);
648 static void handleHeaderFunction(Connection *, value);
649 static void handleCookieFile(Connection *, value);
650 static void handleSSLVersion(Connection *, value);
651 static void handleTimeCondition(Connection *, value);
652 static void handleTimeValue(Connection *, value);
653 static void handleCustomRequest(Connection *, value);
654 static void handleInterface(Connection *, value);
655 static void handleKRB4Level(Connection *, value);
656 static void handleProgressFunction(Connection *, value);
657 static void handleSSLVerifyPeer(Connection *, value);
658 static void handleCAInfo(Connection *, value);
659 static void handleCAPath(Connection *, value);
660 static void handleFileTime(Connection *, value);
661 static void handleMaxRedirs(Connection *, value);
662 static void handleMaxConnects(Connection *, value);
663 static void handleClosePolicy(Connection *, value);
664 static void handleFreshConnect(Connection *, value);
665 static void handleForbidReuse(Connection *, value);
666 static void handleRandomFile(Connection *, value);
667 static void handleEGDSocket(Connection *, value);
668 static void handleConnectTimeout(Connection *, value);
669 static void handleHTTPGet(Connection *, value);
670 static void handleSSLVerifyHost(Connection *, value);
671 static void handleCookieJar(Connection *, value);
672 static void handleSSLCipherList(Connection *, value);
673 static void handleHTTPVersion(Connection *, value);
674 static void handleFTPUseEPSV(Connection *, value);
675 static void handleDNSCacheTimeout(Connection *, value);
676 static void handleDNSUseGlobalCache(Connection *, value);
677 static void handleDebugFunction(Connection *, value);
678 static void handlePrivate(Connection *, value);
679 static void handleHTTP200Aliases(Connection *, value);
680 static void handleUnrestrictedAuth(Connection *, value);
681 static void handleFTPUseEPRT(Connection *, value);
682 static void handleHTTPAuth(Connection *, value);
683 static void handleFTPCreateMissingDirs(Connection *, value);
684 static void handleProxyAuth(Connection *, value);
685 static void handleFTPResponseTimeout(Connection *, value);
686 static void handleIPResolve(Connection *, value);
687 static void handleMaxFileSize(Connection *, value);
688 static void handleInFileSizeLarge(Connection *, value);
689 static void handleResumeFromLarge(Connection *, value);
690 static void handleMaxFileSizeLarge(Connection *, value);
691 static void handleNETRCFile(Connection *, value);
692 static void handleFTPSSL(Connection *, value);
693 static void handlePostFieldSizeLarge(Connection *, value);
694 static void handleTCPNoDelay(Connection *, value);
695 static void handleFTPSSLAuth(Connection *, value);
696 static void handleIOCTLFunction(Connection *, value);
697 static void handleFTPAccount(Connection *, value);
698 static void handleCookieList(Connection *, value);
699 static void handleIgnoreContentLength(Connection *, value);
700 static void handleFTPSkipPASVIP(Connection *, value);
701 static void handleFTPFileMethod(Connection *, value);
702 static void handleLocalPort(Connection *, value);
703 static void handleLocalPortRange(Connection *, value);
704 static void handleConnectOnly(Connection *, value);
705 static void handleMaxSendSpeedLarge(Connection *, value);
706 static void handleMaxRecvSpeedLarge(Connection *, value);
707 static void handleFTPAlternativeToUser(Connection *, value);
708 static void handleSSLSessionIdCache(Connection *, value);
709 static void handleSSHAuthTypes(Connection *, value);
710 static void handleSSHPublicKeyFile(Connection *, value);
711 static void handleSSHPrivateKeyFile(Connection *, value);
712 static void handleFTPSSLCCC(Connection *, value);
713 static void handleTimeoutMS(Connection *, value);
714 static void handleConnectTimeoutMS(Connection *, value);
715 static void handleHTTPTransferDecoding(Connection *, value);
716 static void handleHTTPContentDecoding(Connection *, value);
717 static void handleNewFilePerms(Connection *, value);
718 static void handleNewDirectoryPerms(Connection *, value);
719 static void handlePost301(Connection *, value);
720 static void handleSSHHostPublicKeyMD5(Connection *, value);
721 static void handleCopyPostFields(Connection *, value);
722 static void handleProxyTransferMode(Connection *, value);
723 static void handleSeekFunction(Connection *, value);
725 CURLOptionMapping implementedOptionMap[] =
727 {handleWriteFunction, "CURLOPT_WRITEFUNCTION", CURLOPT_WRITEFUNCTION},
728 {handleReadFunction, "CURLOPT_READFUNCTION", CURLOPT_READFUNCTION},
729 {handleInFileSize, "CURLOPT_INFILESIZE", CURLOPT_INFILESIZE},
730 {handleURL, "CURLOPT_URL", CURLOPT_URL},
731 {handleProxy, "CURLOPT_PROXY", CURLOPT_PROXY},
732 {handleProxyPort, "CURLOPT_PROXYPORT", CURLOPT_PROXYPORT},
733 {handleHTTPProxyTunnel, "CURLOPT_HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL},
734 {handleVerbose, "CURLOPT_VERBOSE", CURLOPT_VERBOSE},
735 {handleHeader, "CURLOPT_HEADER", CURLOPT_HEADER},
736 {handleNoProgress, "CURLOPT_NOPROGRESS", CURLOPT_NOPROGRESS},
737 #if HAVE_DECL_CURLOPT_NOSIGNAL
738 {handleNoSignal, "CURLOPT_NOSIGNAL", CURLOPT_NOSIGNAL},
739 #else
740 {handleNoSignal, "CURLOPT_NOSIGNAL", 0},
741 #endif
742 {handleNoBody, "CURLOPT_NOBODY", CURLOPT_NOBODY},
743 {handleFailOnError, "CURLOPT_FAILONERROR", CURLOPT_FAILONERROR},
744 {handleUpload, "CURLOPT_UPLOAD", CURLOPT_UPLOAD},
745 {handlePost, "CURLOPT_POST", CURLOPT_POST},
746 {handleFTPListOnly, "CURLOPT_FTPLISTONLY", CURLOPT_FTPLISTONLY},
747 {handleFTPAppend, "CURLOPT_FTPAPPEND", CURLOPT_FTPAPPEND},
748 {handleNETRC, "CURLOPT_NETRC", CURLOPT_NETRC},
749 #if HAVE_DECL_CURLOPT_ENCODING
750 {handleEncoding, "CURLOPT_ENCODING", CURLOPT_ENCODING},
751 #else
752 {handleEncoding, "CURLOPT_ENCODING", 0},
753 #endif
754 {handleFollowLocation, "CURLOPT_FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION},
755 {handleTransferText, "CURLOPT_TRANSFERTEXT", CURLOPT_TRANSFERTEXT},
756 {handlePut, "CURLOPT_PUT", CURLOPT_PUT},
757 {handleUserPwd, "CURLOPT_USERPWD", CURLOPT_USERPWD},
758 {handleProxyUserPwd, "CURLOPT_PROXYUSERPWD", CURLOPT_PROXYUSERPWD},
759 {handleRange, "CURLOPT_RANGE", CURLOPT_RANGE},
760 {handleErrorBuffer, "CURLOPT_ERRORBUFFER", CURLOPT_ERRORBUFFER},
761 {handleTimeout, "CURLOPT_TIMEOUT", CURLOPT_TIMEOUT},
762 {handlePostFields, "CURLOPT_POSTFIELDS", CURLOPT_POSTFIELDS},
763 {handlePostFieldSize, "CURLOPT_POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE},
764 {handleReferer, "CURLOPT_REFERER", CURLOPT_REFERER},
765 {handleUserAgent, "CURLOPT_USERAGENT", CURLOPT_USERAGENT},
766 {handleFTPPort, "CURLOPT_FTPPORT", CURLOPT_FTPPORT},
767 {handleLowSpeedLimit, "CURLOPT_LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT},
768 {handleLowSpeedTime, "CURLOPT_LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME},
769 {handleResumeFrom, "CURLOPT_RESUME_FROM", CURLOPT_RESUME_FROM},
770 {handleCookie, "CURLOPT_COOKIE", CURLOPT_COOKIE},
771 {handleHTTPHeader, "CURLOPT_HTTPHEADER", CURLOPT_HTTPHEADER},
772 {handleHTTPPost, "CURLOPT_HTTPPOST", CURLOPT_HTTPPOST},
773 {handleSSLCert, "CURLOPT_SSLCERT", CURLOPT_SSLCERT},
774 {handleSSLCertType, "CURLOPT_SSLCERTTYPE", CURLOPT_SSLCERTTYPE},
775 {handleSSLCertPasswd, "CURLOPT_SSLCERTPASSWD", CURLOPT_SSLCERTPASSWD},
776 {handleSSLKey, "CURLOPT_SSLKEY", CURLOPT_SSLKEY},
777 {handleSSLKeyType, "CURLOPT_SSLKEYTYPE", CURLOPT_SSLKEYTYPE},
778 {handleSSLKeyPasswd, "CURLOPT_SSLKEYPASSWD", CURLOPT_SSLKEYPASSWD},
779 {handleSSLEngine, "CURLOPT_SSLENGINE", CURLOPT_SSLENGINE},
780 {handleSSLEngineDefault, "CURLOPT_SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT},
781 {handleCRLF, "CURLOPT_CRLF", CURLOPT_CRLF},
782 {handleQuote, "CURLOPT_QUOTE", CURLOPT_QUOTE},
783 {handlePostQuote, "CURLOPT_POSTQUOTE", CURLOPT_POSTQUOTE},
784 {handleHeaderFunction, "CURLOPT_HEADERFUNCTION", CURLOPT_HEADERFUNCTION},
785 {handleCookieFile, "CURLOPT_COOKIEFILE", CURLOPT_COOKIEFILE},
786 {handleSSLVersion, "CURLOPT_SSLVERSION", CURLOPT_SSLVERSION},
787 {handleTimeCondition, "CURLOPT_TIMECONDITION", CURLOPT_TIMECONDITION},
788 {handleTimeValue, "CURLOPT_TIMEVALUE", CURLOPT_TIMEVALUE},
789 {handleCustomRequest, "CURLOPT_CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST},
790 {handleInterface, "CURLOPT_INTERFACE", CURLOPT_INTERFACE},
791 {handleKRB4Level, "CURLOPT_KRB4LEVEL", CURLOPT_KRB4LEVEL},
792 {handleProgressFunction, "CURLOPT_PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION},
793 {handleSSLVerifyPeer, "CURLOPT_SSLVERIFYPEER", CURLOPT_SSL_VERIFYPEER},
794 {handleCAInfo, "CURLOPT_CAINFO", CURLOPT_CAINFO},
795 {handleCAPath, "CURLOPT_CAPATH", CURLOPT_CAPATH},
796 {handleFileTime, "CURLOPT_FILETIME", CURLOPT_FILETIME},
797 {handleMaxRedirs, "CURLOPT_MAXREDIRS", CURLOPT_MAXREDIRS},
798 {handleMaxConnects, "CURLOPT_MAXCONNECTS", CURLOPT_MAXCONNECTS},
799 {handleClosePolicy, "CURLOPT_CLOSEPOLICY", CURLOPT_CLOSEPOLICY},
800 {handleFreshConnect, "CURLOPT_FRESH_CONNECT", CURLOPT_FRESH_CONNECT},
801 {handleForbidReuse, "CURLOPT_FORBID_REUSE", CURLOPT_FORBID_REUSE},
802 {handleRandomFile, "CURLOPT_RANDOM_FILE", CURLOPT_RANDOM_FILE},
803 {handleEGDSocket, "CURLOPT_EGDSOCKET", CURLOPT_EGDSOCKET},
804 {handleConnectTimeout, "CURLOPT_CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT},
805 {handleHTTPGet, "CURLOPT_HTTPGET", CURLOPT_HTTPGET},
806 {handleSSLVerifyHost, "CURLOPT_SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST},
807 {handleCookieJar, "CURLOPT_COOKIEJAR", CURLOPT_COOKIEJAR},
808 {handleSSLCipherList, "CURLOPT_SSL_CIPHERLIST", CURLOPT_SSL_CIPHER_LIST},
809 {handleHTTPVersion, "CURLOPT_HTTP_VERSION", CURLOPT_HTTP_VERSION},
810 {handleFTPUseEPSV, "CURLOPT_FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV},
811 {handleDNSCacheTimeout, "CURLOPT_DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT},
812 {handleDNSUseGlobalCache, "CURLOPT_DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE},
813 {handleDebugFunction, "CURLOPT_DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION},
814 #if HAVE_DECL_CURLOPT_PRIVATE
815 {handlePrivate, "CURLOPT_PRIVATE", CURLOPT_PRIVATE},
816 #else
817 {handlePrivate, "CURLOPT_PRIVATE", 0},
818 #endif
819 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
820 {handleHTTP200Aliases, "CURLOPT_HTTP200ALIASES", CURLOPT_HTTP200ALIASES},
821 #else
822 {handleHTTP200Aliases, "CURLOPT_HTTP200ALIASES", 0},
823 #endif
824 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
825 {handleUnrestrictedAuth, "CURLOPT_UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH},
826 #else
827 {handleUnrestrictedAuth, "CURLOPT_UNRESTRICTED_AUTH", 0},
828 #endif
829 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
830 {handleFTPUseEPRT, "CURLOPT_FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT},
831 #else
832 {handleFTPUseEPRT, "CURLOPT_FTP_USE_EPRT", 0},
833 #endif
834 #if HAVE_DECL_CURLOPT_HTTPAUTH
835 {handleHTTPAuth, "CURLOPT_HTTPAUTH", CURLOPT_HTTPAUTH},
836 #else
837 {handleHTTPAuth, "CURLOPT_HTTPAUTH", 0},
838 #endif
839 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
840 {handleFTPCreateMissingDirs, "CURLOPT_FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS},
841 #else
842 {handleFTPCreateMissingDirs, "CURLOPT_FTP_CREATE_MISSING_DIRS", 0},
843 #endif
844 #if HAVE_DECL_CURLOPT_PROXYAUTH
845 {handleProxyAuth, "CURLOPT_PROXYAUTH", CURLOPT_PROXYAUTH},
846 #else
847 {handleProxyAuth, "CURLOPT_PROXYAUTH", 0},
848 #endif
849 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
850 {handleFTPResponseTimeout, "CURLOPT_FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT},
851 #else
852 {handleFTPResponseTimeout, "CURLOPT_FTP_RESPONSE_TIMEOUT", 0},
853 #endif
854 #if HAVE_DECL_CURLOPT_IPRESOLVE
855 {handleIPResolve, "CURLOPT_IPRESOLVE", CURLOPT_IPRESOLVE},
856 #else
857 {handleIPResolve, "CURLOPT_IPRESOLVE", 0},
858 #endif
859 #if HAVE_DECL_CURLOPT_MAXFILESIZE
860 {handleMaxFileSize, "CURLOPT_MAXFILESIZE", CURLOPT_MAXFILESIZE},
861 #else
862 {handleMaxFileSize, "CURLOPT_MAXFILESIZE", 0},
863 #endif
864 #if HAVE_DECL_CURLOPT_INFILSIZE_LARGE
865 {handleInFileSizeLarge, "CURLOPT_INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE},
866 #else
867 {handleInFileSizeLarge, "CURLOPT_INFILESIZE_LARGE", 0},
868 #endif
869 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
870 {handleResumeFromLarge, "CURLOPT_RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE},
871 #else
872 {handleResumeFromLarge, "CURLOPT_RESUME_FROM_LARGE", 0},
873 #endif
874 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
875 {handleMaxFileSizeLarge, "CURLOPT_MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE},
876 #else
877 {handleMaxFileSizeLarge, "CURLOPT_MAXFILESIZE_LARGE", 0},
878 #endif
879 #if HAVE_DECL_CURLOPT_NETRC_FILE
880 {handleNETRCFile, "CURLOPT_NETRC_FILE", CURLOPT_NETRC_FILE},
881 #else
882 {handleNETRCFile, "CURLOPT_NETRC_FILE", 0},
883 #endif
884 #if HAVE_DECL_CURLOPT_FTP_SSL
885 {handleFTPSSL, "CURLOPT_FTP_SSL", CURLOPT_FTP_SSL},
886 #else
887 {handleFTPSSL, "CURLOPT_FTP_SSL", 0},
888 #endif
889 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
890 {handlePostFieldSizeLarge, "CURLOPT_POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE},
891 #else
892 {handlePostFieldSizeLarge, "CURLOPT_POSTFIELDSIZE_LARGE", 0},
893 #endif
894 #if HAVE_DECL_CURLOPT_TCP_NODELAY
895 {handleTCPNoDelay, "CURLOPT_TCP_NODELAY", CURLOPT_TCP_NODELAY},
896 #else
897 {handleTCPNoDelay, "CURLOPT_TCP_NODELAY", 0},
898 #endif
899 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
900 {handleFTPSSLAuth, "CURLOPT_FTPSSLAUTH", CURLOPT_FTPSSLAUTH},
901 #else
902 {handleFTPSSLAuth, "CURLOPT_FTPSSLAUTH", 0},
903 #endif
904 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
905 {handleIOCTLFunction, "CURLOPT_IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION},
906 #else
907 {handleIOCTLFunction, "CURLOPT_IOCTLFUNCTION", 0},
908 #endif
909 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
910 {handleFTPAccount, "CURLOPT_FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT},
911 #else
912 {handleFTPAccount, "CURLOPT_FTP_ACCOUNT", 0},
913 #endif
914 #if HAVE_DECL_CURLOPT_COOKIELIST
915 {handleCookieList, "CURLOPT_COOKIELIST", CURLOPT_COOKIELIST},
916 #else
917 {handleCookieList, "CURLOPT_COOKIELIST", 0},
918 #endif
919 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
920 {handleIgnoreContentLength, "CURLOPT_IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH},
921 #else
922 {handleIgnoreContentLength, "CURLOPT_IGNORE_CONTENT_LENGTH", 0},
923 #endif
924 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
925 {handleFTPSkipPASVIP, "CURLOPT_FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP},
926 #else
927 {handleFTPSkipPASVIP, "CURLOPT_FTP_SKIP_PASV_IP", 0},
928 #endif
929 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
930 {handleFTPFileMethod, "CURLOPT_FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD},
931 #else
932 {handleFTPFileMethod, "CURLOPT_FTP_FILEMETHOD", 0},
933 #endif
934 #if HAVE_DECL_CURLOPT_LOCALPORT
935 {handleLocalPort, "CURLOPT_LOCALPORT", CURLOPT_LOCALPORT},
936 #else
937 {handleLocalPort, "CURLOPT_LOCALPORT", 0},
938 #endif
939 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
940 {handleLocalPortRange, "CURLOPT_LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE},
941 #else
942 {handleLocalPortRange, "CURLOPT_LOCALPORTRANGE", 0},
943 #endif
944 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
945 {handleConnectOnly, "CURLOPT_CONNECT_ONLY", CURLOPT_CONNECT_ONLY},
946 #else
947 {handleConnectOnly, "CURLOPT_CONNECT_ONLY", 0},
948 #endif
949 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
950 {handleMaxSendSpeedLarge, "CURLOPT_MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE},
951 #else
952 {handleMaxSendSpeedLarge, "CURLOPT_MAX_SEND_SPEED_LARGE", 0},
953 #endif
954 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
955 {handleMaxRecvSpeedLarge, "CURLOPT_MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE},
956 #else
957 {handleMaxRecvSpeedLarge, "CURLOPT_MAX_RECV_SPEED_LARGE", 0},
958 #endif
959 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
960 {handleFTPAlternativeToUser, "CURLOPT_FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER},
961 #else
962 {handleFTPAlternativeToUser, "CURLOPT_FTP_ALTERMATIVE_TO_USER", 0},
963 #endif
964 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
965 {handleSSLSessionIdCache, "CURLOPT_SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE},
966 #else
967 {handleSSLSessionIdCache, "CURLOPT_SSL_SESSIONID_CACHE", 0},
968 #endif
969 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
970 {handleSSHAuthTypes, "CURLOPT_SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES},
971 #else
972 {handleSSHAuthTypes, "CURLOPT_SSH_AUTH_TYPES", 0},
973 #endif
974 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
975 {handleSSHPublicKeyFile, "CURLOPT_SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE},
976 #else
977 {handleSSHPublicKeyFile, "CURLOPT_SSH_PUBLIC_KEYFILE", 0},
978 #endif
979 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
980 {handleSSHPrivateKeyFile, "CURLOPT_SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE},
981 #else
982 {handleSSHPrivateKeyFile, "CURLOPT_SSH_PRIVATE_KEYFILE", 0},
983 #endif
984 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
985 {handleFTPSSLCCC, "CURLOPT_FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC},
986 #else
987 {handleFTPSSLCCC, "CURLOPT_FTP_SSL_CCC", 0},
988 #endif
989 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
990 {handleTimeoutMS, "CURLOPT_TIMEOUT_MS", CURLOPT_TIMEOUT_MS},
991 #else
992 {handleTimeoutMS, "CURLOPT_TIMEOUT_MS", 0},
993 #endif
994 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
995 {handleConnectTimeoutMS, "CURLOPT_CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS},
996 #else
997 {handleConnectTimeoutMS, "CURLOPT_CONNECTTIMEOUT_MS", 0},
998 #endif
999 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
1000 {handleHTTPTransferDecoding, "CURLOPT_HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING},
1001 #else
1002 {handleHTTPTransferDecoding, "CURLOPT_HTTP_TRANSFER_DECODING", 0},
1003 #endif
1004 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
1005 {handleHTTPContentDecoding, "CURLOPT_HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING},
1006 #else
1007 {handleHTTPContentDecoding, "CURLOPT_HTTP_CONTENT_DECODING", 0},
1008 #endif
1009 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
1010 {handleNewFilePerms, "CURLOPT_NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS},
1011 #else
1012 {handleNewFilePerms, "CURLOPT_NEW_FILE_PERMS", 0},
1013 #endif
1014 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
1015 {handleNewDirectoryPerms, "CURLOPT_NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS},
1016 #else
1017 {handleNewDirectoryPerms, "CURLOPT_NEW_DIRECTORY_PERMS", 0},
1018 #endif
1019 #if HAVE_DECL_CURLOPT_POST301
1020 {handlePost301, "CURLOPT_POST301", CURLOPT_POST301},
1021 #else
1022 {handlePost301, "CURLOPT_POST301", 0},
1023 #endif
1024 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEY_MD5
1025 {handleSSHHostPublicKeyMD5, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5},
1026 #else
1027 {handleSSHHostPublicKeyMD5, "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 0},
1028 #endif
1029 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
1030 {handleCopyPostFields, "CURLOPT_COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS},
1031 #else
1032 {handleCopyPostFields, "CURLOPT_COPYPOSTFIELDS", 0},
1033 #endif
1034 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
1035 {handleProxyTransferMode, "CURLOPT_PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE},
1036 #else
1037 {handleProxyTransferMode, "CURLOPT_PROXY_TRANSFER_MODE", 0},
1038 #endif
1039 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
1040 {handleSeekFunction, "CURLOPT_SEEKFUNCTION", CURLOPT_SEEKFUNCTION},
1041 #else
1042 {handleSeekFunction, "CURLOPT_SEEKFUNCTION", 0},
1043 #endif
1046 static char *findOption(CURLOptionMapping optionMap[],
1047 CURLoption option)
1049 return optionMap[option].name;
1052 static void free_curl_slist(struct curl_slist *slist)
1054 struct curl_slist *item;
1056 if (slist == NULL)
1057 return;
1059 item = slist;
1061 while (item != NULL)
1063 free(item->data);
1064 item->data = NULL;
1065 item = item->next;
1068 curl_slist_free_all(slist);
1071 static void raiseError(Connection *conn, CURLcode code)
1073 CAMLparam0();
1074 CAMLlocal1(exceptionData);
1075 value *exception;
1076 char *errorString = "Unknown Error";
1077 int i;
1079 for (i = 0; errorMap[i].name != NULL; i++)
1081 if (errorMap[i].error == code)
1083 errorString = errorMap[i].name;
1084 break;
1088 exceptionData = alloc(3, 0);
1090 Field(exceptionData, 0) = Val_int(code);
1091 Field(exceptionData, 1) = Val_int(code);
1092 Field(exceptionData, 2) = copy_string(errorString);
1094 if (conn != NULL && conn->errorBuffer != NULL)
1096 Field(Field(conn->ocamlValues, OcamlErrorBuffer), 0) =
1097 copy_string(conn->errorBuffer);
1100 exception = caml_named_value("CurlException");
1102 if (exception == NULL)
1103 failwith(errorString);
1105 raise_with_arg(*exception, exceptionData);
1107 CAMLreturn0;
1110 static void resetOcamlValues(Connection* connection)
1112 int i;
1114 for (i = 0; i < OcamlValuesSize; i++)
1115 Store_field(connection->ocamlValues, i, Val_unit);
1118 static Connection *newConnection(void)
1120 Connection *connection;
1122 connection = (Connection *)malloc(sizeof(Connection));
1124 enter_blocking_section();
1125 connection->connection = curl_easy_init();
1126 leave_blocking_section();
1128 connection->next = NULL;
1129 connection->prev = NULL;
1131 if (connectionList.tail == NULL)
1133 connectionList.tail = connection;
1134 connectionList.head = connection;
1136 else
1138 connection->prev = connectionList.head;
1139 connectionList.head->next = connection;
1140 connectionList.head = connection;
1143 connection->ocamlValues = alloc(OcamlValuesSize, 0);
1144 resetOcamlValues(connection);
1145 register_global_root(&connection->ocamlValues);
1147 connection->url = NULL;
1148 connection->proxy = NULL;
1149 connection->userPwd = NULL;
1150 connection->proxyUserPwd = NULL;
1151 connection->range = NULL;
1152 connection->errorBuffer = NULL;
1153 connection->postFields = NULL;
1154 connection->postFieldSize = -1;
1155 connection->referer = NULL;
1156 connection->userAgent = NULL;
1157 connection->ftpPort = NULL;
1158 connection->cookie = NULL;
1159 connection->httpHeader = NULL;
1160 connection->httpPostFirst = NULL;
1161 connection->httpPostLast = NULL;
1162 connection->httpPostStrings = NULL;
1163 connection->sslCert = NULL;
1164 connection->sslCertType = NULL;
1165 connection->sslCertPasswd = NULL;
1166 connection->sslKey = NULL;
1167 connection->sslKeyType = NULL;
1168 connection->sslKeyPasswd = NULL;
1169 connection->sslEngine = NULL;
1170 connection->quote = NULL;
1171 connection->postQuote = NULL;
1172 connection->cookieFile = NULL;
1173 connection->customRequest = NULL;
1174 connection->interface = NULL;
1175 connection->caInfo = NULL;
1176 connection->caPath = NULL;
1177 connection->randomFile = NULL;
1178 connection->egdSocket = NULL;
1179 connection->cookieJar = NULL;
1180 connection->sslCipherList = NULL;
1181 connection->private = NULL;
1182 connection->http200Aliases = NULL;
1183 connection->netrcFile = NULL;
1184 connection->ftpaccount = NULL;
1185 connection->cookielist = NULL;
1186 connection->ftpAlternativeToUser = NULL;
1187 connection->sshPublicKeyFile = NULL;
1188 connection->sshPrivateKeyFile = NULL;
1189 connection->copyPostFields = NULL;
1191 return connection;
1194 static Connection *duplicateConnection(Connection *original)
1196 Connection *connection;
1198 connection = (Connection *)malloc(sizeof(Connection));
1200 enter_blocking_section();
1201 connection->connection = curl_easy_duphandle(original->connection);
1202 leave_blocking_section();
1204 connection->next = NULL;
1205 connection->prev = NULL;
1207 if (connectionList.tail == NULL)
1209 connectionList.tail = connection;
1210 connectionList.head = connection;
1212 else
1214 connection->prev = connectionList.head;
1215 connectionList.head->next = connection;
1216 connectionList.head = connection;
1219 connection->ocamlValues = alloc(OcamlValuesSize, 0);
1220 resetOcamlValues(connection);
1221 register_global_root(&connection->ocamlValues);
1223 Store_field(connection->ocamlValues, OcamlWriteCallback,
1224 Field(original->ocamlValues, OcamlWriteCallback));
1225 Store_field(connection->ocamlValues, OcamlReadCallback,
1226 Field(original->ocamlValues, OcamlReadCallback));
1227 Store_field(connection->ocamlValues, OcamlErrorBuffer,
1228 Field(original->ocamlValues, OcamlErrorBuffer));
1229 Store_field(connection->ocamlValues, OcamlPostFields,
1230 Field(original->ocamlValues, OcamlPostFields));
1231 Store_field(connection->ocamlValues, OcamlHTTPHeader,
1232 Field(original->ocamlValues, OcamlHTTPHeader));
1233 Store_field(connection->ocamlValues, OcamlQuote,
1234 Field(original->ocamlValues, OcamlQuote));
1235 Store_field(connection->ocamlValues, OcamlPostQuote,
1236 Field(original->ocamlValues, OcamlPostQuote));
1237 Store_field(connection->ocamlValues, OcamlHeaderCallback,
1238 Field(original->ocamlValues, OcamlHeaderCallback));
1239 Store_field(connection->ocamlValues, OcamlProgressCallback,
1240 Field(original->ocamlValues, OcamlProgressCallback));
1241 Store_field(connection->ocamlValues, OcamlDebugCallback,
1242 Field(original->ocamlValues, OcamlDebugCallback));
1243 Store_field(connection->ocamlValues, OcamlHTTP200Aliases,
1244 Field(original->ocamlValues, OcamlHTTP200Aliases));
1245 Store_field(connection->ocamlValues, OcamlIOCTLCallback,
1246 Field(original->ocamlValues, OcamlIOCTLCallback));
1247 Store_field(connection->ocamlValues, OcamlSeekFunctionCallback,
1248 Field(original->ocamlValues, OcamlSeekFunctionCallback));
1250 connection->url = NULL;
1251 connection->proxy = NULL;
1252 connection->userPwd = NULL;
1253 connection->proxyUserPwd = NULL;
1254 connection->range = NULL;
1255 connection->errorBuffer = NULL;
1256 connection->postFields = NULL;
1257 connection->postFieldSize = -1;
1258 connection->referer = NULL;
1259 connection->userAgent = NULL;
1260 connection->ftpPort = NULL;
1261 connection->cookie = NULL;
1262 connection->httpHeader = NULL;
1263 connection->httpPostFirst = NULL;
1264 connection->httpPostLast = NULL;
1265 connection->httpPostStrings = NULL;
1266 connection->sslCert = NULL;
1267 connection->sslCertType = NULL;
1268 connection->sslCertPasswd = NULL;
1269 connection->sslKey = NULL;
1270 connection->sslKeyType = NULL;
1271 connection->sslKeyPasswd = NULL;
1272 connection->sslEngine = NULL;
1273 connection->quote = NULL;
1274 connection->postQuote = NULL;
1275 connection->cookieFile = NULL;
1276 connection->customRequest = NULL;
1277 connection->interface = NULL;
1278 connection->caInfo = NULL;
1279 connection->caPath = NULL;
1280 connection->randomFile = NULL;
1281 connection->egdSocket = NULL;
1282 connection->cookieJar = NULL;
1283 connection->sslCipherList = NULL;
1284 connection->private = NULL;
1285 connection->http200Aliases = NULL;
1286 connection->netrcFile = NULL;
1287 connection->ftpaccount = NULL;
1288 connection->cookielist = NULL;
1289 connection->sshPublicKeyFile = NULL;
1290 connection->sshPrivateKeyFile = NULL;
1291 connection->copyPostFields = NULL;
1293 if (Field(original->ocamlValues, OcamlURL) != Val_unit)
1294 handleURL(connection, Field(original->ocamlValues,
1295 OcamlURL));
1296 if (Field(original->ocamlValues, OcamlProxy) != Val_unit)
1297 handleProxy(connection, Field(original->ocamlValues,
1298 OcamlProxy));
1299 if (Field(original->ocamlValues, OcamlUserPWD) != Val_unit)
1300 handleUserPwd(connection, Field(original->ocamlValues,
1301 OcamlUserPWD));
1302 if (Field(original->ocamlValues, OcamlProxyUserPWD) != Val_unit)
1303 handleProxyUserPwd(connection, Field(original->ocamlValues,
1304 OcamlProxyUserPWD));
1305 if (Field(original->ocamlValues, OcamlRange) != Val_unit)
1306 handleRange(connection, Field(original->ocamlValues,
1307 OcamlRange));
1308 if (Field(original->ocamlValues, OcamlErrorBuffer) != Val_unit)
1309 handleErrorBuffer(connection, Field(original->ocamlValues,
1310 OcamlErrorBuffer));
1311 if (Field(original->ocamlValues, OcamlPostFields) != Val_unit)
1312 handlePostFields(connection, Field(original->ocamlValues,
1313 OcamlPostFields));
1314 if (Field(original->ocamlValues, OcamlReferer) != Val_unit)
1315 handleReferer(connection, Field(original->ocamlValues,
1316 OcamlReferer));
1317 if (Field(original->ocamlValues, OcamlUserAgent) != Val_unit)
1318 handleUserAgent(connection, Field(original->ocamlValues,
1319 OcamlUserAgent));
1320 if (Field(original->ocamlValues, OcamlFTPPort) != Val_unit)
1321 handleFTPPort(connection, Field(original->ocamlValues,
1322 OcamlFTPPort));
1323 if (Field(original->ocamlValues, OcamlCookie) != Val_unit)
1324 handleCookie(connection, Field(original->ocamlValues,
1325 OcamlCookie));
1326 if (Field(original->ocamlValues, OcamlHTTPHeader) != Val_unit)
1327 handleHTTPHeader(connection, Field(original->ocamlValues,
1328 OcamlHTTPHeader));
1329 if (Field(original->ocamlValues, OcamlHTTPPost) != Val_unit)
1330 handleHTTPPost(connection, Field(original->ocamlValues,
1331 OcamlHTTPPost));
1332 if (Field(original->ocamlValues, OcamlSSLCert) != Val_unit)
1333 handleSSLCert(connection, Field(original->ocamlValues,
1334 OcamlSSLCert));
1335 if (Field(original->ocamlValues, OcamlSSLCertType) != Val_unit)
1336 handleSSLCertType(connection, Field(original->ocamlValues,
1337 OcamlSSLCertType));
1338 if (Field(original->ocamlValues, OcamlSSLCertPasswd) != Val_unit)
1339 handleSSLCertPasswd(connection, Field(original->ocamlValues,
1340 OcamlSSLCertPasswd));
1341 if (Field(original->ocamlValues, OcamlSSLKey) != Val_unit)
1342 handleSSLKey(connection, Field(original->ocamlValues,
1343 OcamlSSLKey));
1344 if (Field(original->ocamlValues, OcamlSSLKeyType) != Val_unit)
1345 handleSSLKeyType(connection, Field(original->ocamlValues,
1346 OcamlSSLKeyType));
1347 if (Field(original->ocamlValues, OcamlSSLKeyPasswd) != Val_unit)
1348 handleSSLKeyPasswd(connection, Field(original->ocamlValues,
1349 OcamlSSLKeyPasswd));
1350 if (Field(original->ocamlValues, OcamlSSLEngine) != Val_unit)
1351 handleSSLEngine(connection, Field(original->ocamlValues,
1352 OcamlSSLEngine));
1353 if (Field(original->ocamlValues, OcamlQuote) != Val_unit)
1354 handleQuote(connection, Field(original->ocamlValues,
1355 OcamlQuote));
1356 if (Field(original->ocamlValues, OcamlPostQuote) != Val_unit)
1357 handlePostQuote(connection, Field(original->ocamlValues,
1358 OcamlPostQuote));
1359 if (Field(original->ocamlValues, OcamlCookieFile) != Val_unit)
1360 handleCookieFile(connection, Field(original->ocamlValues,
1361 OcamlCookieFile));
1362 if (Field(original->ocamlValues, OcamlCustomRequest) != Val_unit)
1363 handleCustomRequest(connection, Field(original->ocamlValues,
1364 OcamlCustomRequest));
1365 if (Field(original->ocamlValues, OcamlInterface) != Val_unit)
1366 handleInterface(connection, Field(original->ocamlValues,
1367 OcamlInterface));
1368 if (Field(original->ocamlValues, OcamlCAInfo) != Val_unit)
1369 handleCAInfo(connection, Field(original->ocamlValues,
1370 OcamlCAInfo));
1371 if (Field(original->ocamlValues, OcamlCAPath) != Val_unit)
1372 handleCAPath(connection, Field(original->ocamlValues,
1373 OcamlCAPath));
1374 if (Field(original->ocamlValues, OcamlRandomFile) != Val_unit)
1375 handleRandomFile(connection, Field(original->ocamlValues,
1376 OcamlRandomFile));
1377 if (Field(original->ocamlValues, OcamlEGDSocket) != Val_unit)
1378 handleEGDSocket(connection, Field(original->ocamlValues,
1379 OcamlEGDSocket));
1380 if (Field(original->ocamlValues, OcamlCookieJar) != Val_unit)
1381 handleCookieJar(connection, Field(original->ocamlValues,
1382 OcamlCookieJar));
1383 if (Field(original->ocamlValues, OcamlSSLCipherList) != Val_unit)
1384 handleSSLCipherList(connection, Field(original->ocamlValues,
1385 OcamlSSLCipherList));
1386 if (Field(original->ocamlValues, OcamlPrivate) != Val_unit)
1387 handlePrivate(connection, Field(original->ocamlValues,
1388 OcamlPrivate));
1389 if (Field(original->ocamlValues, OcamlHTTP200Aliases) != Val_unit)
1390 handleHTTP200Aliases(connection, Field(original->ocamlValues,
1391 OcamlHTTP200Aliases));
1392 if (Field(original->ocamlValues, OcamlNETRCFile) != Val_unit)
1393 handleNETRCFile(connection, Field(original->ocamlValues,
1394 OcamlNETRCFile));
1395 if (Field(original->ocamlValues, OcamlFTPAccount) != Val_unit)
1396 handleFTPAccount(connection, Field(original->ocamlValues,
1397 OcamlFTPAccount));
1398 if (Field(original->ocamlValues, OcamlCookieList) != Val_unit)
1399 handleCookieList(connection, Field(original->ocamlValues,
1400 OcamlCookieList));
1401 if (Field(original->ocamlValues, OcamlFTPAlternativeToUser) != Val_unit)
1402 handleFTPAlternativeToUser(connection,
1403 Field(original->ocamlValues,
1404 OcamlFTPAlternativeToUser));
1405 if (Field(original->ocamlValues, OcamlSSHPublicKeyFile) != Val_unit)
1406 handleSSHPublicKeyFile(connection,
1407 Field(original->ocamlValues,
1408 OcamlSSHPublicKeyFile));
1409 if (Field(original->ocamlValues, OcamlSSHPrivateKeyFile) != Val_unit)
1410 handleSSHPrivateKeyFile(connection,
1411 Field(original->ocamlValues,
1412 OcamlSSHPrivateKeyFile));
1413 if (Field(original->ocamlValues, OcamlCopyPostFields) != Val_unit)
1414 handleCopyPostFields(connection,
1415 Field(original->ocamlValues,
1416 OcamlCopyPostFields));
1418 return connection;
1421 static void removeConnection(Connection *connection)
1423 enter_blocking_section();
1424 curl_easy_cleanup(connection->connection);
1425 leave_blocking_section();
1427 if (connectionList.tail == connection)
1428 connectionList.tail = connectionList.tail->next;
1429 if (connectionList.head == connection)
1430 connectionList.head = connectionList.head->prev;
1432 if (connection->next != NULL)
1433 connection->next->prev = connection->prev;
1434 if (connection->prev != NULL)
1435 connection->prev->next = connection->next;
1437 remove_global_root(&connection->ocamlValues);
1439 if (connection->url != NULL)
1440 free(connection->url);
1441 if (connection->proxy != NULL)
1442 free(connection->proxy);
1443 if (connection->userPwd != NULL)
1444 free(connection->userPwd);
1445 if (connection->proxyUserPwd != NULL)
1446 free(connection->proxyUserPwd);
1447 if (connection->range != NULL)
1448 free(connection->range);
1449 if (connection->errorBuffer != NULL)
1450 free(connection->range);
1451 if (connection->postFields != NULL)
1452 free(connection->postFields);
1453 if (connection->referer != NULL)
1454 free(connection->referer);
1455 if (connection->userAgent != NULL)
1456 free(connection->userAgent);
1457 if (connection->ftpPort != NULL)
1458 free(connection->ftpPort);
1459 if (connection->cookie != NULL)
1460 free(connection->cookie);
1461 if (connection->httpHeader != NULL)
1462 free_curl_slist(connection->httpHeader);
1463 if (connection->httpPostFirst != NULL)
1464 curl_formfree(connection->httpPostFirst);
1465 if (connection->httpPostStrings != NULL)
1466 free_curl_slist(connection->httpPostStrings);
1467 if (connection->sslCert != NULL)
1468 free(connection->sslCert);
1469 if (connection->sslCertType != NULL)
1470 free(connection->sslCertType);
1471 if (connection->sslCertPasswd != NULL)
1472 free(connection->sslCertPasswd);
1473 if (connection->sslKey != NULL)
1474 free(connection->sslKey);
1475 if (connection->sslKeyType != NULL)
1476 free(connection->sslKeyType);
1477 if (connection->sslKeyPasswd != NULL)
1478 free(connection->sslKeyPasswd);
1479 if (connection->sslEngine != NULL)
1480 free(connection->sslEngine);
1481 if (connection->quote != NULL)
1482 free_curl_slist(connection->quote);
1483 if (connection->postQuote != NULL)
1484 free_curl_slist(connection->postQuote);
1485 if (connection->cookieFile != NULL)
1486 free(connection->cookieFile);
1487 if (connection->customRequest != NULL)
1488 free(connection->customRequest);
1489 if (connection->interface != NULL)
1490 free(connection->interface);
1491 if (connection->caInfo != NULL)
1492 free(connection->caInfo);
1493 if (connection->caPath != NULL)
1494 free(connection->caPath);
1495 if (connection->randomFile != NULL)
1496 free(connection->randomFile);
1497 if (connection->egdSocket != NULL)
1498 free(connection->egdSocket);
1499 if (connection->cookieJar != NULL)
1500 free(connection->cookieJar);
1501 if (connection->sslCipherList != NULL)
1502 free(connection->sslCipherList);
1503 if (connection->private != NULL)
1504 free(connection->private);
1505 if (connection->http200Aliases != NULL)
1506 free_curl_slist(connection->http200Aliases);
1507 if (connection->netrcFile != NULL)
1508 free(connection->netrcFile);
1509 if (connection->ftpaccount != NULL)
1510 free(connection->ftpaccount);
1511 if (connection->cookielist != NULL)
1512 free(connection->cookielist);
1513 if (connection->ftpAlternativeToUser != NULL)
1514 free(connection->ftpAlternativeToUser);
1515 if (connection->sshPublicKeyFile != NULL)
1516 free(connection->sshPublicKeyFile);
1517 if (connection->sshPrivateKeyFile != NULL)
1518 free(connection->sshPrivateKeyFile);
1519 if (connection->copyPostFields != NULL)
1520 free(connection->copyPostFields);
1522 free(connection);
1525 static void checkConnection(Connection *connection)
1527 Connection *listIter;
1529 listIter = connectionList.tail;
1531 while (listIter != NULL)
1533 if (listIter == connection)
1534 return;
1536 listIter = listIter->next;
1539 failwith("Invalid Connection");
1542 static Connection* findConnection(CURL* h)
1544 Connection *listIter;
1546 listIter = connectionList.tail;
1548 while (listIter != NULL)
1550 if (listIter->connection == h)
1551 return listIter;
1553 listIter = listIter->next;
1556 failwith("Unknown handle");
1559 #define WRAP_DATA_CALLBACK(f) \
1560 static size_t f(char *ptr, size_t size, size_t nmemb, void *data)\
1562 size_t result;\
1563 leave_blocking_section();\
1564 result = f##_nolock(ptr,size,nmemb,data);\
1565 enter_blocking_section();\
1566 return result;\
1569 static size_t writeFunction_nolock(char *ptr, size_t size, size_t nmemb, void *data)
1571 CAMLparam0();
1572 CAMLlocal2(result, str);
1573 Connection *conn = (Connection *)data;
1574 int i;
1576 checkConnection(conn);
1578 str = alloc_string(size*nmemb);
1580 for (i = 0; i < size*nmemb; i++)
1581 Byte(str, i) = ptr[i];
1583 result = callback(Field(conn->ocamlValues, OcamlWriteCallback), str);
1585 CAMLreturnT(size_t, Int_val(result));
1588 WRAP_DATA_CALLBACK(writeFunction)
1590 static size_t readFunction_nolock(void *ptr, size_t size, size_t nmemb, void *data)
1592 CAMLparam0();
1593 CAMLlocal1(result);
1594 Connection *conn = (Connection *)data;
1595 int length;
1597 checkConnection(conn);
1599 result = callback(Field(conn->ocamlValues, OcamlReadCallback),
1600 Val_int(size*nmemb));
1602 length = string_length(result);
1604 if (length >= size*nmemb)
1605 length = size*nmemb;
1607 memcpy(ptr, String_val(result), length);
1609 CAMLreturnT(size_t,length);
1612 WRAP_DATA_CALLBACK(readFunction)
1614 static size_t headerFunction_nolock(char *ptr, size_t size, size_t nmemb, void *data)
1616 CAMLparam0();
1617 CAMLlocal2(result,str);
1618 Connection *conn = (Connection *)data;
1619 int i;
1621 checkConnection(conn);
1623 str = alloc_string(size*nmemb);
1625 for (i = 0; i < size*nmemb; i++)
1626 Byte(str, i) = ptr[i];
1628 result = callback(Field(conn->ocamlValues, OcamlHeaderCallback), str);
1630 CAMLreturnT(size_t, Int_val(result));
1633 WRAP_DATA_CALLBACK(headerFunction)
1635 static int progressFunction_nolock(void *data,
1636 double dlTotal,
1637 double dlNow,
1638 double ulTotal,
1639 double ulNow)
1641 CAMLparam0();
1642 CAMLlocal1(result);
1643 CAMLlocalN(callbackData, 4);
1644 Connection *conn = (Connection *)data;
1646 checkConnection(conn);
1648 callbackData[0] = copy_double(dlTotal);
1649 callbackData[1] = copy_double(dlNow);
1650 callbackData[2] = copy_double(ulTotal);
1651 callbackData[3] = copy_double(ulNow);
1653 result = callbackN(Field(conn->ocamlValues, OcamlProgressCallback),
1654 4, callbackData);
1656 CAMLreturnT(int, Bool_val(result));
1659 static int progressFunction(void *data,
1660 double dlTotal,
1661 double dlNow,
1662 double ulTotal,
1663 double ulNow)
1665 int r;
1666 leave_blocking_section();
1667 r = progressFunction_nolock(data,dlTotal,dlNow,ulTotal,ulNow);
1668 enter_blocking_section();
1669 return r;
1672 static int debugFunction_nolock(CURL *debugConnection,
1673 curl_infotype infoType,
1674 char *buffer,
1675 size_t bufferLength,
1676 void *data)
1678 CAMLparam0();
1679 CAMLlocal3(camlDebugConnection, camlInfoType, camlMessage);
1680 int i;
1681 Connection *conn = (Connection *)data;
1683 checkConnection(conn);
1685 camlDebugConnection = (value)conn;
1686 camlInfoType = Val_long(infoType);
1687 camlMessage = alloc_string(bufferLength);
1689 for (i = 0; i < bufferLength; i++)
1690 Byte(camlMessage, i) = buffer[i];
1692 callback3(Field(conn->ocamlValues, OcamlDebugCallback),
1693 camlDebugConnection,
1694 camlInfoType,
1695 camlMessage);
1697 CAMLreturnT(int, 0);
1700 static int debugFunction(CURL *debugConnection,
1701 curl_infotype infoType,
1702 char *buffer,
1703 size_t bufferLength,
1704 void *data)
1706 int r;
1707 leave_blocking_section();
1708 r = debugFunction_nolock(debugConnection, infoType, buffer, bufferLength, data);
1709 enter_blocking_section();
1710 return r;
1713 static curlioerr ioctlFunction_nolock(CURL *ioctl,
1714 int cmd,
1715 void *data)
1717 CAMLparam0();
1718 CAMLlocal3(camlResult, camlConnection, camlCmd);
1719 Connection *conn = (Connection *)data;
1720 curlioerr result = CURLIOE_OK;
1722 checkConnection(conn);
1724 if (cmd == CURLIOCMD_NOP)
1725 camlCmd = Val_long(0);
1726 else if (cmd == CURLIOCMD_RESTARTREAD)
1727 camlCmd = Val_long(1);
1728 else
1729 failwith("Invalid IOCTL Cmd!");
1731 camlConnection = alloc(1, Abstract_tag);
1732 Store_field(camlConnection, 0, (value)conn);
1734 camlResult = callback2(Field(conn->ocamlValues, OcamlIOCTLCallback),
1735 camlConnection,
1736 camlCmd);
1738 switch (Long_val(camlResult))
1740 case 0: /* CURLIOE_OK */
1741 result = CURLIOE_OK;
1742 break;
1744 case 1: /* CURLIOE_UNKNOWNCMD */
1745 result = CURLIOE_UNKNOWNCMD;
1746 break;
1748 case 2: /* CURLIOE_FAILRESTART */
1749 result = CURLIOE_FAILRESTART;
1750 break;
1752 default: /* Incorrect return value, but let's handle it */
1753 result = CURLIOE_FAILRESTART;
1754 break;
1757 CAMLreturnT(curlioerr, result);
1760 static curlioerr ioctlFunction(CURL *ioctl,
1761 int cmd,
1762 void *data)
1764 curlioerr r;
1765 leave_blocking_section();
1766 r = ioctlFunction_nolock(ioctl, cmd, data);
1767 enter_blocking_section();
1768 return r;
1771 #ifdef HAVE_DECL_CURLOPT_SEEKFUNCTION
1772 static int seekFunction_nolock(void *data,
1773 curl_off_t offset,
1774 int origin)
1776 CAMLparam0();
1777 CAMLlocal3(camlResult, camlOffset, camlOrigin);
1778 Connection *conn = (Connection *)data;
1779 int result = 0;
1781 camlOffset = copy_int64(offset);
1783 if (origin == SEEK_SET)
1784 camlOrigin = Val_long(0);
1785 else if (origin == SEEK_CUR)
1786 camlOrigin = Val_long(1);
1787 else if (origin == SEEK_END)
1788 camlOrigin = Val_long(2);
1789 else
1790 camlOrigin = Val_long(0);
1792 camlResult = callback2(Field(conn->ocamlValues,
1793 OcamlSeekFunctionCallback),
1794 camlOffset,
1795 camlOrigin);
1797 result = Int_val(camlResult);
1799 CAMLreturnT(int, result);
1802 static int seekFunction(void *data,
1803 curl_off_t offset,
1804 int origin)
1806 int r;
1807 leave_blocking_section();
1808 r = seekFunction_nolock(data,offset,origin);
1809 enter_blocking_section();
1810 return r;
1813 #endif
1816 ** curl_global_init helper function
1819 CAMLprim value helper_curl_global_init(value initOption)
1821 CAMLparam1(initOption);
1823 switch (Long_val(initOption))
1825 case 0: /* CURLINIT_GLOBALALL */
1826 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_ALL)));
1827 break;
1829 case 1: /* CURLINIT_GLOBALSSL */
1830 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_SSL)));
1831 break;
1833 case 2: /* CURLINIT_GLOBALWIN32 */
1834 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_WIN32)));
1835 break;
1837 case 3: /* CURLINIT_GLOBALNOTHING */
1838 CAMLreturn(Val_long(curl_global_init(CURL_GLOBAL_NOTHING)));
1839 break;
1841 default:
1842 failwith("Invalid Initialization Option");
1843 break;
1846 /* Keep compiler happy, we should never get here due to failwith() */
1847 CAMLreturn(Val_unit);
1851 ** curl_global_cleanup helper function
1854 CAMLprim value helper_curl_global_cleanup(void)
1856 CAMLparam0();
1858 curl_global_cleanup();
1860 CAMLreturn(Val_unit);
1864 ** curl_easy_init helper function
1867 CAMLprim value helper_curl_easy_init(void)
1869 CAMLparam0();
1870 CAMLlocal1(result);
1872 Connection *conn = newConnection();
1874 result = alloc(1, Abstract_tag);
1875 Store_field(result, 0, (value)conn);
1877 CAMLreturn(result);
1880 CAMLprim value helper_curl_easy_reset(value conn)
1882 CAMLparam1(conn);
1883 Connection *connection = Connection_val(conn);
1885 checkConnection(connection);
1886 curl_easy_reset(connection->connection);
1887 resetOcamlValues(connection);
1889 CAMLreturn(Val_unit);
1893 ** curl_easy_setopt helper utility functions
1896 static void handleWriteFunction(Connection *conn, value option)
1898 CAMLparam1(option);
1899 CURLcode result = CURLE_OK;
1901 if (Tag_val(option) == Closure_tag)
1902 Store_field(conn->ocamlValues, OcamlWriteCallback, option);
1903 else
1904 failwith("Not a proper closure");
1906 result = curl_easy_setopt(conn->connection,
1907 CURLOPT_WRITEFUNCTION,
1908 writeFunction);
1910 if (result != CURLE_OK)
1911 raiseError(conn, result);
1913 result = curl_easy_setopt(conn->connection,
1914 CURLOPT_WRITEDATA,
1915 conn);
1917 if (result != CURLE_OK)
1918 raiseError(conn, result);
1920 CAMLreturn0;
1923 static void handleReadFunction(Connection *conn, value option)
1925 CAMLparam1(option);
1926 CURLcode result = CURLE_OK;
1928 if (Tag_val(option) == Closure_tag)
1929 Store_field(conn->ocamlValues, OcamlReadCallback, option);
1930 else
1931 failwith("Not a proper closure");
1933 result = curl_easy_setopt(conn->connection,
1934 CURLOPT_READFUNCTION,
1935 readFunction);
1937 if (result != CURLE_OK)
1938 raiseError(conn, result);
1940 result = curl_easy_setopt(conn->connection,
1941 CURLOPT_READDATA,
1942 conn);
1944 if (result != CURLE_OK)
1945 raiseError(conn, result);
1947 CAMLreturn0;
1950 static void handleURL(Connection *conn, value option)
1952 CAMLparam1(option);
1953 CURLcode result = CURLE_OK;
1955 Store_field(conn->ocamlValues, OcamlURL, option);
1957 if (conn->url != NULL)
1958 free(conn->url);
1960 conn->url = strdup(String_val(option));
1962 result = curl_easy_setopt(conn->connection,
1963 CURLOPT_URL,
1964 conn->url);
1966 if (result != CURLE_OK)
1967 raiseError(conn, result);
1969 CAMLreturn0;
1972 static void handleInFileSize(Connection *conn, value option)
1974 CAMLparam1(option);
1975 CURLcode result = CURLE_OK;
1977 result = curl_easy_setopt(conn->connection,
1978 CURLOPT_INFILESIZE,
1979 Long_val(option));
1981 if (result != CURLE_OK)
1982 raiseError(conn, result);
1984 CAMLreturn0;
1987 static void handleProxy(Connection *conn, value option)
1989 CAMLparam1(option);
1990 CURLcode result = CURLE_OK;
1992 Store_field(conn->ocamlValues, OcamlProxy, option);
1994 if (conn->proxy != NULL)
1995 free(conn->proxy);
1997 conn->proxy = strdup(String_val(option));
1999 result = curl_easy_setopt(conn->connection,
2000 CURLOPT_PROXY,
2001 conn->proxy);
2003 if (result != CURLE_OK)
2004 raiseError(conn, result);
2006 CAMLreturn0;
2009 static void handleProxyPort(Connection *conn, value option)
2011 CAMLparam1(option);
2012 CURLcode result = CURLE_OK;
2014 result = curl_easy_setopt(conn->connection,
2015 CURLOPT_PROXYPORT,
2016 Long_val(option));
2018 if (result != CURLE_OK)
2019 raiseError(conn, result);
2021 CAMLreturn0;
2024 static void handleHTTPProxyTunnel(Connection *conn, value option)
2026 CAMLparam1(option);
2027 CURLcode result = CURLE_OK;
2029 result = curl_easy_setopt(conn->connection,
2030 CURLOPT_HTTPPROXYTUNNEL,
2031 Bool_val(option));
2033 if (result != CURLE_OK)
2034 raiseError(conn, result);
2036 CAMLreturn0;
2039 static void handleVerbose(Connection *conn, value option)
2041 CAMLparam1(option);
2042 CURLcode result = CURLE_OK;
2044 result = curl_easy_setopt(conn->connection,
2045 CURLOPT_VERBOSE,
2046 Bool_val(option));
2048 if (result != CURLE_OK)
2049 raiseError(conn, result);
2051 CAMLreturn0;
2054 static void handleHeader(Connection *conn, value option)
2056 CAMLparam1(option);
2057 CURLcode result = CURLE_OK;
2059 result = curl_easy_setopt(conn->connection,
2060 CURLOPT_HEADER,
2061 Bool_val(option));
2063 if (result != CURLE_OK)
2064 raiseError(conn, result);
2066 CAMLreturn0;
2069 static void handleNoProgress(Connection *conn, value option)
2071 CAMLparam1(option);
2072 CURLcode result = CURLE_OK;
2074 result = curl_easy_setopt(conn->connection,
2075 CURLOPT_NOPROGRESS,
2076 Bool_val(option));
2078 if (result != CURLE_OK)
2079 raiseError(conn, result);
2081 CAMLreturn0;
2084 static void handleNoSignal(Connection *conn, value option)
2086 #if HAVE_DECL_CURLOPT_NOSIGNAL
2087 CAMLparam1(option);
2088 CURLcode result = CURLE_OK;
2090 result = curl_easy_setopt(conn->connection,
2091 CURLOPT_NOSIGNAL,
2092 Bool_val(option));
2094 if (result != CURLE_OK)
2095 raiseError(conn, result);
2097 CAMLreturn0;
2098 #else
2099 #warning "libcurl does not implement CURLOPT_NOSIGNAL"
2100 failwith("libcurl does not implement CURLOPT_NOSIGNAL");
2101 #endif
2104 static void handleNoBody(Connection *conn, value option)
2106 CAMLparam1(option);
2107 CURLcode result = CURLE_OK;
2109 result = curl_easy_setopt(conn->connection,
2110 CURLOPT_NOBODY,
2111 Bool_val(option));
2113 if (result != CURLE_OK)
2114 raiseError(conn, result);
2116 CAMLreturn0;
2119 static void handleFailOnError(Connection *conn, value option)
2121 CAMLparam1(option);
2122 CURLcode result = CURLE_OK;
2124 result = curl_easy_setopt(conn->connection,
2125 CURLOPT_FAILONERROR,
2126 Bool_val(option));
2128 if (result != CURLE_OK)
2129 raiseError(conn, result);
2131 CAMLreturn0;
2134 static void handleUpload(Connection *conn, value option)
2136 CAMLparam1(option);
2137 CURLcode result = CURLE_OK;
2139 result = curl_easy_setopt(conn->connection,
2140 CURLOPT_UPLOAD,
2141 Bool_val(option));
2143 if (result != CURLE_OK)
2144 raiseError(conn, result);
2146 CAMLreturn0;
2149 static void handlePost(Connection *conn, value option)
2151 CAMLparam1(option);
2152 CURLcode result = CURLE_OK;
2154 result = curl_easy_setopt(conn->connection,
2155 CURLOPT_POST,
2156 Bool_val(option));
2158 if (result != CURLE_OK)
2159 raiseError(conn, result);
2161 CAMLreturn0;
2164 static void handleFTPListOnly(Connection *conn, value option)
2166 CAMLparam1(option);
2167 CURLcode result = CURLE_OK;
2169 result = curl_easy_setopt(conn->connection,
2170 CURLOPT_FTPLISTONLY,
2171 Bool_val(option));
2173 if (result != CURLE_OK)
2174 raiseError(conn, result);
2176 CAMLreturn0;
2179 static void handleFTPAppend(Connection *conn, value option)
2181 CAMLparam1(option);
2182 CURLcode result = CURLE_OK;
2184 result = curl_easy_setopt(conn->connection,
2185 CURLOPT_FTPAPPEND,
2186 Bool_val(option));
2188 if (result != CURLE_OK)
2189 raiseError(conn, result);
2191 CAMLreturn0;
2194 static void handleNETRC(Connection *conn, value option)
2196 CAMLparam1(option);
2197 CURLcode result = CURLE_OK;
2198 long netrc;
2200 switch (Long_val(option))
2202 case 0: /* CURL_NETRC_OPTIONAL */
2203 netrc = CURL_NETRC_OPTIONAL;
2204 break;
2206 case 1:/* CURL_NETRC_IGNORED */
2207 netrc = CURL_NETRC_IGNORED;
2208 break;
2210 case 2: /* CURL_NETRC_REQUIRED */
2211 netrc = CURL_NETRC_REQUIRED;
2212 break;
2214 default:
2215 failwith("Invalid NETRC Option");
2216 break;
2219 result = curl_easy_setopt(conn->connection,
2220 CURLOPT_NETRC,
2221 netrc);
2223 if (result != CURLE_OK)
2224 raiseError(conn, result);
2226 CAMLreturn0;
2229 static void handleEncoding(Connection *conn, value option)
2231 #if HAVE_DECL_CURLOPT_ENCODING
2232 CAMLparam1(option);
2233 CURLcode result = CURLE_OK;
2235 switch (Long_val(option))
2237 case 0: /* CURL_ENCODING_NONE */
2238 result = curl_easy_setopt(conn->connection,
2239 CURLOPT_ENCODING,
2240 "identity");
2241 break;
2243 case 1: /* CURL_ENCODING_DEFLATE */
2244 result = curl_easy_setopt(conn->connection,
2245 CURLOPT_ENCODING,
2246 "deflate");
2247 break;
2249 default:
2250 failwith("Invalid Encoding Option");
2251 break;
2254 if (result != CURLE_OK)
2255 raiseError(conn, result);
2257 CAMLreturn0;
2258 #else
2259 #warning "libcurl does not implement CURLOPT_ENCODING"
2260 failwith("libcurl does not implement CURLOPT_ENCODING");
2261 #endif
2264 static void handleFollowLocation(Connection *conn, value option)
2266 CAMLparam1(option);
2267 CURLcode result = CURLE_OK;
2269 result = curl_easy_setopt(conn->connection,
2270 CURLOPT_FOLLOWLOCATION,
2271 Bool_val(option));
2273 if (result != CURLE_OK)
2274 raiseError(conn, result);
2276 CAMLreturn0;
2279 static void handleTransferText(Connection *conn, value option)
2281 CAMLparam1(option);
2282 CURLcode result = CURLE_OK;
2284 result = curl_easy_setopt(conn->connection,
2285 CURLOPT_TRANSFERTEXT,
2286 Bool_val(option));
2288 if (result != CURLE_OK)
2289 raiseError(conn, result);
2291 CAMLreturn0;
2294 static void handlePut(Connection *conn, value option)
2296 CAMLparam1(option);
2297 CURLcode result = CURLE_OK;
2299 result = curl_easy_setopt(conn->connection,
2300 CURLOPT_PUT,
2301 Bool_val(option));
2303 if (result != CURLE_OK)
2304 raiseError(conn, result);
2306 CAMLreturn0;
2309 static void handleUserPwd(Connection *conn, value option)
2311 CAMLparam1(option);
2312 CURLcode result = CURLE_OK;
2314 Store_field(conn->ocamlValues, OcamlUserPWD, option);
2316 if (conn->userPwd != NULL)
2317 free(conn->userPwd);
2319 conn->userPwd = strdup(String_val(option));
2321 result = curl_easy_setopt(conn->connection,
2322 CURLOPT_USERPWD,
2323 conn->userPwd);
2325 if (result != CURLE_OK)
2326 raiseError(conn, result);
2328 CAMLreturn0;
2331 static void handleProxyUserPwd(Connection *conn, value option)
2333 CAMLparam1(option);
2334 CURLcode result = CURLE_OK;
2336 Store_field(conn->ocamlValues, OcamlProxyUserPWD, option);
2338 if (conn->proxyUserPwd != NULL)
2339 free(conn->proxyUserPwd);
2341 conn->proxyUserPwd = strdup(String_val(option));
2343 result = curl_easy_setopt(conn->connection,
2344 CURLOPT_PROXYUSERPWD,
2345 conn->proxyUserPwd);
2347 if (result != CURLE_OK)
2348 raiseError(conn, result);
2350 CAMLreturn0;
2353 static void handleRange(Connection *conn, value option)
2355 CAMLparam1(option);
2356 CURLcode result = CURLE_OK;
2358 Store_field(conn->ocamlValues, OcamlRange, option);
2360 if (conn->range != NULL)
2361 free(conn->range);
2363 conn->range = strdup(String_val(option));
2365 result = curl_easy_setopt(conn->connection,
2366 CURLOPT_RANGE,
2367 conn->range);
2369 if (result != CURLE_OK)
2370 raiseError(conn, result);
2372 CAMLreturn0;
2375 static void handleErrorBuffer(Connection *conn, value option)
2377 CAMLparam1(option);
2378 CURLcode result = CURLE_OK;
2380 Store_field(conn->ocamlValues, OcamlErrorBuffer, option);
2382 if (conn->errorBuffer != NULL)
2383 free(conn->errorBuffer);
2385 conn->errorBuffer = malloc(sizeof(char) * CURL_ERROR_SIZE);
2387 result = curl_easy_setopt(conn->connection,
2388 CURLOPT_ERRORBUFFER,
2389 conn->errorBuffer);
2391 if (result != CURLE_OK)
2392 raiseError(conn, result);
2394 CAMLreturn0;
2397 static void handleTimeout(Connection *conn, value option)
2399 CAMLparam1(option);
2400 CURLcode result = CURLE_OK;
2402 result = curl_easy_setopt(conn->connection,
2403 CURLOPT_TIMEOUT,
2404 Long_val(option));
2406 if (result != CURLE_OK)
2407 raiseError(conn, result);
2409 CAMLreturn0;
2412 static void handlePostFields(Connection *conn, value option)
2414 CAMLparam1(option);
2415 CURLcode result = CURLE_OK;
2417 Store_field(conn->ocamlValues, OcamlPostFields, option);
2419 if (conn->postFields != NULL)
2420 free(conn->postFields);
2422 conn->postFields = malloc(string_length(option)+1);
2423 memcpy(conn->postFields, String_val(option), string_length(option));
2425 result = curl_easy_setopt(conn->connection,
2426 CURLOPT_POSTFIELDS,
2427 conn->postFields);
2429 if (result != CURLE_OK)
2430 raiseError(conn, result);
2432 CAMLreturn0;
2435 static void handlePostFieldSize(Connection *conn, value option)
2437 CAMLparam1(option);
2438 CURLcode result = CURLE_OK;
2440 result = curl_easy_setopt(conn->connection,
2441 CURLOPT_POSTFIELDSIZE,
2442 Long_val(option));
2444 if (result != CURLE_OK)
2445 raiseError(conn, result);
2447 CAMLreturn0;
2450 static void handleReferer(Connection *conn, value option)
2452 CAMLparam1(option);
2453 CURLcode result = CURLE_OK;
2455 Store_field(conn->ocamlValues, OcamlReferer, option);
2457 if (conn->referer != NULL)
2458 free(conn->referer);
2460 conn->referer = strdup(String_val(option));
2462 result = curl_easy_setopt(conn->connection,
2463 CURLOPT_REFERER,
2464 conn->referer);
2466 if (result != CURLE_OK)
2467 raiseError(conn, result);
2469 CAMLreturn0;
2472 static void handleUserAgent(Connection *conn, value option)
2474 CAMLparam1(option);
2475 CURLcode result = CURLE_OK;
2477 Store_field(conn->ocamlValues, OcamlUserAgent, option);
2479 if (conn->userAgent != NULL)
2480 free(conn->userAgent);
2482 conn->userAgent = strdup(String_val(option));
2484 result = curl_easy_setopt(conn->connection,
2485 CURLOPT_USERAGENT,
2486 conn->userAgent);
2488 if (result != CURLE_OK)
2489 raiseError(conn, result);
2491 CAMLreturn0;
2494 static void handleFTPPort(Connection *conn, value option)
2496 CAMLparam1(option);
2497 CURLcode result = CURLE_OK;
2499 Store_field(conn->ocamlValues, OcamlFTPPort, option);
2501 if (conn->ftpPort != NULL)
2502 free(conn->ftpPort);
2504 conn->ftpPort = strdup(String_val(option));
2506 result = curl_easy_setopt(conn->connection,
2507 CURLOPT_FTPPORT,
2508 conn->ftpPort);
2510 if (result != CURLE_OK)
2511 raiseError(conn, result);
2513 CAMLreturn0;
2516 static void handleLowSpeedLimit(Connection *conn, value option)
2518 CAMLparam1(option);
2519 CURLcode result = CURLE_OK;
2521 result = curl_easy_setopt(conn->connection,
2522 CURLOPT_LOW_SPEED_LIMIT,
2523 Long_val(option));
2525 if (result != CURLE_OK)
2526 raiseError(conn, result);
2528 CAMLreturn0;
2531 static void handleLowSpeedTime(Connection *conn, value option)
2533 CAMLparam1(option);
2534 CURLcode result = CURLE_OK;
2536 result = curl_easy_setopt(conn->connection,
2537 CURLOPT_LOW_SPEED_TIME,
2538 Long_val(option));
2540 if (result != CURLE_OK)
2541 raiseError(conn, result);
2543 CAMLreturn0;
2546 static void handleResumeFrom(Connection *conn, value option)
2548 CAMLparam1(option);
2549 CURLcode result = CURLE_OK;
2551 result = curl_easy_setopt(conn->connection,
2552 CURLOPT_RESUME_FROM,
2553 Long_val(option));
2555 if (result != CURLE_OK)
2556 raiseError(conn, result);
2558 CAMLreturn0;
2561 static void handleCookie(Connection *conn, value option)
2563 CAMLparam1(option);
2564 CURLcode result = CURLE_OK;
2566 Store_field(conn->ocamlValues, OcamlCookie, option);
2568 if (conn->cookie != NULL)
2569 free(conn->cookie);
2571 conn->cookie = strdup(String_val(option));
2573 result = curl_easy_setopt(conn->connection,
2574 CURLOPT_COOKIE,
2575 conn->cookie);
2577 if (result != CURLE_OK)
2578 raiseError(conn, result);
2580 CAMLreturn0;
2583 static void handleHTTPHeader(Connection *conn, value option)
2585 CAMLparam1(option);
2586 CAMLlocal1(listIter);
2587 CURLcode result = CURLE_OK;
2588 char *str;
2590 Store_field(conn->ocamlValues, OcamlHTTPHeader, option);
2592 if (conn->httpHeader != NULL)
2593 free_curl_slist(conn->httpHeader);
2595 conn->httpHeader = NULL;
2597 listIter = option;
2599 while (!Is_long(listIter))
2601 if (Tag_val(Field(listIter, 0)) != String_tag)
2602 failwith("Not a string");
2604 str = strdup(String_val(Field(listIter, 0)));
2606 conn->httpHeader = curl_slist_append(conn->httpHeader, str);
2608 listIter = Field(listIter, 1);
2611 result = curl_easy_setopt(conn->connection,
2612 CURLOPT_HTTPHEADER,
2613 conn->httpHeader);
2615 if (result != CURLE_OK)
2616 raiseError(conn, result);
2618 CAMLreturn0;
2621 static void handleHTTPPost(Connection *conn, value option)
2623 CAMLparam1(option);
2624 CAMLlocal3(listIter, formItem, contentType);
2625 CURLcode result = CURLE_OK;
2626 char *str1, *str2, *str3, *str4;
2628 listIter = option;
2630 Store_field(conn->ocamlValues, OcamlHTTPPost, option);
2632 if (conn->httpPostFirst != NULL)
2633 curl_formfree(conn->httpPostFirst);
2635 conn->httpPostFirst = NULL;
2636 conn->httpPostLast = NULL;
2638 if (conn->httpPostStrings != NULL)
2639 free_curl_slist(conn->httpPostStrings);
2641 while (!Is_long(listIter))
2643 formItem = Field(listIter, 0);
2645 switch (Tag_val(formItem))
2647 case 0: /* CURLFORM_CONTENT */
2648 if (Wosize_val(formItem) < 3)
2650 failwith("Incorrect CURLFORM_CONTENT parameters");
2653 if (Is_long(Field(formItem, 2)) &&
2654 Long_val(Field(formItem, 2)) == 0)
2656 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2657 memcpy(str1,
2658 String_val(Field(formItem, 0)),
2659 string_length(Field(formItem, 0)));
2660 str1[string_length(Field(formItem, 0))] = 0;
2661 conn->httpPostStrings =
2662 curl_slist_append(conn->httpPostStrings, str1);
2664 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2665 memcpy(str2,
2666 String_val(Field(formItem, 1)),
2667 string_length(Field(formItem, 1)));
2668 str2[string_length(Field(formItem, 1))] = 0;
2669 conn->httpPostStrings =
2670 curl_slist_append(conn->httpPostStrings, str2);
2672 curl_formadd(&conn->httpPostFirst,
2673 &conn->httpPostLast,
2674 CURLFORM_PTRNAME,
2675 str1,
2676 CURLFORM_NAMELENGTH,
2677 string_length(Field(formItem, 0)),
2678 CURLFORM_PTRCONTENTS,
2679 str2,
2680 CURLFORM_CONTENTSLENGTH,
2681 string_length(Field(formItem, 1)),
2682 CURLFORM_END);
2684 else if (Is_block(Field(formItem, 2)))
2686 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2687 memcpy(str1,
2688 String_val(Field(formItem, 0)),
2689 string_length(Field(formItem, 0)));
2690 str1[string_length(Field(formItem, 0))] = 0;
2691 conn->httpPostStrings =
2692 curl_slist_append(conn->httpPostStrings, str1);
2694 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2695 memcpy(str2,
2696 String_val(Field(formItem, 1)),
2697 string_length(Field(formItem, 1)));
2698 str2[string_length(Field(formItem, 1))] = 0;
2699 conn->httpPostStrings =
2700 curl_slist_append(conn->httpPostStrings, str2);
2702 contentType = Field(formItem, 2);
2704 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2705 memcpy(str3,
2706 String_val(Field(contentType, 0)),
2707 string_length(Field(contentType, 0)));
2708 str3[string_length(Field(contentType, 0))] = 0;
2709 conn->httpPostStrings =
2710 curl_slist_append(conn->httpPostStrings, str3);
2712 curl_formadd(&conn->httpPostFirst,
2713 &conn->httpPostLast,
2714 CURLFORM_PTRNAME,
2715 str1,
2716 CURLFORM_NAMELENGTH,
2717 string_length(Field(formItem, 0)),
2718 CURLFORM_PTRCONTENTS,
2719 str2,
2720 CURLFORM_CONTENTSLENGTH,
2721 string_length(Field(formItem, 1)),
2722 CURLFORM_CONTENTTYPE,
2723 str3,
2724 CURLFORM_END);
2726 else
2728 failwith("Incorrect CURLFORM_CONTENT parameters");
2730 break;
2732 case 1: /* CURLFORM_FILECONTENT */
2733 if (Wosize_val(formItem) < 3)
2735 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2738 if (Is_long(Field(formItem, 2)) &&
2739 Long_val(Field(formItem, 2)) == 0)
2741 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2742 memcpy(str1,
2743 String_val(Field(formItem, 0)),
2744 string_length(Field(formItem, 0)));
2745 str1[string_length(Field(formItem, 0))] = 0;
2746 conn->httpPostStrings =
2747 curl_slist_append(conn->httpPostStrings, str1);
2749 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2750 memcpy(str2,
2751 String_val(Field(formItem, 1)),
2752 string_length(Field(formItem, 1)));
2753 str2[string_length(Field(formItem, 1))] = 0;
2754 conn->httpPostStrings =
2755 curl_slist_append(conn->httpPostStrings, str2);
2757 curl_formadd(&conn->httpPostFirst,
2758 &conn->httpPostLast,
2759 CURLFORM_PTRNAME,
2760 str1,
2761 CURLFORM_NAMELENGTH,
2762 string_length(Field(formItem, 0)),
2763 CURLFORM_FILECONTENT,
2764 str2,
2765 CURLFORM_END);
2767 else if (Is_block(Field(formItem, 2)))
2769 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2770 memcpy(str1,
2771 String_val(Field(formItem, 0)),
2772 string_length(Field(formItem, 0)));
2773 str1[string_length(Field(formItem, 0))] = 0;
2774 conn->httpPostStrings =
2775 curl_slist_append(conn->httpPostStrings, str1);
2777 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2778 memcpy(str2,
2779 String_val(Field(formItem, 1)),
2780 string_length(Field(formItem, 1)));
2781 str2[string_length(Field(formItem, 1))] = 0;
2782 conn->httpPostStrings =
2783 curl_slist_append(conn->httpPostStrings, str2);
2785 contentType = Field(formItem, 2);
2787 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2788 memcpy(str3,
2789 String_val(Field(contentType, 0)),
2790 string_length(Field(contentType, 0)));
2791 str3[string_length(Field(contentType, 0))] = 0;
2792 conn->httpPostStrings =
2793 curl_slist_append(conn->httpPostStrings, str3);
2795 curl_formadd(&conn->httpPostFirst,
2796 &conn->httpPostLast,
2797 CURLFORM_PTRNAME,
2798 str1,
2799 CURLFORM_NAMELENGTH,
2800 string_length(Field(formItem, 0)),
2801 CURLFORM_FILECONTENT,
2802 str2,
2803 CURLFORM_CONTENTTYPE,
2804 str3,
2805 CURLFORM_END);
2807 else
2809 failwith("Incorrect CURLFORM_FILECONTENT parameters");
2811 break;
2813 case 2: /* CURLFORM_FILE */
2814 if (Wosize_val(formItem) < 3)
2816 failwith("Incorrect CURLFORM_FILE parameters");
2819 if (Is_long(Field(formItem, 2)) &&
2820 Long_val(Field(formItem, 2)) == 0)
2822 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2823 memcpy(str1,
2824 String_val(Field(formItem, 0)),
2825 string_length(Field(formItem, 0)));
2826 str1[string_length(Field(formItem, 0))] = 0;
2827 conn->httpPostStrings =
2828 curl_slist_append(conn->httpPostStrings, str1);
2830 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2831 memcpy(str2,
2832 String_val(Field(formItem, 1)),
2833 string_length(Field(formItem, 1)));
2834 str2[string_length(Field(formItem, 1))] = 0;
2835 conn->httpPostStrings =
2836 curl_slist_append(conn->httpPostStrings, str2);
2838 curl_formadd(&conn->httpPostFirst,
2839 &conn->httpPostLast,
2840 CURLFORM_PTRNAME,
2841 str1,
2842 CURLFORM_NAMELENGTH,
2843 string_length(Field(formItem, 0)),
2844 CURLFORM_FILE,
2845 str2,
2846 CURLFORM_END);
2848 else if (Is_block(Field(formItem, 2)))
2850 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2851 memcpy(str1,
2852 String_val(Field(formItem, 0)),
2853 string_length(Field(formItem, 0)));
2854 str1[string_length(Field(formItem, 0))] = 0;
2855 conn->httpPostStrings =
2856 curl_slist_append(conn->httpPostStrings, str1);
2858 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2859 memcpy(str2,
2860 String_val(Field(formItem, 1)),
2861 string_length(Field(formItem, 1)));
2862 str2[string_length(Field(formItem, 1))] = 0;
2863 conn->httpPostStrings =
2864 curl_slist_append(conn->httpPostStrings, str2);
2866 contentType = Field(formItem, 2);
2868 str3 = (char *)malloc(string_length(Field(contentType, 0))+1);
2869 memcpy(str3,
2870 String_val(Field(contentType, 0)),
2871 string_length(Field(contentType, 0)));
2872 str3[string_length(Field(contentType, 0))] = 0;
2873 conn->httpPostStrings =
2874 curl_slist_append(conn->httpPostStrings, str3);
2876 curl_formadd(&conn->httpPostFirst,
2877 &conn->httpPostLast,
2878 CURLFORM_PTRNAME,
2879 str1,
2880 CURLFORM_NAMELENGTH,
2881 string_length(Field(formItem, 0)),
2882 CURLFORM_FILE,
2883 str2,
2884 CURLFORM_CONTENTTYPE,
2885 str3,
2886 CURLFORM_END);
2888 else
2890 failwith("Incorrect CURLFORM_FILE parameters");
2892 break;
2894 case 3: /* CURLFORM_BUFFER */
2895 if (Wosize_val(formItem) < 4)
2897 failwith("Incorrect CURLFORM_BUFFER parameters");
2900 if (Is_long(Field(formItem, 3)) &&
2901 Long_val(Field(formItem, 3)) == 0)
2903 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2904 memcpy(str1,
2905 String_val(Field(formItem, 0)),
2906 string_length(Field(formItem, 0)));
2907 str1[string_length(Field(formItem, 0))] = 0;
2908 conn->httpPostStrings =
2909 curl_slist_append(conn->httpPostStrings, str1);
2911 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2912 memcpy(str2,
2913 String_val(Field(formItem, 1)),
2914 string_length(Field(formItem, 1)));
2915 str2[string_length(Field(formItem, 1))] = 0;
2916 conn->httpPostStrings =
2917 curl_slist_append(conn->httpPostStrings, str2);
2919 str3 = (char *)malloc(string_length(Field(formItem, 2))+1);
2920 memcpy(str3,
2921 String_val(Field(formItem, 2)),
2922 string_length(Field(formItem, 2)));
2923 str3[string_length(Field(formItem, 2))] = 0;
2924 conn->httpPostStrings =
2925 curl_slist_append(conn->httpPostStrings, str3);
2927 curl_formadd(&conn->httpPostFirst,
2928 &conn->httpPostLast,
2929 CURLFORM_PTRNAME,
2930 str1,
2931 CURLFORM_NAMELENGTH,
2932 string_length(Field(formItem, 0)),
2933 CURLFORM_BUFFER,
2934 str2,
2935 CURLFORM_BUFFERPTR,
2936 str3,
2937 CURLFORM_BUFFERLENGTH,
2938 string_length(Field(formItem, 2)),
2939 CURLFORM_END);
2941 else if (Is_block(Field(formItem, 3)))
2943 str1 = (char *)malloc(string_length(Field(formItem, 0))+1);
2944 memcpy(str1,
2945 String_val(Field(formItem, 0)),
2946 string_length(Field(formItem, 0)));
2947 str1[string_length(Field(formItem, 0))] = 0;
2948 conn->httpPostStrings =
2949 curl_slist_append(conn->httpPostStrings, str1);
2951 str2 = (char *)malloc(string_length(Field(formItem, 1))+1);
2952 memcpy(str2,
2953 String_val(Field(formItem, 1)),
2954 string_length(Field(formItem, 1)));
2955 str2[string_length(Field(formItem, 1))] = 0;
2956 conn->httpPostStrings =
2957 curl_slist_append(conn->httpPostStrings, str2);
2959 str3 = (char *)malloc(string_length(Field(formItem, 2))+1);
2960 memcpy(str3,
2961 String_val(Field(formItem, 2)),
2962 string_length(Field(formItem, 2)));
2963 str3[string_length(Field(formItem, 2))] = 0;
2964 conn->httpPostStrings =
2965 curl_slist_append(conn->httpPostStrings, str3);
2967 contentType = Field(formItem, 3);
2969 str4 = (char *)malloc(string_length(Field(contentType, 0))+1);
2970 memcpy(str4,
2971 String_val(Field(contentType, 0)),
2972 string_length(Field(contentType, 0)));
2973 str4[string_length(Field(contentType, 0))] = 0;
2974 conn->httpPostStrings =
2975 curl_slist_append(conn->httpPostStrings, str4);
2977 curl_formadd(&conn->httpPostFirst,
2978 &conn->httpPostLast,
2979 CURLFORM_PTRNAME,
2980 str1,
2981 CURLFORM_NAMELENGTH,
2982 string_length(Field(formItem, 0)),
2983 CURLFORM_BUFFER,
2984 str2,
2985 CURLFORM_BUFFERPTR,
2986 str3,
2987 CURLFORM_BUFFERLENGTH,
2988 string_length(Field(formItem, 2)),
2989 CURLFORM_CONTENTTYPE,
2990 str4,
2991 CURLFORM_END);
2993 else
2995 failwith("Incorrect CURLFORM_BUFFER parameters");
2997 break;
3000 listIter = Field(listIter, 1);
3003 result = curl_easy_setopt(conn->connection,
3004 CURLOPT_HTTPPOST,
3005 conn->httpPostFirst);
3007 if (result != CURLE_OK)
3008 raiseError(conn, result);
3010 CAMLreturn0;
3013 static void handleSSLCert(Connection *conn, value option)
3015 CAMLparam1(option);
3016 CURLcode result = CURLE_OK;
3018 Store_field(conn->ocamlValues, OcamlSSLCert, option);
3020 if (conn->sslCert != NULL)
3021 free(conn->sslCert);
3023 conn->sslCert = strdup(String_val(option));
3025 result = curl_easy_setopt(conn->connection,
3026 CURLOPT_SSLCERT,
3027 conn->sslCert);
3029 if (result != CURLE_OK)
3030 raiseError(conn, result);
3032 CAMLreturn0;
3035 static void handleSSLCertType(Connection *conn, value option)
3037 CAMLparam1(option);
3038 CURLcode result = CURLE_OK;
3040 Store_field(conn->ocamlValues, OcamlSSLCertType, option);
3042 if (conn->sslCertType != NULL)
3043 free(conn->sslCertType);
3045 conn->sslCertType = strdup(String_val(option));
3047 result = curl_easy_setopt(conn->connection,
3048 CURLOPT_SSLCERTTYPE,
3049 conn->sslCertType);
3051 if (result != CURLE_OK)
3052 raiseError(conn, result);
3054 CAMLreturn0;
3057 static void handleSSLCertPasswd(Connection *conn, value option)
3059 CAMLparam1(option);
3060 CURLcode result = CURLE_OK;
3062 Store_field(conn->ocamlValues, OcamlSSLCertPasswd, option);
3064 if (conn->sslCertPasswd != NULL)
3065 free(conn->sslCertPasswd);
3067 conn->sslCertPasswd = strdup(String_val(option));
3069 result = curl_easy_setopt(conn->connection,
3070 CURLOPT_SSLCERTPASSWD,
3071 conn->sslCertPasswd);
3073 if (result != CURLE_OK)
3074 raiseError(conn, result);
3076 CAMLreturn0;
3079 static void handleSSLKey(Connection *conn, value option)
3081 CAMLparam1(option);
3082 CURLcode result = CURLE_OK;
3084 Store_field(conn->ocamlValues, OcamlSSLKey, option);
3086 if (conn->sslKey != NULL)
3087 free(conn->sslKey);
3089 conn->sslKey = strdup(String_val(option));
3091 result = curl_easy_setopt(conn->connection,
3092 CURLOPT_SSLKEY,
3093 conn->sslKey);
3095 if (result != CURLE_OK)
3096 raiseError(conn, result);
3098 CAMLreturn0;
3101 static void handleSSLKeyType(Connection *conn, value option)
3103 CAMLparam1(option);
3104 CURLcode result = CURLE_OK;
3106 Store_field(conn->ocamlValues, OcamlSSLKeyType, option);
3108 if (conn->sslKeyType != NULL)
3109 free(conn->sslKeyType);
3111 conn->sslKeyType = strdup(String_val(option));
3113 result = curl_easy_setopt(conn->connection,
3114 CURLOPT_SSLKEYTYPE,
3115 conn->sslKeyType);
3117 if (result != CURLE_OK)
3118 raiseError(conn, result);
3120 CAMLreturn0;
3123 static void handleSSLKeyPasswd(Connection *conn, value option)
3125 CAMLparam1(option);
3126 CURLcode result = CURLE_OK;
3128 Store_field(conn->ocamlValues, OcamlSSLKeyPasswd, option);
3130 if (conn->sslKeyPasswd != NULL)
3131 free(conn->sslKeyPasswd);
3133 conn->sslKeyPasswd = strdup(String_val(option));
3135 result = curl_easy_setopt(conn->connection,
3136 CURLOPT_SSLKEYPASSWD,
3137 conn->sslKeyPasswd);
3139 if (result != CURLE_OK)
3140 raiseError(conn, result);
3142 CAMLreturn0;
3145 static void handleSSLEngine(Connection *conn, value option)
3147 CAMLparam1(option);
3148 CURLcode result = CURLE_OK;
3150 Store_field(conn->ocamlValues, OcamlSSLEngine, option);
3152 if (conn->sslEngine != NULL)
3153 free(conn->sslEngine);
3155 conn->sslEngine = strdup(String_val(option));
3157 result = curl_easy_setopt(conn->connection,
3158 CURLOPT_SSLENGINE,
3159 conn->sslEngine);
3161 if (result != CURLE_OK)
3162 raiseError(conn, result);
3164 CAMLreturn0;
3167 static void handleSSLEngineDefault(Connection *conn, value option)
3169 CAMLparam1(option);
3170 CURLcode result = CURLE_OK;
3172 result = curl_easy_setopt(conn->connection,
3173 CURLOPT_SSLENGINE_DEFAULT,
3174 Bool_val(option));
3176 if (result != CURLE_OK)
3177 raiseError(conn, result);
3179 CAMLreturn0;
3182 static void handleCRLF(Connection *conn, value option)
3184 CAMLparam1(option);
3185 CURLcode result = CURLE_OK;
3187 result = curl_easy_setopt(conn->connection,
3188 CURLOPT_CRLF,
3189 Bool_val(option));
3191 if (result != CURLE_OK)
3192 raiseError(conn, result);
3194 CAMLreturn0;
3197 static void handleQuote(Connection *conn, value option)
3199 CAMLparam1(option);
3200 CAMLlocal1(listIter);
3201 CURLcode result = CURLE_OK;
3202 char *str;
3204 Store_field(conn->ocamlValues, OcamlQuote, option);
3206 if (conn->quote != NULL)
3207 free_curl_slist(conn->quote);
3209 conn->quote = NULL;
3211 listIter = option;
3213 while (!Is_long(listIter))
3215 if (Tag_val(Field(listIter, 0)) != String_tag)
3216 failwith("Not a string");
3218 str = strdup(String_val(Field(listIter, 0)));
3220 conn->quote = curl_slist_append(conn->quote, str);
3222 listIter = Field(listIter, 1);
3225 result = curl_easy_setopt(conn->connection,
3226 CURLOPT_QUOTE,
3227 conn->quote);
3229 if (result != CURLE_OK)
3230 raiseError(conn, result);
3232 CAMLreturn0;
3235 static void handlePostQuote(Connection *conn, value option)
3237 CAMLparam1(option);
3238 CAMLlocal1(listIter);
3239 CURLcode result = CURLE_OK;
3240 char *str;
3242 Store_field(conn->ocamlValues, OcamlPostQuote, option);
3244 if (conn->postQuote != NULL)
3245 free_curl_slist(conn->postQuote);
3247 conn->postQuote = NULL;
3249 listIter = option;
3251 while (!Is_long(listIter))
3253 if (Tag_val(Field(listIter, 0)) != String_tag)
3254 failwith("Not a string");
3256 str = strdup(String_val(Field(listIter, 0)));
3258 conn->postQuote = curl_slist_append(conn->postQuote, str);
3260 listIter = Field(listIter, 1);
3263 result = curl_easy_setopt(conn->connection,
3264 CURLOPT_POSTQUOTE,
3265 conn->postQuote);
3267 if (result != CURLE_OK)
3268 raiseError(conn, result);
3270 CAMLreturn0;
3273 static void handleHeaderFunction(Connection *conn, value option)
3275 CAMLparam1(option);
3276 CURLcode result = CURLE_OK;
3278 if (Tag_val(option) == Closure_tag)
3279 Store_field(conn->ocamlValues, OcamlHeaderCallback, option);
3280 else
3281 failwith("Not a proper closure");
3283 result = curl_easy_setopt(conn->connection,
3284 CURLOPT_HEADERFUNCTION,
3285 headerFunction);
3287 if (result != CURLE_OK)
3288 raiseError(conn, result);
3290 result = curl_easy_setopt(conn->connection,
3291 CURLOPT_WRITEHEADER,
3292 conn);
3294 if (result != CURLE_OK)
3295 raiseError(conn, result);
3297 CAMLreturn0;
3300 static void handleCookieFile(Connection *conn, value option)
3302 CAMLparam1(option);
3303 CURLcode result = CURLE_OK;
3305 Store_field(conn->ocamlValues, OcamlCookieFile, option);
3307 if (conn->cookieFile != NULL)
3308 free(conn->cookieFile);
3310 conn->cookieFile = strdup(String_val(option));
3312 result = curl_easy_setopt(conn->connection,
3313 CURLOPT_COOKIEFILE,
3314 conn->cookieFile);
3316 if (result != CURLE_OK)
3317 raiseError(conn, result);
3319 CAMLreturn0;
3322 static void handleSSLVersion(Connection *conn, value option)
3324 CAMLparam1(option);
3325 CURLcode result = CURLE_OK;
3327 result = curl_easy_setopt(conn->connection,
3328 CURLOPT_SSLVERSION,
3329 Long_val(option));
3331 if (result != CURLE_OK)
3332 raiseError(conn, result);
3334 CAMLreturn0;
3337 static void handleTimeCondition(Connection *conn, value option)
3339 CAMLparam1(option);
3340 CURLcode result = CURLE_OK;
3342 switch (Long_val(option))
3344 case 0: /* TIMECOND_IFMODSINCE */
3345 result = curl_easy_setopt(conn->connection,
3346 CURLOPT_TIMECONDITION,
3347 CURL_TIMECOND_IFMODSINCE);
3348 break;
3350 case 1: /* TIMECOND_IFUNMODSINCE */
3351 result = curl_easy_setopt(conn->connection,
3352 CURLOPT_TIMECONDITION,
3353 CURL_TIMECOND_IFUNMODSINCE);
3354 break;
3356 default:
3357 failwith("Invalid TIMECOND Option");
3358 break;
3361 if (result != CURLE_OK)
3362 raiseError(conn, result);
3364 CAMLreturn0;
3367 static void handleTimeValue(Connection *conn, value option)
3369 CAMLparam1(option);
3370 CURLcode result = CURLE_OK;
3372 result = curl_easy_setopt(conn->connection,
3373 CURLOPT_TIMEVALUE,
3374 Int32_val(option));
3376 if (result != CURLE_OK)
3377 raiseError(conn, result);
3379 CAMLreturn0;
3382 static void handleCustomRequest(Connection *conn, value option)
3384 CAMLparam1(option);
3385 CURLcode result = CURLE_OK;
3387 Store_field(conn->ocamlValues, OcamlCustomRequest, option);
3389 if (conn->customRequest != NULL)
3390 free(conn->customRequest);
3392 conn->customRequest = strdup(String_val(option));
3394 result = curl_easy_setopt(conn->connection,
3395 CURLOPT_CUSTOMREQUEST,
3396 conn->customRequest);
3398 if (result != CURLE_OK)
3399 raiseError(conn, result);
3401 CAMLreturn0;
3404 static void handleInterface(Connection *conn, value option)
3406 CAMLparam1(option);
3407 CURLcode result = CURLE_OK;
3409 Store_field(conn->ocamlValues, OcamlInterface, option);
3411 if (conn->interface != NULL)
3412 free(conn->interface);
3414 conn->interface = strdup(String_val(option));
3416 result = curl_easy_setopt(conn->connection,
3417 CURLOPT_INTERFACE,
3418 conn->interface);
3420 if (result != CURLE_OK)
3421 raiseError(conn, result);
3423 CAMLreturn0;
3426 static void handleKRB4Level(Connection *conn, value option)
3428 CAMLparam1(option);
3429 CURLcode result = CURLE_OK;
3431 switch (Long_val(option))
3433 case 0: /* KRB4_NONE */
3434 result = curl_easy_setopt(conn->connection,
3435 CURLOPT_KRB4LEVEL,
3436 NULL);
3437 break;
3439 case 1: /* KRB4_CLEAR */
3440 result = curl_easy_setopt(conn->connection,
3441 CURLOPT_KRB4LEVEL,
3442 "clear");
3443 break;
3445 case 2: /* KRB4_SAFE */
3446 result = curl_easy_setopt(conn->connection,
3447 CURLOPT_KRB4LEVEL,
3448 "safe");
3449 break;
3451 case 3: /* KRB4_CONFIDENTIAL */
3452 result = curl_easy_setopt(conn->connection,
3453 CURLOPT_KRB4LEVEL,
3454 "confidential");
3455 break;
3457 case 4: /* KRB4_PRIVATE */
3458 result = curl_easy_setopt(conn->connection,
3459 CURLOPT_KRB4LEVEL,
3460 "private");
3461 break;
3463 default:
3464 failwith("Invalid KRB4 Option");
3465 break;
3468 if (result != CURLE_OK)
3469 raiseError(conn, result);
3471 CAMLreturn0;
3474 static void handleProgressFunction(Connection *conn, value option)
3476 CAMLparam1(option);
3477 CURLcode result = CURLE_OK;
3479 if (Tag_val(option) == Closure_tag)
3480 Store_field(conn->ocamlValues, OcamlProgressCallback, option);
3481 else
3482 failwith("Not a proper closure");
3484 result = curl_easy_setopt(conn->connection,
3485 CURLOPT_PROGRESSFUNCTION,
3486 progressFunction);
3487 if (result != CURLE_OK)
3488 raiseError(conn, result);
3490 result = curl_easy_setopt(conn->connection,
3491 CURLOPT_PROGRESSDATA,
3492 conn);
3494 if (result != CURLE_OK)
3495 raiseError(conn, result);
3497 CAMLreturn0;
3500 static void handleSSLVerifyPeer(Connection *conn, value option)
3502 CAMLparam1(option);
3503 CURLcode result = CURLE_OK;
3505 result = curl_easy_setopt(conn->connection,
3506 CURLOPT_SSL_VERIFYPEER,
3507 Bool_val(option));
3509 if (result != CURLE_OK)
3510 raiseError(conn, result);
3512 CAMLreturn0;
3515 static void handleCAInfo(Connection *conn, value option)
3517 CAMLparam1(option);
3518 CURLcode result = CURLE_OK;
3520 Store_field(conn->ocamlValues, OcamlCAInfo, option);
3522 if (conn->caInfo != NULL)
3523 free(conn->caInfo);
3525 conn->caInfo = strdup(String_val(option));
3527 result = curl_easy_setopt(conn->connection,
3528 CURLOPT_CAINFO,
3529 conn->caInfo);
3531 if (result != CURLE_OK)
3532 raiseError(conn, result);
3534 CAMLreturn0;
3537 static void handleCAPath(Connection *conn, value option)
3539 CAMLparam1(option);
3540 CURLcode result = CURLE_OK;
3542 Store_field(conn->ocamlValues, OcamlCAPath, option);
3544 if (conn->caPath != NULL)
3545 free(conn->caPath);
3547 conn->caPath = strdup(String_val(option));
3549 result = curl_easy_setopt(conn->connection,
3550 CURLOPT_CAPATH,
3551 conn->caPath);
3553 if (result != CURLE_OK)
3554 raiseError(conn, result);
3556 CAMLreturn0;
3559 static void handleFileTime(Connection *conn, value option)
3561 CAMLparam1(option);
3562 CURLcode result = CURLE_OK;
3564 result = curl_easy_setopt(conn->connection,
3565 CURLOPT_FILETIME,
3566 Bool_val(option));
3568 if (result != CURLE_OK)
3569 raiseError(conn, result);
3571 CAMLreturn0;
3574 static void handleMaxRedirs(Connection *conn, value option)
3576 CAMLparam1(option);
3577 CURLcode result = CURLE_OK;
3579 result = curl_easy_setopt(conn->connection,
3580 CURLOPT_MAXREDIRS,
3581 Long_val(option));
3583 if (result != CURLE_OK)
3584 raiseError(conn, result);
3586 CAMLreturn0;
3589 static void handleMaxConnects(Connection *conn, value option)
3591 CAMLparam1(option);
3592 CURLcode result = CURLE_OK;
3594 result = curl_easy_setopt(conn->connection,
3595 CURLOPT_MAXCONNECTS,
3596 Long_val(option));
3598 if (result != CURLE_OK)
3599 raiseError(conn, result);
3601 CAMLreturn0;
3604 static void handleClosePolicy(Connection *conn, value option)
3606 CAMLparam1(option);
3607 CURLcode result = CURLE_OK;
3609 switch (Long_val(option))
3611 case 0: /* CLOSEPOLICY_OLDEST */
3612 result = curl_easy_setopt(conn->connection,
3613 CURLOPT_CLOSEPOLICY,
3614 CURLCLOSEPOLICY_OLDEST);
3615 break;
3617 case 1: /* CLOSEPOLICY_LEAST_RECENTLY_USED */
3618 result = curl_easy_setopt(conn->connection,
3619 CURLOPT_CLOSEPOLICY,
3620 CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
3621 break;
3623 default:
3624 failwith("Invalid CLOSEPOLICY Option");
3625 break;
3628 if (result != CURLE_OK)
3629 raiseError(conn, result);
3631 CAMLreturn0;
3634 static void handleFreshConnect(Connection *conn, value option)
3636 CAMLparam1(option);
3637 CURLcode result = CURLE_OK;
3639 result = curl_easy_setopt(conn->connection,
3640 CURLOPT_FRESH_CONNECT,
3641 Bool_val(option));
3643 if (result != CURLE_OK)
3644 raiseError(conn, result);
3646 CAMLreturn0;
3649 static void handleForbidReuse(Connection *conn, value option)
3651 CAMLparam1(option);
3652 CURLcode result = CURLE_OK;
3654 result = curl_easy_setopt(conn->connection,
3655 CURLOPT_FORBID_REUSE,
3656 Bool_val(option));
3658 if (result != CURLE_OK)
3659 raiseError(conn, result);
3661 CAMLreturn0;
3664 static void handleRandomFile(Connection *conn, value option)
3666 CAMLparam1(option);
3667 CURLcode result = CURLE_OK;
3669 Store_field(conn->ocamlValues, OcamlRandomFile, option);
3671 if (conn->randomFile != NULL)
3672 free(conn->randomFile);
3674 conn->randomFile = strdup(String_val(option));
3676 result = curl_easy_setopt(conn->connection,
3677 CURLOPT_RANDOM_FILE,
3678 conn->randomFile);
3680 if (result != CURLE_OK)
3681 raiseError(conn, result);
3683 CAMLreturn0;
3686 static void handleEGDSocket(Connection *conn, value option)
3688 CAMLparam1(option);
3689 CURLcode result = CURLE_OK;
3691 Store_field(conn->ocamlValues, OcamlEGDSocket, option);
3693 if (conn->egdSocket != NULL)
3694 free(conn->egdSocket);
3696 conn->egdSocket = strdup(String_val(option));
3698 result = curl_easy_setopt(conn->connection,
3699 CURLOPT_EGDSOCKET,
3700 conn->egdSocket);
3702 if (result != CURLE_OK)
3703 raiseError(conn, result);
3705 CAMLreturn0;
3708 static void handleConnectTimeout(Connection *conn, value option)
3710 CAMLparam1(option);
3711 CURLcode result = CURLE_OK;
3713 result = curl_easy_setopt(conn->connection,
3714 CURLOPT_CONNECTTIMEOUT,
3715 Long_val(option));
3717 if (result != CURLE_OK)
3718 raiseError(conn, result);
3720 CAMLreturn0;
3723 static void handleHTTPGet(Connection *conn, value option)
3725 CAMLparam1(option);
3726 CURLcode result = CURLE_OK;
3728 result = curl_easy_setopt(conn->connection,
3729 CURLOPT_HTTPGET,
3730 Bool_val(option));
3732 if (result != CURLE_OK)
3733 raiseError(conn, result);
3735 CAMLreturn0;
3738 static void handleSSLVerifyHost(Connection *conn, value option)
3740 CAMLparam1(option);
3741 CURLcode result = CURLE_OK;
3743 switch (Long_val(option))
3745 case 0: /* SSLVERIFYHOST_EXISTENCE */
3746 result = curl_easy_setopt(conn->connection,
3747 CURLOPT_SSL_VERIFYHOST,
3749 break;
3751 case 1: /* SSLVERIFYHOST_HOSTNAME */
3752 result = curl_easy_setopt(conn->connection,
3753 CURLOPT_SSL_VERIFYHOST,
3755 break;
3757 default:
3758 failwith("Invalid SSLVERIFYHOST Option");
3759 break;
3762 if (result != CURLE_OK)
3763 raiseError(conn, result);
3765 CAMLreturn0;
3768 static void handleCookieJar(Connection *conn, value option)
3770 CAMLparam1(option);
3771 CURLcode result = CURLE_OK;
3773 Store_field(conn->ocamlValues, OcamlCookieJar, option);
3775 if (conn->cookieJar != NULL)
3776 free(conn->cookieJar);
3778 conn->cookieJar = strdup(String_val(option));
3780 result = curl_easy_setopt(conn->connection,
3781 CURLOPT_COOKIEJAR,
3782 conn->cookieJar);
3784 if (result != CURLE_OK)
3785 raiseError(conn, result);
3787 CAMLreturn0;
3790 static void handleSSLCipherList(Connection *conn, value option)
3792 CAMLparam1(option);
3793 CURLcode result = CURLE_OK;
3795 Store_field(conn->ocamlValues, OcamlSSLCipherList, option);
3797 if (conn->sslCipherList != NULL)
3798 free(conn->sslCipherList);
3800 conn->sslCipherList = strdup(String_val(option));
3802 result = curl_easy_setopt(conn->connection,
3803 CURLOPT_SSL_CIPHER_LIST,
3804 conn->sslCipherList);
3806 if (result != CURLE_OK)
3807 raiseError(conn, result);
3809 CAMLreturn0;
3812 static void handleHTTPVersion(Connection *conn, value option)
3814 CAMLparam1(option);
3815 CURLcode result = CURLE_OK;
3817 switch (Long_val(option))
3819 case 0: /* HTTP_VERSION_NONE */
3820 result = curl_easy_setopt(conn->connection,
3821 CURLOPT_HTTP_VERSION,
3822 CURL_HTTP_VERSION_NONE);
3823 break;
3825 case 1: /* HTTP_VERSION_1_0 */
3826 result = curl_easy_setopt(conn->connection,
3827 CURLOPT_HTTP_VERSION,
3828 CURL_HTTP_VERSION_1_0);
3829 break;
3831 case 2: /* HTTP_VERSION_1_1 */
3832 result = curl_easy_setopt(conn->connection,
3833 CURLOPT_HTTP_VERSION,
3834 CURL_HTTP_VERSION_1_1);
3835 break;
3837 default:
3838 failwith("Invalid HTTP_VERSION Option");
3839 break;
3842 if (result != CURLE_OK)
3843 raiseError(conn, result);
3845 CAMLreturn0;
3848 static void handleFTPUseEPSV(Connection *conn, value option)
3850 CAMLparam1(option);
3851 CURLcode result = CURLE_OK;
3853 result = curl_easy_setopt(conn->connection,
3854 CURLOPT_FTP_USE_EPSV,
3855 Bool_val(option));
3857 if (result != CURLE_OK)
3858 raiseError(conn, result);
3860 CAMLreturn0;
3863 static void handleDNSCacheTimeout(Connection *conn, value option)
3865 CAMLparam1(option);
3866 CURLcode result = CURLE_OK;
3868 result = curl_easy_setopt(conn->connection,
3869 CURLOPT_DNS_CACHE_TIMEOUT,
3870 Long_val(option));
3872 if (result != CURLE_OK)
3873 raiseError(conn, result);
3875 CAMLreturn0;
3878 static void handleDNSUseGlobalCache(Connection *conn, value option)
3880 CAMLparam1(option);
3881 CURLcode result = CURLE_OK;
3883 result = curl_easy_setopt(conn->connection,
3884 CURLOPT_DNS_USE_GLOBAL_CACHE,
3885 Bool_val(option));
3887 if (result != CURLE_OK)
3888 raiseError(conn, result);
3890 CAMLreturn0;
3893 static void handleDebugFunction(Connection *conn, value option)
3895 CAMLparam1(option);
3896 CURLcode result = CURLE_OK;
3898 if (Tag_val(option) == Closure_tag)
3899 Store_field(conn->ocamlValues, OcamlDebugCallback, option);
3900 else
3901 failwith("Not a proper closure");
3903 result = curl_easy_setopt(conn->connection,
3904 CURLOPT_DEBUGFUNCTION,
3905 debugFunction);
3906 if (result != CURLE_OK)
3907 raiseError(conn, result);
3909 result = curl_easy_setopt(conn->connection,
3910 CURLOPT_DEBUGDATA,
3911 conn);
3913 if (result != CURLE_OK)
3914 raiseError(conn, result);
3916 CAMLreturn0;
3919 static void handlePrivate(Connection *conn, value option)
3921 #if HAVE_DECL_CURLOPT_PRIVATE
3922 CAMLparam1(option);
3923 CURLcode result = CURLE_OK;
3925 Store_field(conn->ocamlValues, OcamlPrivate, option);
3927 if (conn->private != NULL)
3928 free(conn->private);
3930 conn->private = strdup(String_val(option));
3932 result = curl_easy_setopt(conn->connection,
3933 CURLOPT_PRIVATE,
3934 conn->private);
3936 if (result != CURLE_OK)
3937 raiseError(conn, result);
3939 CAMLreturn0;
3940 #else
3941 #warning "libcurl does not implement CURLOPT_PRIVATE"
3942 failwith("libcurl does not implement CURLOPT_PRIVATE");
3943 #endif
3946 static void handleHTTP200Aliases(Connection *conn, value option)
3948 #if HAVE_DECL_CURLOPT_HTTP200ALIASES
3949 CAMLparam1(option);
3950 CAMLlocal1(listIter);
3951 CURLcode result = CURLE_OK;
3952 char *str;
3954 Store_field(conn->ocamlValues, OcamlHTTP200Aliases, option);
3956 if (conn->http200Aliases != NULL)
3957 free_curl_slist(conn->http200Aliases);
3959 conn->http200Aliases = NULL;
3961 listIter = option;
3963 while (!Is_long(listIter))
3965 if (Tag_val(Field(listIter, 0)) != String_tag)
3966 failwith("Not a string");
3968 str = strdup(String_val(Field(listIter, 0)));
3970 conn->http200Aliases = curl_slist_append(conn->http200Aliases, str);
3972 listIter = Field(listIter, 1);
3975 result = curl_easy_setopt(conn->connection,
3976 CURLOPT_HTTP200ALIASES,
3977 conn->http200Aliases);
3979 if (result != CURLE_OK)
3980 raiseError(conn, result);
3982 CAMLreturn0;
3983 #else
3984 #warning "libcurl does not implement CURLOPT_HTTP200ALIASES"
3985 failwith("libcurl does not implement CURLOPT_HTTP200ALIASES");
3986 #endif
3989 static void handleUnrestrictedAuth(Connection *conn, value option)
3991 #if HAVE_DECL_CURLOPT_UNRESTRICTED_AUTH
3992 CAMLparam1(option);
3993 CURLcode result = CURLE_OK;
3995 result = curl_easy_setopt(conn->connection,
3996 CURLOPT_UNRESTRICTED_AUTH,
3997 Bool_val(option));
3999 if (result != CURLE_OK)
4000 raiseError(conn, result);
4002 CAMLreturn0;
4003 #else
4004 #warning "libcurl does not implement CURLOPT_UNRESTRICTED_AUTH"
4005 failwith("libcurl does not implement CURLOPT_UNRESTRICTED_AUTH");
4006 #endif
4009 static void handleFTPUseEPRT(Connection *conn, value option)
4011 #if HAVE_DECL_CURLOPT_FTP_USE_EPRT
4012 CAMLparam1(option);
4013 CURLcode result = CURLE_OK;
4015 result = curl_easy_setopt(conn->connection,
4016 CURLOPT_FTP_USE_EPRT,
4017 Bool_val(option));
4019 if (result != CURLE_OK)
4020 raiseError(conn, result);
4022 CAMLreturn0;
4023 #else
4024 #warning "libcurl does not implement CURLOPT_FTP_USE_EPRT"
4025 failwith("libcurl does not implement CURLOPT_FTP_USE_EPRT");
4026 #endif
4029 static void handleHTTPAuth(Connection *conn, value option)
4031 #if HAVE_DECL_CURLOPT_HTTPAUTH
4032 CAMLparam1(option);
4033 CAMLlocal1(listIter);
4034 CURLcode result = CURLE_OK;
4035 long auth = CURLAUTH_NONE;
4037 listIter = option;
4039 while (!Is_long(listIter))
4041 switch (Long_val(Field(listIter, 0)))
4043 case 0: /* CURLAUTH_BASIC */
4044 auth |= CURLAUTH_BASIC;
4045 break;
4047 case 1: /* CURLAUTH_DIGEST */
4048 auth |= CURLAUTH_DIGEST;
4049 break;
4051 case 2: /* CURLAUTH_GSSNEGOTIATE */
4052 auth |= CURLAUTH_GSSNEGOTIATE;
4053 break;
4055 case 3: /* CURLAUTH_NTLM */
4056 auth |= CURLAUTH_NTLM;
4057 break;
4059 case 4: /* CURLAUTH_ANY */
4060 auth |= CURLAUTH_ANY;
4061 break;
4063 case 5: /* CURLAUTH_ANYSAFE */
4064 auth |= CURLAUTH_ANYSAFE;
4065 break;
4067 default:
4068 failwith("Invalid HTTPAUTH Value");
4069 break;
4072 listIter = Field(listIter, 1);
4075 result = curl_easy_setopt(conn->connection,
4076 CURLOPT_HTTPAUTH,
4077 auth);
4079 if (result != CURLE_OK)
4080 raiseError(conn, result);
4082 CAMLreturn0;
4083 #else
4084 #warning "libcurl does not implement CURLOPT_HTTPAUTH"
4085 failwith("libcurl does not implement CURLOPT_HTTPAUTH");
4086 #endif
4089 static void handleFTPCreateMissingDirs(Connection *conn, value option)
4091 #if HAVE_DECL_CURLOPT_FTP_CREATE_MISSING_DIRS
4092 CAMLparam1(option);
4093 CURLcode result = CURLE_OK;
4095 result = curl_easy_setopt(conn->connection,
4096 CURLOPT_FTP_CREATE_MISSING_DIRS,
4097 Bool_val(option));
4099 if (result != CURLE_OK)
4100 raiseError(conn, result);
4102 CAMLreturn0;
4103 #else
4104 #warning "libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS"
4105 failwith("libcurl does not implement CURLOPT_FTP_CREATE_MISSING_DIRS");
4106 #endif
4109 static void handleProxyAuth(Connection *conn, value option)
4111 #if HAVE_DECL_CURLOPT_PROXYAUTH
4112 CAMLparam1(option);
4113 CAMLlocal1(listIter);
4114 CURLcode result = CURLE_OK;
4115 long auth = CURLAUTH_NONE;
4117 listIter = option;
4119 while (!Is_long(listIter))
4121 switch (Long_val(Field(listIter, 0)))
4123 case 0: /* CURLAUTH_BASIC */
4124 auth |= CURLAUTH_BASIC;
4125 break;
4127 case 1: /* CURLAUTH_DIGEST */
4128 auth |= CURLAUTH_DIGEST;
4129 break;
4131 case 2: /* CURLAUTH_GSSNEGOTIATE */
4132 auth |= CURLAUTH_GSSNEGOTIATE;
4133 break;
4135 case 3: /* CURLAUTH_NTLM */
4136 auth |= CURLAUTH_NTLM;
4137 break;
4139 case 4: /* CURLAUTH_ANY */
4140 auth |= CURLAUTH_ANY;
4141 break;
4143 case 5: /* CURLAUTH_ANYSAFE */
4144 auth |= CURLAUTH_ANYSAFE;
4145 break;
4147 default:
4148 failwith("Invalid HTTPAUTH Value");
4149 break;
4152 listIter = Field(listIter, 1);
4155 result = curl_easy_setopt(conn->connection,
4156 CURLOPT_PROXYAUTH,
4157 auth);
4159 if (result != CURLE_OK)
4160 raiseError(conn, result);
4162 CAMLreturn0;
4163 #else
4164 #warning "libcurl does not implement CURLOPT_PROXYAUTH"
4165 failwith("libcurl does not implement CURLOPT_PROXYAUTH");
4166 #endif
4169 static void handleFTPResponseTimeout(Connection *conn, value option)
4171 #if HAVE_DECL_CURLOPT_FTP_RESPONSE_TIMEOUT
4172 CAMLparam1(option);
4173 CURLcode result = CURLE_OK;
4175 result = curl_easy_setopt(conn->connection,
4176 CURLOPT_FTP_RESPONSE_TIMEOUT,
4177 Long_val(option));
4179 if (result != CURLE_OK)
4180 raiseError(conn, result);
4182 CAMLreturn0;
4183 #else
4184 #warning "libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT"
4185 failwith("libcurl does not implement CURLOPT_FTP_RESPONSE_TIMEOUT");
4186 #endif
4189 static void handleIPResolve(Connection *conn, value option)
4191 #if HAVE_DECL_CURLOPT_IPRESOLVE
4192 CAMLparam1(option);
4193 CURLcode result = CURLE_OK;
4195 switch (Long_val(option))
4197 case 0: /* CURL_IPRESOLVE_WHATEVER */
4198 result = curl_easy_setopt(conn->connection,
4199 CURLOPT_IPRESOLVE,
4200 CURL_IPRESOLVE_WHATEVER);
4201 break;
4203 case 1: /* CURL_IPRESOLVE_V4 */
4204 result = curl_easy_setopt(conn->connection,
4205 CURLOPT_IPRESOLVE,
4206 CURL_IPRESOLVE_V4);
4207 break;
4209 case 2: /* CURL_IPRESOLVE_V6 */
4210 result = curl_easy_setopt(conn->connection,
4211 CURLOPT_IPRESOLVE,
4212 CURL_IPRESOLVE_V6);
4213 break;
4215 default:
4216 failwith("Invalid IPRESOLVE Value");
4217 break;
4220 if (result != CURLE_OK)
4221 raiseError(conn, result);
4223 CAMLreturn0;
4224 #else
4225 #warning "libcurl does not implement CURLOPT_IPRESOLVE"
4226 failwith("libcurl does not implement CURLOPT_IPRESOLVE");
4227 #endif
4230 static void handleMaxFileSize(Connection *conn, value option)
4232 #if HAVE_DECL_CURLOPT_MAXFILESIZE
4233 CAMLparam1(option);
4234 CURLcode result = CURLE_OK;
4236 result = curl_easy_setopt(conn->connection,
4237 CURLOPT_MAXFILESIZE,
4238 Int32_val(option));
4240 if (result != CURLE_OK)
4241 raiseError(conn, result);
4243 CAMLreturn0;
4244 #else
4245 #warning "libcurl does not implement CURLOPT_MAXFILESIZE"
4246 failwith("libcurl does not implement CURLOPT_MAXFILESIZE");
4247 #endif
4250 static void handleInFileSizeLarge(Connection *conn, value option)
4252 #if HAVE_DECL_CURLOPT_INFILESIZE_LARGE
4253 CAMLparam1(option);
4254 CURLcode result = CURLE_OK;
4256 result = curl_easy_setopt(conn->connection,
4257 CURLOPT_INFILESIZE_LARGE,
4258 Int64_val(option));
4260 if (result != CURLE_OK)
4261 raiseError(conn, result);
4263 CAMLreturn0;
4264 #else
4265 #warning("libcurl does not implement CURLOPT_INFILESIZE_LARGE")
4266 failwith("libcurl does not implement CURLOPT_INFILESIZE_LARGE");
4267 #endif
4270 static void handleResumeFromLarge(Connection *conn, value option)
4272 #if HAVE_DECL_CURLOPT_RESUME_FROM_LARGE
4273 CAMLparam1(option);
4274 CURLcode result = CURLE_OK;
4276 result = curl_easy_setopt(conn->connection,
4277 CURLOPT_RESUME_FROM_LARGE,
4278 Int64_val(option));
4280 if (result != CURLE_OK)
4281 raiseError(conn, result);
4283 CAMLreturn0;
4284 #else
4285 #warning("libcurl does not implement CURLOPT_RESUME_FROM_LARGE")
4286 failwith("libcurl does not implement CURLOPT_RESUME_FROM_LARGE");
4287 #endif
4290 static void handleMaxFileSizeLarge(Connection *conn, value option)
4292 #if HAVE_DECL_CURLOPT_MAXFILESIZE_LARGE
4293 CAMLparam1(option);
4294 CURLcode result = CURLE_OK;
4296 result = curl_easy_setopt(conn->connection,
4297 CURLOPT_MAXFILESIZE_LARGE,
4298 Int64_val(option));
4300 if (result != CURLE_OK)
4301 raiseError(conn, result);
4303 CAMLreturn0;
4304 #else
4305 #warning "libcurl does not implement CURLOPT_MAXFILESIZE_LARGE"
4306 failwith("libcurl does not implement CURLOPT_MAXFILESIZE_LARGE");
4307 #endif
4310 static void handleNETRCFile(Connection *conn, value option)
4312 #if HAVE_DECL_CURLOPT_NETRC_FILE
4313 CAMLparam1(option);
4314 CURLcode result = CURLE_OK;
4316 Store_field(conn->ocamlValues, OcamlNETRCFile, option);
4318 if (conn->netrcFile != NULL)
4319 free(conn->netrcFile);
4321 conn->netrcFile = strdup(String_val(option));
4323 result = curl_easy_setopt(conn->connection,
4324 CURLOPT_NETRC_FILE,
4325 conn->netrcFile);
4327 if (result != CURLE_OK)
4328 raiseError(conn, result);
4330 CAMLreturn0;
4331 #else
4332 #warning "libcurl does not implement CURLOPT_NETRC_FILE"
4333 failwith("libcurl does not implement CURLOPT_NETRC_FILE");
4334 #endif
4337 static void handleFTPSSL(Connection *conn, value option)
4339 #if HAVE_DECL_CURLOPT_FTP_SSL
4340 CAMLparam1(option);
4341 CURLcode result = CURLE_OK;
4343 switch (Long_val(option))
4345 case 0: /* CURLFTPSSL_NONE */
4346 result = curl_easy_setopt(conn->connection,
4347 CURLOPT_FTP_SSL,
4348 CURLFTPSSL_NONE);
4349 break;
4351 case 1: /* CURLFTPSSL_TRY */
4352 result = curl_easy_setopt(conn->connection,
4353 CURLOPT_FTP_SSL,
4354 CURLFTPSSL_TRY);
4355 break;
4357 case 2: /* CURLFTPSSL_CONTROL */
4358 result = curl_easy_setopt(conn->connection,
4359 CURLOPT_FTP_SSL,
4360 CURLFTPSSL_CONTROL);
4361 break;
4363 case 3: /* CURLFTPSSL_ALL */
4364 result = curl_easy_setopt(conn->connection,
4365 CURLOPT_FTP_SSL,
4366 CURLFTPSSL_ALL);
4367 break;
4369 default:
4370 failwith("Invalid FTP_SSL Value");
4371 break;
4374 if (result != CURLE_OK)
4375 raiseError(conn, result);
4377 CAMLreturn0;
4378 #else
4379 #warning "libcurl does not implement CURLOPT_FTP_SSL"
4380 failwith("libcurl does not implement CURLOPT_FTP_SSL");
4381 #endif
4384 static void handlePostFieldSizeLarge(Connection *conn, value option)
4386 #if HAVE_DECL_CURLOPT_POSTFIELDSIZE_LARGE
4387 CAMLparam1(option);
4388 CURLcode result = CURLE_OK;
4390 result = curl_easy_setopt(conn->connection,
4391 CURLOPT_POSTFIELDSIZE_LARGE,
4392 Int64_val(option));
4394 if (result != CURLE_OK)
4395 raiseError(conn, result);
4397 CAMLreturn0;
4398 #else
4399 #warning "libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE"
4400 failwith("libcurl does not implement CURLOPT_POSTFIELDSIZE_LARGE");
4401 #endif
4404 static void handleTCPNoDelay(Connection *conn, value option)
4406 #if HAVE_DECL_CURLOPT_TCP_NODELAY
4407 CAMLparam1(option);
4408 CURLcode result = CURLE_OK;
4410 result = curl_easy_setopt(conn->connection,
4411 CURLOPT_TCP_NODELAY,
4412 Bool_val(option));
4414 if (result != CURLE_OK)
4415 raiseError(conn, result);
4417 CAMLreturn0;
4418 #else
4419 #warning "libcurl does not implement CURLOPT_TCP_NODELAY"
4420 failwith("libcurl does not implement CURLOPT_TCP_NODELAY");
4421 #endif
4424 static void handleFTPSSLAuth(Connection *conn, value option)
4426 #if HAVE_DECL_CURLOPT_FTPSSLAUTH
4427 CAMLparam1(option);
4428 CURLcode result = CURLE_OK;
4430 switch (Long_val(option))
4432 case 0: /* CURLFTPAUTH_DEFAULT */
4433 result = curl_easy_setopt(conn->connection,
4434 CURLOPT_FTPSSLAUTH,
4435 CURLFTPAUTH_DEFAULT);
4436 break;
4438 case 1: /* CURLFTPAUTH_SSL */
4439 result = curl_easy_setopt(conn->connection,
4440 CURLOPT_FTPSSLAUTH,
4441 CURLFTPAUTH_SSL);
4442 break;
4444 case 2: /* CURLFTPAUTH_TLS */
4445 result = curl_easy_setopt(conn->connection,
4446 CURLOPT_FTPSSLAUTH,
4447 CURLFTPAUTH_TLS);
4448 break;
4450 default:
4451 failwith("Invalid FTPSSLAUTH value");
4452 break;
4455 if (result != CURLE_OK)
4456 raiseError(conn, result);
4458 CAMLreturn0;
4459 #else
4460 #warning "libcurl does not implement CURLOPT_FTPSSLAUTH"
4461 failwith("libcurl does not implement CURLOPT_FTPSSLAUTH");
4462 #endif
4465 static void handleIOCTLFunction(Connection *conn, value option)
4467 #if HAVE_DECL_CURLOPT_IOCTLFUNCTION
4468 CAMLparam1(option);
4469 CURLcode result = CURLE_OK;
4471 if (Tag_val(option) == Closure_tag)
4472 Store_field(conn->ocamlValues, OcamlIOCTLCallback, option);
4473 else
4474 failwith("Not a proper closure");
4476 result = curl_easy_setopt(conn->connection,
4477 CURLOPT_IOCTLFUNCTION,
4478 ioctlFunction);
4479 if (result != CURLE_OK)
4480 raiseError(conn, result);
4482 result = curl_easy_setopt(conn->connection,
4483 CURLOPT_DEBUGDATA,
4484 conn);
4486 if (result != CURLE_OK)
4487 raiseError(conn, result);
4489 CAMLreturn0;
4490 #else
4491 #warning "libcurl does not implement CURLOPT_IOCTLFUNCTION"
4492 failwith("libcurl does not implement CURLOPT_IOCTLFUNCTION");
4493 #endif
4496 static void handleFTPAccount(Connection *conn, value option)
4498 #if HAVE_DECL_CURLOPT_FTP_ACCOUNT
4499 CAMLparam1(option);
4500 CURLcode result = CURLE_OK;
4502 Store_field(conn->ocamlValues, OcamlFTPAccount, option);
4504 if (conn->ftpaccount != NULL)
4505 free(conn->ftpaccount);
4507 conn->ftpaccount = strdup(String_val(option));
4509 result = curl_easy_setopt(conn->connection,
4510 CURLOPT_FTP_ACCOUNT,
4511 conn->ftpaccount);
4513 if (result != CURLE_OK)
4514 raiseError(conn, result);
4516 CAMLreturn0;
4517 #else
4518 #warning "libcurl does not implement CURLOPT_FTP_ACCOUNT"
4519 failwith("libcurl does not implement CURLOPT_FTP_ACCOUNT");
4520 #endif
4523 static void handleCookieList(Connection *conn, value option)
4525 #if HAVE_DECL_CURLOPT_COOKIELIST
4526 CAMLparam1(option);
4527 CURLcode result = CURLE_OK;
4529 Store_field(conn->ocamlValues, OcamlCookieList, option);
4531 if (conn->cookielist != NULL)
4532 free(conn->cookielist);
4534 conn->cookielist = strdup(String_val(option));
4536 result = curl_easy_setopt(conn->connection,
4537 CURLOPT_COOKIELIST,
4538 conn->cookielist);
4540 if (result != CURLE_OK)
4541 raiseError(conn, result);
4543 CAMLreturn0;
4544 #else
4545 #warning "libcurl does not implement CURLOPT_COOKIELIST"
4546 failwith("libcurl does not implement CURLOPT_COOKIELIST");
4547 #endif
4550 static void handleIgnoreContentLength(Connection *conn, value option)
4552 #if HAVE_DECL_CURLOPT_IGNORE_CONTENT_LENGTH
4553 CAMLparam1(option);
4554 CURLcode result = CURLE_OK;
4556 result = curl_easy_setopt(conn->connection,
4557 CURLOPT_IGNORE_CONTENT_LENGTH,
4558 Bool_val(option));
4560 if (result != CURLE_OK)
4561 raiseError(conn, result);
4563 CAMLreturn0;
4564 #else
4565 #warning "libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH"
4566 failwith("libcurl does not implement CURLOPT_IGNORE_CONTENT_LENGTH");
4567 #endif
4570 static void handleFTPSkipPASVIP(Connection *conn, value option)
4572 #if HAVE_DECL_CURLOPT_FTP_SKIP_PASV_IP
4573 CAMLparam1(option);
4574 CURLcode result = CURLE_OK;
4576 result = curl_easy_setopt(conn->connection,
4577 CURLOPT_FTP_SKIP_PASV_IP,
4578 Bool_val(option));
4580 if (result != CURLE_OK)
4581 raiseError(conn, result);
4583 CAMLreturn0;
4584 #else
4585 #warning "libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP"
4586 failwith("libcurl does not implement CURLOPT_FTP_SKIP_PASV_IP");
4587 #endif
4590 static void handleFTPFileMethod(Connection *conn, value option)
4592 #if HAVE_DECL_CURLOPT_FTP_FILEMETHOD
4593 CAMLparam1(option);
4594 CURLcode result = CURLE_OK;
4596 switch (Long_val(option))
4598 case 0: /* CURLFTPMETHOD_DEFAULT */
4599 result = curl_easy_setopt(conn->connection,
4600 CURLOPT_FTP_FILEMETHOD,
4601 CURLFTPMETHOD_DEFAULT);
4602 break;
4604 case 1: /* CURLFTMETHOD_MULTICWD */
4605 result = curl_easy_setopt(conn->connection,
4606 CURLOPT_FTP_FILEMETHOD,
4607 CURLFTPMETHOD_MULTICWD);
4608 break;
4610 case 2: /* CURLFTPMETHOD_NOCWD */
4611 result = curl_easy_setopt(conn->connection,
4612 CURLOPT_FTP_FILEMETHOD,
4613 CURLFTPMETHOD_NOCWD);
4614 break;
4616 case 3: /* CURLFTPMETHOD_SINGLECWD */
4617 result = curl_easy_setopt(conn->connection,
4618 CURLOPT_FTP_FILEMETHOD,
4619 CURLFTPMETHOD_SINGLECWD);
4621 default:
4622 failwith("Invalid FTP_FILEMETHOD value");
4623 break;
4626 if (result != CURLE_OK)
4627 raiseError(conn, result);
4629 CAMLreturn0;
4630 #else
4631 #warning "libcurl does not implement CURLOPT_FTP_FILEMETHOD"
4632 failwith("libcurl does not implement CURLOPT_FTP_FILEMETHOD");
4633 #endif
4636 static void handleLocalPort(Connection *conn, value option)
4638 #if HAVE_DECL_CURLOPT_LOCALPORT
4639 CAMLparam1(option);
4640 CURLcode result = CURLE_OK;
4642 result = curl_easy_setopt(conn->connection,
4643 CURLOPT_LOCALPORT,
4644 Long_val(option));
4646 if (result != CURLE_OK)
4647 raiseError(conn, result);
4649 CAMLreturn0;
4650 #else
4651 #warning "libcurl does not implement CURLOPT_LOCALPORT"
4652 failwith("libcurl does not implement CURLOPT_LOCALPORT");
4653 #endif
4656 static void handleLocalPortRange(Connection *conn, value option)
4658 #if HAVE_DECL_CURLOPT_LOCALPORTRANGE
4659 CAMLparam1(option);
4660 CURLcode result = CURLE_OK;
4662 result = curl_easy_setopt(conn->connection,
4663 CURLOPT_LOCALPORTRANGE,
4664 Long_val(option));
4666 if (result != CURLE_OK)
4667 raiseError(conn, result);
4669 CAMLreturn0;
4670 #else
4671 #warning "libcurl does not implement CURLOPT_LOCALPORTRANGE"
4672 failwith("libcurl does not implement CURLOPT_LOCALPORTRANGE");
4673 #endif
4676 static void handleConnectOnly(Connection *conn, value option)
4678 #if HAVE_DECL_CURLOPT_CONNECT_ONLY
4679 CAMLparam1(option);
4680 CURLcode result = CURLE_OK;
4682 result = curl_easy_setopt(conn->connection,
4683 CURLOPT_CONNECT_ONLY,
4684 Bool_val(option));
4686 if (result != CURLE_OK)
4687 raiseError(conn, result);
4689 CAMLreturn0;
4690 #else
4691 #warning "libcurl does not implement CURLOPT_CONNECT_ONLY"
4692 failwith("libcurl does not implement CURLOPT_CONNECT_ONLY");
4693 #endif
4696 static void handleMaxSendSpeedLarge(Connection *conn, value option)
4698 #if HAVE_DECL_CURLOPT_MAX_SEND_SPEED_LARGE
4699 CAMLparam1(option);
4700 CURLcode result = CURLE_OK;
4702 result = curl_easy_setopt(conn->connection,
4703 CURLOPT_MAX_SEND_SPEED_LARGE,
4704 Int64_val(option));
4706 if (result != CURLE_OK)
4707 raiseError(conn, result);
4709 CAMLreturn0;
4710 #else
4711 #warning "libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE"
4712 failwith("libcurl does not implement CURLOPT_MAX_SEND_SPEED_LARGE");
4713 #endif
4716 static void handleMaxRecvSpeedLarge(Connection *conn, value option)
4718 #if HAVE_DECL_CURLOPT_MAX_RECV_SPEED_LARGE
4719 CAMLparam1(option);
4720 CURLcode result = CURLE_OK;
4722 result = curl_easy_setopt(conn->connection,
4723 CURLOPT_MAX_RECV_SPEED_LARGE,
4724 Int64_val(option));
4726 if (result != CURLE_OK)
4727 raiseError(conn, result);
4729 CAMLreturn0;
4730 #else
4731 #warning "libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE"
4732 failwith("libcurl does not implement CURLOPT_MAX_RECV_SPEED_LARGE");
4733 #endif
4736 static void handleFTPAlternativeToUser(Connection *conn, value option)
4738 #if HAVE_DECL_CURLOPT_FTP_ALTERNATIVE_TO_USER
4739 CAMLparam1(option);
4740 CURLcode result = CURLE_OK;
4742 Store_field(conn->ocamlValues, OcamlFTPAlternativeToUser, option);
4744 if (conn->ftpAlternativeToUser != NULL)
4745 free(conn->ftpAlternativeToUser);
4747 conn->ftpAlternativeToUser = strdup(String_val(option));
4749 result = curl_easy_setopt(conn->connection,
4750 CURLOPT_FTP_ALTERNATIVE_TO_USER,
4751 conn->ftpAlternativeToUser);
4753 if (result != CURLE_OK)
4754 raiseError(conn, result);
4756 CAMLreturn0;
4757 #else
4758 #warning "libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER"
4759 failwith("libcurl does not implement CURLOPT_FTP_ALTERNATIVE_TO_USER");
4760 #endif
4763 static void handleSSLSessionIdCache(Connection *conn, value option)
4765 #if HAVE_DECL_CURLOPT_SSL_SESSIONID_CACHE
4766 CAMLparam1(option);
4767 CURLcode result = CURLE_OK;
4769 result = curl_easy_setopt(conn->connection,
4770 CURLOPT_SSL_SESSIONID_CACHE,
4771 Bool_val(option));
4773 if (result != CURLE_OK)
4774 raiseError(conn, result);
4776 CAMLreturn0;
4777 #else
4778 #warning "libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE"
4779 failwith("libcurl does not implement CURLOPT_SSL_SESSIONID_CACHE");
4780 #endif
4783 static void handleSSHAuthTypes(Connection *conn, value option)
4785 #if HAVE_DECL_CURLOPT_SSH_AUTH_TYPES
4786 CAMLparam1(option);
4787 CAMLlocal1(listIter);
4788 CURLcode result = CURLE_OK;
4789 long authTypes = CURLSSH_AUTH_NONE;
4791 listIter = option;
4793 while (!Is_long(listIter))
4795 switch (Long_val(Field(listIter, 0)))
4797 case 0: /* CURLSSH_AUTH_ANY */
4798 authTypes |= CURLSSH_AUTH_ANY;
4799 break;
4801 case 1: /* CURLSSH_AUTH_PUBLICKEY */
4802 authTypes |= CURLSSH_AUTH_PUBLICKEY;
4803 break;
4805 case 2: /* CURLSSH_AUTH_PASSWORD */
4806 authTypes |= CURLSSH_AUTH_PASSWORD;
4807 break;
4809 case 3: /* CURLSSH_AUTH_HOST */
4810 authTypes |= CURLSSH_AUTH_HOST;
4811 break;
4813 case 4: /* CURLSSH_AUTH_KEYBOARD */
4814 authTypes |= CURLSSH_AUTH_KEYBOARD;
4815 break;
4817 default:
4818 failwith("Invalid CURLSSH_AUTH_TYPES Value");
4819 break;
4822 listIter = Field(listIter, 1);
4825 result = curl_easy_setopt(conn->connection,
4826 CURLOPT_SSH_AUTH_TYPES,
4827 authTypes);
4829 if (result != CURLE_OK)
4830 raiseError(conn, result);
4832 CAMLreturn0;
4833 #else
4834 #warning "libcurl does not implement CURLOPT_SSH_AUTH_TYPES"
4835 failwith("libcurl does not implement CURLOPT_SSH_AUTH_TYPES");
4836 #endif
4839 static void handleSSHPublicKeyFile(Connection *conn, value option)
4841 #if HAVE_DECL_CURLOPT_SSH_PUBLIC_KEYFILE
4842 CAMLparam1(option);
4843 CURLcode result = CURLE_OK;
4845 Store_field(conn->ocamlValues, OcamlSSHPublicKeyFile, option);
4847 if (conn->sshPublicKeyFile != NULL)
4848 free(conn->sshPublicKeyFile);
4850 conn->sshPublicKeyFile = strdup(String_val(option));
4852 result = curl_easy_setopt(conn->connection,
4853 CURLOPT_SSH_PUBLIC_KEYFILE,
4854 conn->sshPublicKeyFile);
4856 if (result != CURLE_OK)
4857 raiseError(conn, result);
4859 CAMLreturn0;
4860 #else
4861 #warning "libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE"
4862 failwith("libcurl does not implement CURLOPT_SSH_PUBLIC_KEYFILE");
4863 #endif
4866 static void handleSSHPrivateKeyFile(Connection *conn, value option)
4868 #if HAVE_DECL_CURLOPT_SSH_PRIVATE_KEYFILE
4869 CAMLparam1(option);
4870 CURLcode result = CURLE_OK;
4872 Store_field(conn->ocamlValues, OcamlSSHPrivateKeyFile, option);
4874 if (conn->sshPrivateKeyFile != NULL)
4875 free(conn->sshPrivateKeyFile);
4877 conn->sshPrivateKeyFile = strdup(String_val(option));
4879 result = curl_easy_setopt(conn->connection,
4880 CURLOPT_SSH_PRIVATE_KEYFILE,
4881 conn->sshPrivateKeyFile);
4883 if (result != CURLE_OK)
4884 raiseError(conn, result);
4886 CAMLreturn0;
4887 #else
4888 #warning "libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE"
4889 failwith("libcurl does not implement CURLOPT_SSH_PRIVATE_KEYFILE");
4890 #endif
4893 static void handleFTPSSLCCC(Connection *conn, value option)
4895 #if HAVE_DECL_CURLOPT_FTP_SSL_CCC
4896 CAMLparam1(option);
4897 CURLcode result = CURLE_OK;
4899 switch (Long_val(option))
4901 case 0: /* CURLFTPSSL_CCC_NONE */
4902 result = curl_easy_setopt(conn->connection,
4903 CURLOPT_FTP_SSL_CCC,
4904 CURLFTPSSL_CCC_NONE);
4905 break;
4907 case 1: /* CURLFTPSSL_CCC_PASSIVE */
4908 result = curl_easy_setopt(conn->connection,
4909 CURLOPT_FTP_SSL_CCC,
4910 CURLFTPSSL_CCC_PASSIVE);
4911 break;
4913 case 2: /* CURLFTPSSL_CCC_ACTIVE */
4914 result = curl_easy_setopt(conn->connection,
4915 CURLOPT_FTP_SSL_CCC,
4916 CURLFTPSSL_CCC_ACTIVE);
4917 break;
4919 default:
4920 failwith("Invalid FTPSSL_CCC value");
4921 break;
4924 if (result != CURLE_OK)
4925 raiseError(conn, result);
4927 CAMLreturn0;
4928 #else
4929 #warning "libcurl does not implement CURLOPT_FTP_SSL_CCC"
4930 failwith("libcurl does not implement CURLOPT_FTP_SSL_CCC");
4931 #endif
4934 static void handleTimeoutMS(Connection *conn, value option)
4936 #if HAVE_DECL_CURLOPT_TIMEOUT_MS
4937 CAMLparam1(option);
4938 CURLcode result = CURLE_OK;
4940 result = curl_easy_setopt(conn->connection,
4941 CURLOPT_TIMEOUT_MS,
4942 Long_val(option));
4944 if (result != CURLE_OK)
4945 raiseError(conn, result);
4947 CAMLreturn0;
4948 #else
4949 #warning "libcurl does not implement CURLOPT_TIMEOUT_MS"
4950 failwith("libcurl does not implement CURLOPT_TIMEOUT_MS");
4951 #endif
4954 static void handleConnectTimeoutMS(Connection *conn, value option)
4956 #if HAVE_DECL_CURLOPT_CONNECTTIMEOUT_MS
4957 CAMLparam1(option);
4958 CURLcode result = CURLE_OK;
4960 result = curl_easy_setopt(conn->connection,
4961 CURLOPT_CONNECTTIMEOUT_MS,
4962 Long_val(option));
4964 if (result != CURLE_OK)
4965 raiseError(conn, result);
4967 CAMLreturn0;
4968 #else
4969 #warning "libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS"
4970 failwith("libcurl does not implement CURLOPT_CONNECTTIMEOUT_MS");
4971 #endif
4974 static void handleHTTPTransferDecoding(Connection *conn, value option)
4976 #if HAVE_DECL_CURLOPT_HTTP_TRANSFER_DECODING
4977 CAMLparam1(option);
4978 CURLcode result = CURLE_OK;
4980 result = curl_easy_setopt(conn->connection,
4981 CURLOPT_HTTP_TRANSFER_DECODING,
4982 Bool_val(option));
4984 if (result != CURLE_OK)
4985 raiseError(conn, result);
4987 CAMLreturn0;
4988 #else
4989 #warning "libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING"
4990 failwith("libcurl does not implement CURLOPT_HTTP_TRANSFER_DECODING");
4991 #endif
4994 static void handleHTTPContentDecoding(Connection *conn, value option)
4996 #if HAVE_DECL_CURLOPT_HTTP_CONTENT_DECODING
4997 CAMLparam1(option);
4998 CURLcode result = CURLE_OK;
5000 result = curl_easy_setopt(conn->connection,
5001 CURLOPT_HTTP_CONTENT_DECODING,
5002 Bool_val(option));
5004 if (result != CURLE_OK)
5005 raiseError(conn, result);
5007 CAMLreturn0;
5008 #else
5009 #warning "libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING"
5010 failwith("libcurl does not implement CURLOPT_HTTP_CONTENT_DECODING");
5011 #endif
5014 static void handleNewFilePerms(Connection *conn, value option)
5016 #if HAVE_DECL_CURLOPT_NEW_FILE_PERMS
5017 CAMLparam1(option);
5018 CURLcode result = CURLE_OK;
5020 result = curl_easy_setopt(conn->connection,
5021 CURLOPT_NEW_FILE_PERMS,
5022 Long_val(option));
5024 if (result != CURLE_OK)
5025 raiseError(conn, result);
5027 CAMLreturn0;
5028 #else
5029 #warning "libcurl does not implement CURLOPT_NEW_FILE_PERMS"
5030 failwith("libcurl does not implement CURLOPT_NEW_FILE_PERMS");
5031 #endif
5034 static void handleNewDirectoryPerms(Connection *conn, value option)
5036 #if HAVE_DECL_CURLOPT_NEW_DIRECTORY_PERMS
5037 CAMLparam1(option);
5038 CURLcode result = CURLE_OK;
5040 result = curl_easy_setopt(conn->connection,
5041 CURLOPT_NEW_DIRECTORY_PERMS,
5042 Long_val(option));
5044 if (result != CURLE_OK)
5045 raiseError(conn, result);
5047 CAMLreturn0;
5048 #else
5049 #warning "libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS"
5050 failwith("libcurl does not implement CURLOPT_NEW_DIRECTORY_PERMS");
5051 #endif
5054 static void handlePost301(Connection *conn, value option)
5056 #if HAVE_DECL_CURLOPT_POST301
5057 CAMLparam1(option);
5058 CURLcode result = CURLE_OK;
5060 result = curl_easy_setopt(conn->connection,
5061 CURLOPT_POST301,
5062 Bool_val(option));
5064 if (result != CURLE_OK)
5065 raiseError(conn, result);
5067 CAMLreturn0;
5068 #else
5069 #warning "libcurl does not implement CURLOPT_POST301"
5070 failwith("libcurl does not implement CURLOPT_POST301");
5071 #endif
5074 static void handleSSHHostPublicKeyMD5(Connection *conn, value option)
5076 #if HAVE_DECL_CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
5077 CAMLparam1(option);
5078 CURLcode result = CURLE_OK;
5080 Store_field(conn->ocamlValues, OcamlSSHHostPublicKeyMD5, option);
5082 if (conn->sshHostPublicKeyMD5 != NULL)
5083 free(conn->sshHostPublicKeyMD5);
5085 conn->sshHostPublicKeyMD5 = strdup(String_val(option));
5087 result = curl_easy_setopt(conn->connection,
5088 CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
5089 conn->sshHostPublicKeyMD5);
5091 if (result != CURLE_OK)
5092 raiseError(conn, result);
5094 CAMLreturn0;
5095 #else
5096 #warning "libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
5097 failwith("libcurl does not implement CURLOPT_SSH_HOST_PUBLIC_KEY_MD5");
5098 #endif
5101 static void handleCopyPostFields(Connection *conn, value option)
5103 #if HAVE_DECL_CURLOPT_COPYPOSTFIELDS
5104 CAMLparam1(option);
5105 CURLcode result = CURLE_OK;
5107 Store_field(conn->ocamlValues, OcamlCopyPostFields, option);
5109 if (conn->copyPostFields != NULL)
5110 free(conn->copyPostFields);
5112 conn->copyPostFields = strdup(String_val(option));
5114 result = curl_easy_setopt(conn->connection,
5115 CURLOPT_COPYPOSTFIELDS,
5116 conn->copyPostFields);
5118 if (result != CURLE_OK)
5119 raiseError(conn, result);
5121 CAMLreturn0;
5122 #else
5123 #warning "libcurl does not implement CURLOPT_COPYPOSTFIELDS"
5124 failwith("libcurl does not implement CURLOPT_COPYPOSTFIELDS");
5125 #endif
5128 static void handleProxyTransferMode(Connection *conn, value option)
5130 #if HAVE_DECL_CURLOPT_PROXY_TRANSFER_MODE
5131 CAMLparam1(option);
5132 CURLcode result = CURLE_OK;
5134 result = curl_easy_setopt(conn->connection,
5135 CURLOPT_PROXY_TRANSFER_MODE,
5136 Bool_val(option));
5138 if (result != CURLE_OK)
5139 raiseError(conn, result);
5141 CAMLreturn0;
5142 #else
5143 #warning "libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE"
5144 failwith("libcurl does not implement CURLOPT_PROXY_TRANSFER_MODE");
5145 #endif
5148 static void handleSeekFunction(Connection *conn, value option)
5150 #if HAVE_DECL_CURLOPT_SEEKFUNCTION
5151 CAMLparam1(option);
5152 CURLcode result = CURLE_OK;
5154 if (Tag_val(option) == Closure_tag)
5155 Store_field(conn->ocamlValues, OcamlSeekFunctionCallback, option);
5156 else
5157 failwith("Not a proper closure");
5159 result = curl_easy_setopt(conn->connection,
5160 CURLOPT_SEEKFUNCTION,
5161 seekFunction);
5163 if (result != CURLE_OK)
5164 raiseError(conn, result);
5166 result = curl_easy_setopt(conn->connection,
5167 CURLOPT_SEEKDATA,
5168 conn);
5170 if (result != CURLE_OK)
5171 raiseError(conn, result);
5173 CAMLreturn0;
5174 #else
5175 #warning "libcurl does not implement CURLOPT_SEEKFUNCTION"
5176 failwith("libcurl does not implement CURLOPT_SEEKFUNCTION");
5177 #endif
5181 ** curl_easy_setopt helper function
5184 CAMLprim value helper_curl_easy_setopt(value conn, value option)
5186 CAMLparam2(conn, option);
5187 CAMLlocal1(data);
5188 Connection *connection = Connection_val(conn);
5190 checkConnection(connection);
5192 if (Is_long(option))
5194 char error[128];
5196 sprintf(error, "Unimplemented Option: %s",
5197 findOption(unimplementedOptionMap,
5198 (CURLoption)(Long_val(option))));
5200 failwith(error);
5203 if (!Is_block(option))
5204 failwith("Not a block");
5206 if (Wosize_val(option) < 1)
5207 failwith("Insufficient data in block");
5209 data = Field(option, 0);
5211 if (Tag_val(option) < sizeof(implementedOptionMap)/sizeof(CURLOptionMapping))
5212 (*implementedOptionMap[Tag_val(option)].optionHandler)(connection,
5213 data);
5214 else
5215 failwith("Invalid CURLOPT Option");
5217 CAMLreturn(Val_unit);
5221 ** curl_easy_perform helper function
5224 CAMLprim value helper_curl_easy_perform(value conn)
5226 CAMLparam1(conn);
5227 CURLcode result = CURLE_OK;
5228 Connection *connection = Connection_val(conn);
5230 checkConnection(connection);
5232 enter_blocking_section();
5233 result = curl_easy_perform(connection->connection);
5234 leave_blocking_section();
5236 if (result != CURLE_OK)
5237 raiseError(connection, result);
5239 CAMLreturn(Val_unit);
5243 ** curl_easy_cleanup helper function
5246 CAMLprim value helper_curl_easy_cleanup(value conn)
5248 CAMLparam1(conn);
5249 Connection *connection = Connection_val(conn);
5251 checkConnection(connection);
5253 removeConnection(connection);
5255 CAMLreturn(Val_unit);
5259 ** curl_easy_duphandle helper function
5262 CAMLprim value helper_curl_easy_duphandle(value conn)
5264 CAMLparam1(conn);
5265 CAMLlocal1(result);
5266 Connection *connection = Connection_val(conn);
5268 checkConnection(connection);
5270 result = alloc(1, Abstract_tag);
5271 Store_field(result, 0, (value)duplicateConnection(connection));
5273 CAMLreturn(result);
5277 ** curl_easy_getinfo helper function
5280 enum GetInfoResultType {
5281 StringValue, LongValue, DoubleValue, StringListValue
5284 value convertStringList(struct curl_slist *slist)
5286 CAMLparam0();
5287 CAMLlocal3(result, current, next);
5288 struct curl_slist *p = slist;
5290 result = Val_int(0);
5291 current = Val_int(0);
5292 next = Val_int(0);
5294 while (p != NULL)
5296 next = alloc_tuple(2);
5297 Store_field(next, 0, copy_string(p->data));
5298 Store_field(next, 1, Val_int(0));
5300 if (result == Val_int(0))
5301 result = next;
5303 if (current != Val_int(0))
5304 Store_field(current, 1, next);
5306 current = next;
5308 p = p->next;
5311 curl_slist_free_all(slist);
5313 CAMLreturn(result);
5316 CAMLprim value helper_curl_easy_getinfo(value conn, value option)
5318 CAMLparam2(conn, option);
5319 CAMLlocal1(result);
5320 CURLcode curlResult;
5321 Connection *connection = Connection_val(conn);
5322 enum GetInfoResultType resultType;
5323 char *strValue = NULL;
5324 double doubleValue;
5325 long longValue;
5326 struct curl_slist *stringListValue = NULL;
5328 checkConnection(connection);
5330 switch(Long_val(option))
5332 #if HAVE_DECL_CURLINFO_EFFECTIVE_URL
5333 case 0: /* CURLINFO_EFFECTIVE_URL */
5334 resultType = StringValue;
5336 curlResult = curl_easy_getinfo(connection->connection,
5337 CURLINFO_EFFECTIVE_URL,
5338 &strValue);
5339 break;
5340 #else
5341 #warning "libcurl does not provide CURLINFO_EFFECTIVE_URL"
5342 #endif
5344 #if HAVE_DECL_CURLINFO_RESPONSE_CODE || HAVE_DECL_CURLINFO_HTTP_CODE
5345 case 1: /* CURLINFO_HTTP_CODE */
5346 case 2: /* CURLINFO_RESPONSE_CODE */
5347 #if HAVE_DECL_CURLINFO_RESPONSE_CODE
5348 resultType = LongValue;
5350 curlResult = curl_easy_getinfo(connection->connection,
5351 CURLINFO_RESPONSE_CODE,
5352 &longValue);
5353 #else
5354 resultType = LongValue;
5356 curlResult = curl_easy_getinfo(connection->connection,
5357 CURLINFO_HTTP_CODE,
5358 &longValue);
5359 #endif
5360 break;
5361 #endif
5363 #if HAVE_DECL_CURLINFO_TOTAL_TIME
5364 case 3: /* CURLINFO_TOTAL_TIME */
5365 resultType = DoubleValue;
5367 curlResult = curl_easy_getinfo(connection->connection,
5368 CURLINFO_TOTAL_TIME,
5369 &doubleValue);
5370 break;
5371 #endif
5373 #if HAVE_DECL_CURLINFO_NAMELOOKUP_TIME
5374 case 4: /* CURLINFO_NAMELOOKUP_TIME */
5375 resultType = DoubleValue;
5377 curlResult = curl_easy_getinfo(connection->connection,
5378 CURLINFO_NAMELOOKUP_TIME,
5379 &doubleValue);
5380 break;
5381 #endif
5383 #if HAVE_DECL_CURLINFO_CONNECT_TIME
5384 case 5: /* CURLINFO_CONNECT_TIME */
5385 resultType = DoubleValue;
5387 curlResult = curl_easy_getinfo(connection->connection,
5388 CURLINFO_CONNECT_TIME,
5389 &doubleValue);
5390 break;
5391 #endif
5393 #if HAVE_DECL_CURLINFO_PRETRANSFER_TIME
5394 case 6: /* CURLINFO_PRETRANSFER_TIME */
5395 resultType = DoubleValue;
5397 curlResult = curl_easy_getinfo(connection->connection,
5398 CURLINFO_PRETRANSFER_TIME,
5399 &doubleValue);
5400 break;
5401 #endif
5403 #if HAVE_DECL_CURLINFO_SIZE_UPLOAD
5404 case 7: /* CURLINFO_SIZE_UPLOAD */
5405 resultType = DoubleValue;
5407 curlResult = curl_easy_getinfo(connection->connection,
5408 CURLINFO_SIZE_UPLOAD,
5409 &doubleValue);
5410 break;
5411 #endif
5413 #if HAVE_DECL_CURLINFO_SIZE_DOWNLOAD
5414 case 8: /* CURLINFO_SIZE_DOWNLOAD */
5415 resultType = DoubleValue;
5417 curlResult = curl_easy_getinfo(connection->connection,
5418 CURLINFO_SIZE_DOWNLOAD,
5419 &doubleValue);
5420 break;
5421 #endif
5423 #if HAVE_DECL_CURLINFO_SPEED_DOWNLOAD
5424 case 9: /* CURLINFO_SPEED_DOWNLOAD */
5425 resultType = DoubleValue;
5427 curlResult = curl_easy_getinfo(connection->connection,
5428 CURLINFO_SPEED_DOWNLOAD,
5429 &doubleValue);
5430 break;
5431 #endif
5433 #if HAVE_DECL_CURLINFO_SPEED_UPLOAD
5434 case 10: /* CURLINFO_SPEED_UPLOAD */
5435 resultType = DoubleValue;
5437 curlResult = curl_easy_getinfo(connection->connection,
5438 CURLINFO_SPEED_UPLOAD,
5439 &doubleValue);
5440 break;
5442 #endif
5444 #if HAVE_DECL_CURLINFO_HEADER_SIZE
5445 case 11: /* CURLINFO_HEADER_SIZE */
5446 resultType = LongValue;
5448 curlResult = curl_easy_getinfo(connection->connection,
5449 CURLINFO_HEADER_SIZE,
5450 &longValue);
5451 break;
5452 #endif
5454 #if HAVE_DECL_CURLINFO_REQUEST_SIZE
5455 case 12: /* CURLINFO_REQUEST_SIZE */
5456 resultType = LongValue;
5458 curlResult = curl_easy_getinfo(connection->connection,
5459 CURLINFO_REQUEST_SIZE,
5460 &longValue);
5461 break;
5462 #endif
5464 #if HAVE_DECL_CURLINFO_SSL_VERIFYRESULT
5465 case 13: /* CURLINFO_SSL_VERIFYRESULT */
5466 resultType = LongValue;
5468 curlResult = curl_easy_getinfo(connection->connection,
5469 CURLINFO_SSL_VERIFYRESULT,
5470 &longValue);
5471 break;
5472 #endif
5474 #if HAVE_DECL_CURLINFO_FILETIME
5475 case 14: /* CURLINFO_FILETIME */
5476 resultType = DoubleValue;
5478 curlResult = curl_easy_getinfo(connection->connection,
5479 CURLINFO_FILETIME,
5480 &doubleValue);
5481 break;
5482 #endif
5484 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_DOWNLOAD
5485 case 15: /* CURLINFO_CONTENT_LENGTH_DOWNLOAD */
5486 resultType = DoubleValue;
5488 curlResult = curl_easy_getinfo(connection->connection,
5489 CURLINFO_CONTENT_LENGTH_DOWNLOAD,
5490 &doubleValue);
5491 break;
5492 #endif
5494 #if HAVE_DECL_CURLINFO_CONTENT_LENGTH_UPLOAD
5495 case 16: /* CURLINFO_CONTENT_LENGTH_UPLOAD */
5496 resultType = DoubleValue;
5498 curlResult = curl_easy_getinfo(connection->connection,
5499 CURLINFO_CONTENT_LENGTH_UPLOAD,
5500 &doubleValue);
5501 break;
5502 #endif
5504 #if HAVE_DECL_CURLINFO_STARTTRANSFER_TIME
5505 case 17: /* CURLINFO_STARTTRANSFER_TIME */
5506 resultType = DoubleValue;
5508 curlResult = curl_easy_getinfo(connection->connection,
5509 CURLINFO_STARTTRANSFER_TIME,
5510 &doubleValue);
5511 break;
5512 #endif
5514 #if HAVE_DECL_CURLINFO_CONTENT_TYPE
5515 case 18: /* CURLINFO_CONTENT_TYPE */
5516 resultType = StringValue;
5518 curlResult = curl_easy_getinfo(connection->connection,
5519 CURLINFO_CONTENT_TYPE,
5520 &strValue);
5521 break;
5522 #endif
5524 #if HAVE_DECL_CURLINFO_REDIRECT_TIME
5525 case 19: /* CURLINFO_REDIRECT_TIME */
5526 resultType = DoubleValue;
5528 curlResult = curl_easy_getinfo(connection->connection,
5529 CURLINFO_REDIRECT_TIME,
5530 &doubleValue);
5531 break;
5532 #endif
5534 #if HAVE_DECL_CURLINFO_REDIRECT_COUNT
5535 case 20: /* CURLINFO_REDIRECT_COUNT */
5536 resultType = LongValue;
5538 curlResult = curl_easy_getinfo(connection->connection,
5539 CURLINFO_REDIRECT_COUNT,
5540 &longValue);
5541 break;
5542 #endif
5544 #if HAVE_DECL_CURLINFO_PRIVATE
5545 case 21: /* CURLINFO_PRIVATE */
5546 resultType = StringValue;
5548 curlResult = curl_easy_getinfo(connection->connection,
5549 CURLINFO_PRIVATE,
5550 &strValue);
5551 break;
5552 #endif
5554 #if HAVE_DECL_CURLINFO_HTTP_CONNECT_CODE
5555 case 22: /* CURLINFO_HTTP_CONNECT_CODE */
5556 resultType = LongValue;
5558 curlResult = curl_easy_getinfo(connection->connection,
5559 CURLINFO_HTTP_CONNECT_CODE,
5560 &longValue);
5561 break;
5562 #endif
5564 #if HAVE_DECL_CURLINFO_HTTPAUTH_AVAIL
5565 case 23: /* CURLINFO_HTTPAUTH_AVAIL */
5566 resultType = LongValue;
5568 curlResult = curl_easy_getinfo(connection->connection,
5569 CURLINFO_HTTPAUTH_AVAIL,
5570 &longValue);
5571 break;
5572 #endif
5574 #if HAVE_DECL_CURLINFO_PROXYAUTH_AVAIL
5575 case 24: /* CURLINFO_PROXYAUTH_AVAIL */
5576 resultType = LongValue;
5578 curlResult = curl_easy_getinfo(connection->connection,
5579 CURLINFO_PROXYAUTH_AVAIL,
5580 &longValue);
5581 break;
5582 #endif
5584 #if HAVE_DECL_CURLINFO_OS_ERRNO
5585 case 25: /* CURLINFO_OS_ERRNO */
5586 resultType = LongValue;
5588 curlResult = curl_easy_getinfo(connection->connection,
5589 CURLINFO_OS_ERRNO,
5590 &longValue);
5591 break;
5592 #endif
5594 #if HAVE_DECL_CURLINFO_NUM_CONNECTS
5595 case 26: /* CURLINFO_NUM_CONNECTS */
5596 resultType = LongValue;
5598 curlResult = curl_easy_getinfo(connection->connection,
5599 CURLINFO_NUM_CONNECTS,
5600 &longValue);
5601 break;
5602 #endif
5604 #if HAVE_DECL_CURLINFO_SSL_ENGINES
5605 case 27: /* CURLINFO_SSL_ENGINES */
5606 resultType = StringListValue;
5608 curlResult = curl_easy_getinfo(connection->connection,
5609 CURLINFO_SSL_ENGINES,
5610 &stringListValue);
5611 break;
5612 #endif
5614 #if HAVE_DECL_CURLINFO_COOKIELIST
5615 case 28: /* CURLINFO_COOKIELIST */
5616 resultType = StringListValue;
5618 curlResult = curl_easy_getinfo(connection->connection,
5619 CURLINFO_COOKIELIST,
5620 &stringListValue);
5621 break;
5622 #endif
5624 #if HAVE_DECL_CURLINFO_LASTSOCKET
5625 case 29: /* CURLINFO_LASTSOCKET */
5626 resultType = LongValue;
5628 curlResult = curl_easy_getinfo(connection->connection,
5629 CURLINFO_LASTSOCKET,
5630 &longValue);
5631 break;
5632 #endif
5634 default:
5635 failwith("Invalid CURLINFO Option");
5636 break;
5639 if (curlResult != CURLE_OK)
5640 raiseError(connection, curlResult);
5642 switch (resultType)
5644 case StringValue:
5645 result = alloc(1, StringValue);
5647 libcurl can return NULL, e.g. for CONTENT_TYPE or PRIVATE
5648 alternative: add StringOptionValue and break API..
5650 Store_field(result, 0, copy_string(strValue?strValue:""));
5651 break;
5653 case LongValue:
5654 result = alloc(1, LongValue);
5655 Store_field(result, 0, Val_long(longValue));
5656 break;
5658 case DoubleValue:
5659 result = alloc(1, DoubleValue);
5660 Store_field(result, 0, copy_double(doubleValue));
5661 break;
5663 case StringListValue:
5664 result = alloc(1, StringListValue);
5665 Store_field(result, 0, convertStringList(stringListValue));
5666 break;
5669 CAMLreturn(result);
5673 ** curl_escape helper function
5676 CAMLprim value helper_curl_escape(value str)
5678 CAMLparam1(str);
5679 CAMLlocal1(result);
5680 char *curlResult;
5682 curlResult = curl_escape(String_val(str), string_length(str));
5683 result = copy_string(curlResult);
5684 free(curlResult);
5686 CAMLreturn(result);
5690 ** curl_unescape helper function
5693 CAMLprim value helper_curl_unescape(value str)
5695 CAMLparam1(str);
5696 CAMLlocal1(result);
5697 char *curlResult;
5699 curlResult = curl_unescape(String_val(str), string_length(str));
5700 result = copy_string(curlResult);
5701 free(curlResult);
5703 CAMLreturn(result);
5707 ** curl_getdate helper function
5710 CAMLprim value helper_curl_getdate(value str, value now)
5712 CAMLparam2(str, now);
5713 CAMLlocal1(result);
5714 time_t curlResult;
5715 time_t curlNow;
5717 curlNow = (time_t)Double_val(now);
5718 curlResult = curl_getdate(String_val(str), &curlNow);
5719 result = copy_double((double)curlResult);
5721 CAMLreturn(result);
5725 ** curl_version helper function
5728 CAMLprim value helper_curl_version(void)
5730 CAMLparam0();
5731 CAMLlocal1(result);
5732 char *str;
5734 str = curl_version();
5735 result = copy_string(str);
5737 CAMLreturn(result);
5741 * Curl multi stack support
5743 * Exported thin wrappers for libcurl are prefixed with caml_curl_multi_.
5744 * Other exported functions are prefixed with caml_curlm_, some of them
5745 * can/should be decomposed into smaller parts.
5748 #define CURLM_val(v) ((CURLM*)v)
5749 #define Val_CURLM(h) ((value)h)
5751 CAMLprim value caml_curl_multi_init(value unit)
5753 CAMLparam1(unit);
5754 CURLM* h;
5756 h = curl_multi_init();
5758 if (!h)
5759 failwith("caml_curl_multi_init");
5761 CAMLreturn(Val_CURLM(h));
5764 CAMLprim value caml_curl_multi_cleanup(value handle)
5766 CAMLparam1(handle);
5768 if (CURLM_OK != curl_multi_cleanup(CURLM_val(handle)))
5769 failwith("caml_curl_multi_cleanup");
5771 CAMLreturn(Val_unit);
5774 static CURL* curlm_remove_finished(CURLM* multi_handle)
5776 int msgs_in_queue = 0;
5778 while (1)
5780 CURLMsg* msg = curl_multi_info_read(multi_handle, &msgs_in_queue);
5781 if (NULL == msg) return NULL;
5782 if (CURLMSG_DONE == msg->msg)
5784 CURL* easy_handle = msg->easy_handle;
5785 if (CURLM_OK != curl_multi_remove_handle(multi_handle, easy_handle))
5787 //failwith("curlm_remove_finished");
5789 return easy_handle;
5794 CAMLprim value caml_curlm_remove_finished(value v_multi)
5796 CAMLparam1(v_multi);
5797 CAMLlocal1(v_easy);
5798 CURL* handle;
5799 CURLM* multi_handle;
5801 multi_handle = CURLM_val(v_multi);
5803 caml_enter_blocking_section();
5804 handle = curlm_remove_finished(multi_handle);
5805 caml_leave_blocking_section();
5807 if (NULL == handle)
5809 CAMLreturn(Val_none);
5811 else
5813 /* not good */
5814 v_easy = alloc(1, Abstract_tag);
5815 Store_field(v_easy, 0, (value)findConnection(handle));
5816 CAMLreturn(Val_some(v_easy));
5820 static int curlm_wait_data(CURLM* multi_handle)
5822 struct timeval timeout;
5823 CURLMcode ret;
5825 fd_set fdread;
5826 fd_set fdwrite;
5827 fd_set fdexcep;
5828 int maxfd;
5830 FD_ZERO(&fdread);
5831 FD_ZERO(&fdwrite);
5832 FD_ZERO(&fdexcep);
5834 /* set a suitable timeout */
5835 timeout.tv_sec = 1;
5836 timeout.tv_usec = 0;
5838 /* get file descriptors from the transfers */
5839 ret = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
5841 if (ret == CURLM_OK && maxfd >= 0)
5843 int rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
5844 if (-1 != rc) return 0;
5845 //printf("select error\n");
5847 else
5849 //printf("curl_multi_fdset error\n");
5851 return 1;
5854 CAMLprim value caml_curlm_wait_data(value v_multi)
5856 CAMLparam1(v_multi);
5857 int ret;
5858 CURLM* h;
5860 h = CURLM_val(v_multi);
5862 caml_enter_blocking_section();
5863 ret = curlm_wait_data(h);
5864 caml_leave_blocking_section();
5866 CAMLreturn(Val_bool(0 == ret));
5869 CAMLprim value caml_curl_multi_add_handle(value v_multi, value v_easy)
5871 CAMLparam2(v_multi,v_easy);
5873 if (CURLM_OK != curl_multi_add_handle(CURLM_val(v_multi), Connection_val(v_easy)->connection))
5874 failwith("caml_curl_multi_add_handle");
5876 CAMLreturn(Val_unit);
5879 CAMLprim value caml_curl_multi_perform_all(value v_multi)
5881 CAMLparam1(v_multi);
5882 CURLM* h;
5883 int still_running = 0;
5885 h = CURLM_val(v_multi);
5887 caml_enter_blocking_section();
5888 while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(h, &still_running));
5889 caml_leave_blocking_section();
5891 CAMLreturn(Val_int(still_running));