This is an automated email from the git hooks/post-receive script. mehdi pushed a commit to branch master in repository ocurl.
commit 85c2a6c1d694e143ccd001f5e4a8dd1b9f0b5373 Author: Mehdi Dogguy <me...@debian.org> Date: Fri Aug 11 14:54:35 2017 -0400 New upstream version 0.7.7 --- .gitignore | 4 +- CHANGES.txt | 4 + Makefile.in | 13 ++- config.h.in | 16 ++++ configure | 109 +++++++++++++++++++++-- configure.in | 13 ++- curl-helper.c | 232 ++++++++++++++++++++++++++++++++++++------------ curl.ml | 9 ++ curl.mli | 11 +++ curl_lwt.ml | 4 + curl_lwt.mli | 5 ++ errors.ml | 116 ++++++++++++++++++++++++ examples/Makefile.in | 4 + examples/test_cb_exn.ml | 3 +- 14 files changed, 472 insertions(+), 71 deletions(-) diff --git a/.gitignore b/.gitignore index 05775dd..15f91ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -*.cm[aiox] +*.cm[aioxt] *.cmxa +*.cmti *.o *.obj *.a @@ -16,6 +17,7 @@ examples/opar examples/ossl examples/oput examples/ominimal +examples/omulti examples/ocurl examples/ocurl_test_threads examples/test_cb_exn diff --git a/CHANGES.txt b/CHANGES.txt index ebb2e0c..fc94b55 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,7 @@ +0.7.7 - 16 May 2016 + + + Multi.setopt + 0.7.6 - 25 Oct 2015 * fix invalid memory access in CURLOPT_HTTPPOST handling (mfp) diff --git a/Makefile.in b/Makefile.in index 3f93a2f..8990bdf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -21,6 +21,9 @@ EXT_OBJ = @EXT_OBJ@ EXT_DLL = @EXT_DLL@ FLAGS = -g +ifeq (@OCAML_HAS_BIN_ANNOT@,yes) +FLAGS += -bin-annot +endif LIBS = CFLAGS = @CFLAGS@ @DEFS@ -Wall @@ -43,13 +46,19 @@ endif endif INSTALL_TARGETS = curl$(EXT_LIB) curl.cmi curl.mli $(TARGETS) +ifeq (@OCAML_HAS_BIN_ANNOT@,yes) +INSTALL_TARGETS += curl.cmt curl.cmti +endif ifneq (@OCAML_PKG_lwt@,no) INSTALL_TARGETS += curl_lwt.cmi curl_lwt.mli curl_lwt$(EXT_OBJ) +ifeq (@OCAML_HAS_BIN_ANNOT@,yes) +INSTALL_TARGETS += curl_lwt.cmt curl_lwt.cmti +endif endif all: @$(MAKE) depend - @$(MAKE) targets + @$(MAKE) $(TARGETS) build: all @@ -75,8 +84,6 @@ else ocamldoc -html -d doc curl.mli endif -targets: $(TARGETS) examples - examples: (cd examples; $(MAKE)) diff --git a/config.h.in b/config.h.in index cf037af..17f63cb 100644 --- a/config.h.in +++ b/config.h.in @@ -463,6 +463,22 @@ if you don't. */ #undef HAVE_DECL_CURLINFO_TOTAL_TIME +/* Define to 1 if you have the declaration of `CURLMOPT_MAXCONNECTS', and to 0 + if you don't. */ +#undef HAVE_DECL_CURLMOPT_MAXCONNECTS + +/* Define to 1 if you have the declaration of `CURLMOPT_MAX_HOST_CONNECTIONS', + and to 0 if you don't. */ +#undef HAVE_DECL_CURLMOPT_MAX_HOST_CONNECTIONS + +/* Define to 1 if you have the declaration of `CURLMOPT_MAX_PIPELINE_LENGTH', + and to 0 if you don't. */ +#undef HAVE_DECL_CURLMOPT_MAX_PIPELINE_LENGTH + +/* Define to 1 if you have the declaration of `CURLMOPT_PIPELINING', and to 0 + if you don't. */ +#undef HAVE_DECL_CURLMOPT_PIPELINING + /* Define to 1 if you have the declaration of `CURLMOPT_SOCKETDATA', and to 0 if you don't. */ #undef HAVE_DECL_CURLMOPT_SOCKETDATA diff --git a/configure b/configure index 8bc0dc6..c42b144 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for ocurl 0.7.6. +# Generated by GNU Autoconf 2.69 for ocurl 0.7.7. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ocurl' PACKAGE_TARNAME='ocurl' -PACKAGE_VERSION='0.7.6' -PACKAGE_STRING='ocurl 0.7.6' +PACKAGE_VERSION='0.7.7' +PACKAGE_STRING='ocurl 0.7.7' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -626,9 +626,11 @@ CPP EXT_OBJ EXT_LIB EXT_DLL +OCAML_HAS_BIN_ANNOT INSTALLDIR CURLLIBS ac_prefix_program +OCAML_PKG_camlp4 OCAML_PKG_lwt OCAMLFIND OCAMLBUILD @@ -1245,7 +1247,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures ocurl 0.7.6 to adapt to many kinds of systems. +\`configure' configures ocurl 0.7.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1306,7 +1308,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ocurl 0.7.6:";; + short | recursive ) echo "Configuration of ocurl 0.7.7:";; esac cat <<\_ACEOF @@ -1386,7 +1388,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ocurl configure 0.7.6 +ocurl configure 0.7.7 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1684,7 +1686,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by ocurl $as_me 0.7.6, which was +It was created by ocurl $as_me 0.7.7, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4087,6 +4089,30 @@ $as_echo "not found" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OCaml findlib package camlp4" >&5 +$as_echo_n "checking for OCaml findlib package camlp4... " >&6; } + + unset found + unset pkg + found=no + for pkg in camlp4 ; do + if $OCAMLFIND query $pkg >/dev/null 2>/dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + OCAML_PKG_camlp4=$pkg + found=yes + break + fi + done + if test "$found" = "no" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + OCAML_PKG_camlp4=no + fi + + + + INSTALLDIR=$OCAMLLIB/curl if test "x$prefix" = xNONE; then @@ -4188,12 +4214,25 @@ fi + if test "$OCAMLFIND" == "no"; then : $OCAMLC -I +compiler-libs ocamlcommon.cma print_ext.ml -o print_ext else $OCAMLFIND c -linkpkg -package compiler-libs.common print_ext.ml -o print_ext fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bin-annot support" >&5 +$as_echo_n "checking for bin-annot support... " >&6; } +if test "$OCAMLVERSION" \> "4"; then : + OCAML_HAS_BIN_ANNOT=yes +else + OCAML_HAS_BIN_ANNOT=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAML_HAS_BIN_ANNOT" >&5 +$as_echo "$OCAML_HAS_BIN_ANNOT" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ext_dll" >&5 $as_echo_n "checking for ext_dll... " >&6; } EXT_DLL=`./print_ext dll || $OCAMLC -config | fgrep ext_dll | sed -e "s/.*: //"` @@ -8114,6 +8153,58 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CURLE_AGAIN $ac_have_decl _ACEOF +ac_fn_c_check_decl "$LINENO" "CURLMOPT_MAXCONNECTS" "ac_cv_have_decl_CURLMOPT_MAXCONNECTS" " +#include \"curl/curl.h\" + +" +if test "x$ac_cv_have_decl_CURLMOPT_MAXCONNECTS" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CURLMOPT_MAXCONNECTS $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "CURLMOPT_PIPELINING" "ac_cv_have_decl_CURLMOPT_PIPELINING" " +#include \"curl/curl.h\" + +" +if test "x$ac_cv_have_decl_CURLMOPT_PIPELINING" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CURLMOPT_PIPELINING $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "CURLMOPT_MAX_PIPELINE_LENGTH" "ac_cv_have_decl_CURLMOPT_MAX_PIPELINE_LENGTH" " +#include \"curl/curl.h\" + +" +if test "x$ac_cv_have_decl_CURLMOPT_MAX_PIPELINE_LENGTH" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CURLMOPT_MAX_PIPELINE_LENGTH $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "CURLMOPT_MAX_HOST_CONNECTIONS" "ac_cv_have_decl_CURLMOPT_MAX_HOST_CONNECTIONS" " +#include \"curl/curl.h\" + +" +if test "x$ac_cv_have_decl_CURLMOPT_MAX_HOST_CONNECTIONS" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CURLMOPT_MAX_HOST_CONNECTIONS $ac_have_decl +_ACEOF ac_fn_c_check_decl "$LINENO" "CURL_VERSION_TLSAUTH_SRP" "ac_cv_have_decl_CURL_VERSION_TLSAUTH_SRP" " #include \"curl/curl.h\" @@ -8653,7 +8744,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by ocurl $as_me 0.7.6, which was +This file was extended by ocurl $as_me 0.7.7, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8715,7 +8806,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -ocurl config.status 0.7.6 +ocurl config.status 0.7.7 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.in b/configure.in index 57cc4dd..4a5d873 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ dnl dnl ocurl autoconf input dnl -AC_INIT(ocurl,0.7.6) +AC_INIT(ocurl,0.7.7) AC_PROG_CC() @@ -21,6 +21,7 @@ AC_PROG_OCAML() AC_PROG_FINDLIB() AC_CHECK_OCAML_PKG([lwt]) +AC_CHECK_OCAML_PKG([camlp4]) INSTALLDIR=$OCAMLLIB/curl @@ -31,11 +32,18 @@ AC_SUBST(OCAMLLIB) AC_SUBST(INSTALLDIR) AC_SUBST(OCAMLFIND) AC_SUBST(OCAML_PKG_lwt) +AC_SUBST(OCAML_PKG_camlp4) AS_IF([test "$OCAMLFIND" == "no"], [$OCAMLC -I +compiler-libs ocamlcommon.cma print_ext.ml -o print_ext], [$OCAMLFIND c -linkpkg -package compiler-libs.common print_ext.ml -o print_ext]) +AC_MSG_CHECKING([for bin-annot support]) +AS_IF([test "$OCAMLVERSION" \> "4"],[OCAML_HAS_BIN_ANNOT=yes],[OCAML_HAS_BIN_ANNOT=no]) +AC_MSG_RESULT([$OCAML_HAS_BIN_ANNOT]) + +AC_SUBST(OCAML_HAS_BIN_ANNOT) + AC_MSG_CHECKING([for ext_dll]) EXT_DLL=`./print_ext dll || $OCAMLC -config | fgrep ext_dll | sed -e "s/.*: //"` AS_IF([ test "$?" -eq 0 ],,[AC_MSG_ERROR([failed])] ) @@ -160,6 +168,9 @@ CURLE_REMOTE_FILE_EXISTS, CURLE_TFTP_NOSUCHUSER, CURLE_CONV_FAILED, CURLE_CONV_REQD, CURLE_SSL_CACERT_BADFILE, CURLE_REMOTE_FILE_NOT_FOUND, CURLE_SSH, CURLE_SSL_SHUTDOWN_FAILED, CURLE_AGAIN, +CURLMOPT_MAXCONNECTS, CURLMOPT_PIPELINING, CURLMOPT_MAX_PIPELINE_LENGTH, +CURLMOPT_MAX_HOST_CONNECTIONS, + CURL_VERSION_TLSAUTH_SRP, CURL_VERSION_NTLM_WB], [], [], [ diff --git a/curl-helper.c b/curl-helper.c index e515b4d..c909e76 100644 --- a/curl-helper.c +++ b/curl-helper.c @@ -203,6 +203,7 @@ struct CURLErrorMapping CURLErrorMapping errorMap[] = { + {"CURLE_OK", CURLE_OK}, #if HAVE_DECL_CURLE_UNSUPPORTED_PROTOCOL {"CURLE_UNSUPPORTED_PROTOCOL", CURLE_UNSUPPORTED_PROTOCOL}, #else @@ -308,10 +309,10 @@ CURLErrorMapping errorMap[] = #else {"CURLE_FTP_QUOTE_ERROR", -1}, #endif -#if HAVE_DECL_CURLE_HTTP_NOT_FOUND - {"CURLE_HTTP_NOT_FOUND", CURLE_HTTP_NOT_FOUND}, +#if HAVE_DECL_CURLE_HTTP_RETURNED_ERROR + {"CURLE_HTTP_RETURNED_ERROR", CURLE_HTTP_RETURNED_ERROR}, #else - {"CURLE_HTTP_NOT_FOUND", -1}, + {"CURLE_HTTP_RETURNED_ERROR", -1}, #endif #if HAVE_DECL_CURLE_WRITE_ERROR {"CURLE_WRITE_ERROR", CURLE_WRITE_ERROR}, @@ -378,10 +379,10 @@ CURLErrorMapping errorMap[] = #else {"CURLE_SSL_CONNECT_ERROR", -1}, #endif -#if HAVE_DECL_CURLE_FTP_BAD_DOWNLOAD_RESUME - {"CURLE_FTP_BAD_DOWNLOAD_RESUME", CURLE_FTP_BAD_DOWNLOAD_RESUME}, +#if HAVE_DECL_CURLE_BAD_DOWNLOAD_RESUME + {"CURLE_BAD_DOWNLOAD_RESUME", CURLE_BAD_DOWNLOAD_RESUME}, #else - {"CURLE_FTP_BAD_DOWNLOAD_RESUME", -1}, + {"CURLE_BAD_DOWNLOAD_RESUME", -1}, #endif #if HAVE_DECL_CURLE_FILE_COULDNT_READ_FILE {"CURLE_FILE_COULDNT_READ_FILE", CURLE_FILE_COULDNT_READ_FILE}, @@ -423,10 +424,10 @@ CURLErrorMapping errorMap[] = #else {"CURLE_BAD_CALLING_ORDER", -1}, #endif -#if HAVE_DECL_CURLE_HTTP_PORT_FAILED - {"CURLE_HTTP_PORT_FAILED", CURLE_HTTP_PORT_FAILED}, +#if HAVE_DECL_CURLE_INTERFACE_FAILED + {"CURLE_INTERFACE_FAILED", CURLE_INTERFACE_FAILED}, #else - {"CURLE_HTTP_PORT_FAILED", -1}, + {"CURLE_INTERFACE_FAILED", -1}, #endif #if HAVE_DECL_CURLE_BAD_PASSWORD_ENTERED {"CURLE_BAD_PASSWORD_ENTERED", CURLE_BAD_PASSWORD_ENTERED}, @@ -458,15 +459,15 @@ CURLErrorMapping errorMap[] = #else {"CURLE_GOT_NOTHING", -1}, #endif -#if HAVE_DECL_CURLE_SSL_ENGINE_NOT_FOUND - {"CURLE_SSL_ENGINE_NOT_FOUND", CURLE_SSL_ENGINE_NOTFOUND}, +#if HAVE_DECL_CURLE_SSL_ENGINE_NOTFOUND + {"CURLE_SSL_ENGINE_NOTFOUND", CURLE_SSL_ENGINE_NOTFOUND}, #else - {"CURLE_SSL_ENGINE_NOT_FOUND", -1}, + {"CURLE_SSL_ENGINE_NOTFOUND", -1}, #endif -#if HAVE_DECL_CURLE_SSL_ENGINE_SET_FAILED - {"CURLE_SSL_ENGINE_SET_FAILED", CURLE_SSL_ENGINE_SETFAILED}, +#if HAVE_DECL_CURLE_SSL_ENGINE_SETFAILED + {"CURLE_SSL_ENGINE_SETFAILED", CURLE_SSL_ENGINE_SETFAILED}, #else - {"CURLE_SSL_ENGINE_SET_FAILED", -1}, + {"CURLE_SSL_ENGINE_SETFAILED", -1}, #endif #if HAVE_DECL_CURLE_SEND_ERROR {"CURLE_SEND_ERROR", CURLE_SEND_ERROR}, @@ -484,9 +485,9 @@ CURLErrorMapping errorMap[] = {"CURLE_SHARE_IN_USE", -1}, #endif #if HAVE_DECL_CURLE_SSL_CERTPROBLEM - {"CURLE_SSL_CERTPROBLEN", CURLE_SSL_CERTPROBLEM}, + {"CURLE_SSL_CERTPROBLEM", CURLE_SSL_CERTPROBLEM}, #else - {"CURLE_SSL_CERTPROBLEN", -1}, + {"CURLE_SSL_CERTPROBLEM", -1}, #endif #if HAVE_DECL_CURLE_SSL_CIPHER {"CURLE_SSL_CIPHER", CURLE_SSL_CIPHER}, @@ -573,10 +574,10 @@ CURLErrorMapping errorMap[] = #else {"CURLE_CONV_FAILED", -1}, #endif -#if HAVE_DECL_CURLE_CONV_REQUIRED - {"CURLE_CONV_REQUIRED", CURLE_CONV_REQUIRED}, +#if HAVE_DECL_CURLE_CONV_REQD + {"CURLE_CONV_REQD", CURLE_CONV_REQD}, #else - {"CURLE_CONV_REQUIRED", -1}, + {"CURLE_CONV_REQD", -1}, #endif #if HAVE_DECL_CURLE_SSL_CACERT_BADFILE {"CURLE_SSL_CACERT_BADFILE", CURLE_SSL_CACERT_BADFILE}, @@ -603,7 +604,6 @@ CURLErrorMapping errorMap[] = #else {"CURLE_AGAIN", -1}, #endif - {"CURLE_OK", CURLE_OK}, {NULL, 0} }; @@ -661,16 +661,15 @@ static void raiseError(Connection *conn, CURLcode code) } } - exceptionData = caml_alloc(3, 0); + exceptionData = caml_alloc_tuple(3); Store_field(exceptionData, 0, Val_int(code)); Store_field(exceptionData, 1, Val_int(code)); - Store_field(exceptionData, 2, copy_string(errorString)); + Store_field(exceptionData, 2, caml_copy_string(errorString)); if (conn != NULL && conn->curl_ERRORBUFFER != NULL) { - Store_field(Field(conn->ocamlValues, Ocaml_ERRORBUFFER), 0, - copy_string(conn->curl_ERRORBUFFER)); + Store_field(Field(conn->ocamlValues, Ocaml_ERRORBUFFER), 0, caml_copy_string(conn->curl_ERRORBUFFER)); } exception = caml_named_value("CurlException"); @@ -1409,6 +1408,26 @@ static void handle_slist(Connection *conn, struct curl_slist** slist, OcamlValue CAMLreturn0; } +static long convert_bit_list(long *map, size_t map_size, value option) +{ + CAMLparam1(option); + long bits = 0; + int index; + + while (Val_emptylist != option) + { + index = Int_val(Field(option, 0)); + if ((index < 0) || ((size_t)index >= map_size)) + caml_invalid_argument("convert_bit_list"); + + bits |= map[index]; + + option = Field(option, 1); + } + + CAMLreturnT(long, bits); +} + #define SETOPT_STRING(name) \ static void handle_##name(Connection *conn, value option) \ { \ @@ -2428,7 +2447,7 @@ static void handle_SSH_AUTH_TYPES(Connection *conn, value option) long authTypes = CURLSSH_AUTH_NONE; listIter = option; - + while (!Is_long(listIter)) { switch (Long_val(Field(listIter, 0))) @@ -2676,23 +2695,9 @@ static void handle_PROTOCOLSOPTION(CURLoption curlopt, Connection *conn, value o { CAMLparam1(option); CURLcode result = CURLE_OK; - long protocols = 0; - int index; - - while (Val_emptylist != option) - { - index = Int_val(Field(option, 0)); - if ((index < 0) || ((size_t)index >= sizeof(protoMap) / sizeof(protoMap[0]))) - failwith("Invalid curl protocol"); - - protocols = protocols | protoMap[index]; - - option = Field(option, 1); - } + long bits = convert_bit_list(protoMap, sizeof(protoMap) / sizeof(protoMap[0]), option); - result = curl_easy_setopt(conn->connection, - curlopt, - protocols); + result = curl_easy_setopt(conn->connection, curlopt, bits); if (result != CURLE_OK) raiseError(conn, result); @@ -3142,19 +3147,15 @@ CAMLprim value helper_curl_easy_setopt(value conn, value option) checkConnection(connection); - if (!Is_block(option)) - failwith("Not a block"); - - if (Wosize_val(option) < 1) - failwith("Insufficient data in block"); - data = Field(option, 0); if (Tag_val(option) < sizeof(implementedOptionMap)/sizeof(CURLOptionMapping)) { thisOption = &implementedOptionMap[Tag_val(option)]; if (thisOption->optionHandler) + { thisOption->optionHandler(connection, data); + } else { if (NULL == exception) @@ -3167,7 +3168,9 @@ CAMLprim value helper_curl_easy_setopt(value conn, value option) } } else - failwith("Invalid CURLOPT Option"); + { + caml_failwith("Invalid CURLOPT Option"); + } CAMLreturn(Val_unit); } @@ -3248,7 +3251,7 @@ value convertStringList(struct curl_slist *slist) while (p != NULL) { next = alloc_tuple(2); - Store_field(next, 0, copy_string(p->data)); + Store_field(next, 0, caml_copy_string(p->data)); Store_field(next, 1, Val_int(0)); if (result == Val_int(0)) @@ -3669,7 +3672,7 @@ CAMLprim value helper_curl_easy_getinfo(value conn, value option) { case StringValue: result = alloc(1, StringValue); - Store_field(result, 0, copy_string(strValue?strValue:"")); + Store_field(result, 0, caml_copy_string(strValue?strValue:"")); break; case LongValue: @@ -3700,9 +3703,9 @@ CAMLprim value helper_curl_escape(value str) CAMLparam1(str); CAMLlocal1(result); char *curlResult; - + curlResult = curl_escape(String_val(str), string_length(str)); - result = copy_string(curlResult); + result = caml_copy_string(curlResult); free(curlResult); CAMLreturn(result); @@ -3717,9 +3720,9 @@ CAMLprim value helper_curl_unescape(value str) CAMLparam1(str); CAMLlocal1(result); char *curlResult; - + curlResult = curl_unescape(String_val(str), string_length(str)); - result = copy_string(curlResult); + result = caml_copy_string(curlResult); free(curlResult); CAMLreturn(result); @@ -3754,7 +3757,7 @@ CAMLprim value helper_curl_version(void) char *str; str = curl_version(); - result = copy_string(str); + result = caml_copy_string(str); CAMLreturn(result); } @@ -3937,6 +3940,7 @@ CAMLprim value caml_curl_multi_cleanup(value handle) if (CURLM_OK != curl_multi_cleanup(h->handle)) failwith("caml_curl_multi_cleanup"); + caml_stat_free(h); Multi_val(handle) = (ml_multi_handle*)NULL; CAMLreturn(Val_unit); @@ -4306,3 +4310,119 @@ CAMLprim value caml_curl_multi_timeout(value v_multi) CAMLreturn(Val_long(ms)); } + +#define SETMOPT_VAL_(func_name, curl_option, conv_val) \ +static void func_name(CURLM *handle, value option) \ +{ \ + CAMLparam1(option); \ + CURLcode result = CURLM_OK; \ +\ + result = curl_multi_setopt(handle, curl_option, conv_val(option)); \ +\ + check_mcode(result); \ +\ + CAMLreturn0; \ +} + +#define SETMOPT_VAL(name, conv) SETMOPT_VAL_(handle_multi_##name, CURLMOPT_##name, conv) +#define SETMOPT_BOOL(name) SETMOPT_VAL(name, Bool_val) +#define SETMOPT_LONG(name) SETMOPT_VAL(name, Long_val) +#define SETMOPT_INT64(name) SETMOPT_VAL(name, Int64_val) + +long pipeliningMap[] = +{ + 0, /* CURLPIPE_NOTHING */ + 1, /* CURLPIPE_HTTP1 */ + 2, /* CURLPIPE_MULTIPLEX */ +}; + +static void handle_multi_PIPELINING(CURLM* handle, value option) +{ + CAMLparam1(option); + CURLcode result = CURLM_OK; + + long bits = convert_bit_list(pipeliningMap, sizeof(pipeliningMap) / sizeof(pipeliningMap[0]), option); + + result = curl_multi_setopt(handle, CURLMOPT_PIPELINING, bits); + + check_mcode(result); + + CAMLreturn0; +} + +#if HAVE_DECL_CURLMOPT_MAXCONNECTS +SETMOPT_LONG( MAXCONNECTS) +#endif + +#if HAVE_DECL_CURLMOPT_MAX_PIPELINE_LENGTH +SETMOPT_LONG( MAX_PIPELINE_LENGTH) +#endif + +#if HAVE_DECL_CURLMOPT_MAX_HOST_CONNECTIONS +SETMOPT_LONG( MAX_HOST_CONNECTIONS) +#endif + +typedef struct CURLMOptionMapping CURLMOptionMapping; +#define OPT(name) { handle_multi_## name, "CURLMOPT_"#name} +#define NO_OPT(name) { NULL, "CURLMOPT_"#name} + +struct CURLMOptionMapping +{ + void (*optionHandler)(CURLM *, value); + char *name; +}; + +CURLMOptionMapping implementedMOptionMap[] = { + OPT( PIPELINING), +#if HAVE_DECL_CURLMOPT_MAXCONNECTS + OPT( MAXCONNECTS), +#else + NO_OPT( MAXCONNECTS), +#endif +#if HAVE_DECL_CURLMOPT_MAX_PIPELINE_LENGTH + OPT( MAX_PIPELINE_LENGTH), +#else + NO_OPT( MAX_PIPELINE_LENGTH), +#endif +#if HAVE_DECL_CURLMOPT_MAX_HOST_CONNECTIONS + OPT( MAX_HOST_CONNECTIONS), +#else + NO_OPT( MAX_HOST_CONNECTIONS), +#endif +}; + +CAMLprim value caml_curl_multi_setopt(value v_multi, value option) +{ + CAMLparam2(v_multi, option); + CAMLlocal1(data); + CURLM *handle = Multi_val(v_multi)->handle; + CURLMOptionMapping* thisOption = NULL; + static value* exception = NULL; + + data = Field(option, 0); + + if (Tag_val(option) < sizeof(implementedMOptionMap)/sizeof(CURLMOptionMapping)) + { + thisOption = &implementedMOptionMap[Tag_val(option)]; + if (thisOption->optionHandler) + { + thisOption->optionHandler(handle, data); + } + else + { + if (NULL == exception) + { + exception = caml_named_value("Curl.NotImplemented"); + if (NULL == exception) caml_invalid_argument("Curl.NotImplemented"); + } + + caml_raise_with_string(*exception, thisOption->name); + } + } + else + { + caml_failwith("Invalid CURLMOPT Option"); + } + + CAMLreturn(Val_unit); +} diff --git a/curl.ml b/curl.ml index 684bf4f..81f77f5 100644 --- a/curl.ml +++ b/curl.ml @@ -1301,6 +1301,14 @@ module Multi = struct type mt + type curlPipelining = PIPE_NOTHING | PIPE_HTTP1 | PIPE_MULTIPLEX + + type curlMultiOption = + | CURLMOPT_PIPELINING of curlPipelining list + | CURLMOPT_MAXCONNECTS of int + | CURLMOPT_MAX_PIPELINE_LENGTH of int + | CURLMOPT_MAX_HOST_CONNECTIONS of int + exception Error of string let () = Callback.register_exception "Curl.Multi.Error" (Error "") @@ -1329,5 +1337,6 @@ module Multi = struct external timeout : mt -> int = "caml_curl_multi_timeout" + external setopt : mt -> curlMultiOption -> unit = "caml_curl_multi_setopt" end diff --git a/curl.mli b/curl.mli index 805dd1b..80a899c 100644 --- a/curl.mli +++ b/curl.mli @@ -877,6 +877,14 @@ module Multi : sig (** type of Curl multi stack *) type mt + type curlPipelining = PIPE_NOTHING | PIPE_HTTP1 | PIPE_MULTIPLEX + + type curlMultiOption = + | CURLMOPT_PIPELINING of curlPipelining list + | CURLMOPT_MAXCONNECTS of int + | CURLMOPT_MAX_PIPELINE_LENGTH of int + | CURLMOPT_MAX_HOST_CONNECTIONS of int + (** exception raised on internal errors *) exception Error of string @@ -953,4 +961,7 @@ module Multi : sig *) external timeout : mt -> int = "caml_curl_multi_timeout" + (** @raise NotImplemented for not implemented option *) + val setopt : mt -> curlMultiOption -> unit + end diff --git a/curl_lwt.ml b/curl_lwt.ml index 93c909f..44c9fba 100644 --- a/curl_lwt.ml +++ b/curl_lwt.ml @@ -90,6 +90,10 @@ let create () = (* lwt may not run in parallel so one global is OK'ish *) let global = lazy (create ()) +let setopt opt = + let t = Lazy.force global in + M.setopt t.mt opt + let perform h = let t = Lazy.force global in let (waiter,wakener) = Lwt.wait () in diff --git a/curl_lwt.mli b/curl_lwt.mli index 6eb4ff7..7e8a626 100644 --- a/curl_lwt.mli +++ b/curl_lwt.mli @@ -8,3 +8,8 @@ val set_debug : bool -> unit @return transfer result code *) val perform : Curl.t -> Curl.curlCode Lwt.t + +(** + set option on global multi_handle +*) +val setopt : Curl.Multi.curlMultiOption -> unit diff --git a/errors.ml b/errors.ml new file mode 100644 index 0000000..82ece4e --- /dev/null +++ b/errors.ml @@ -0,0 +1,116 @@ +#use "topfind";; +#require "extlib";; + +open ExtLib + +let all = {| +CURLE_OK +CURLE_UNSUPPORTED_PROTOCOL +CURLE_FAILED_INIT +CURLE_URL_MALFORMAT +CURLE_URL_MALFORMAT_USER +CURLE_COULDNT_RESOLVE_PROXY +CURLE_COULDNT_RESOLVE_HOST +CURLE_COULDNT_CONNECT +CURLE_FTP_WEIRD_SERVER_REPLY +CURLE_FTP_ACCESS_DENIED +CURLE_FTP_USER_PASSWORD_INCORRECT +CURLE_FTP_WEIRD_PASS_REPLY +CURLE_FTP_WEIRD_USER_REPLY +CURLE_FTP_WEIRD_PASV_REPLY +CURLE_FTP_WEIRD_227_FORMAT +CURLE_FTP_CANT_GET_HOST +CURLE_FTP_CANT_RECONNECT +CURLE_FTP_COULDNT_SET_BINARY +CURLE_PARTIAL_FILE +CURLE_FTP_COULDNT_RETR_FILE +CURLE_FTP_WRITE_ERROR +CURLE_FTP_QUOTE_ERROR +CURLE_HTTP_RETURNED_ERROR +CURLE_WRITE_ERROR +CURLE_MALFORMAT_USER +CURLE_FTP_COULDNT_STOR_FILE +CURLE_READ_ERROR +CURLE_OUT_OF_MEMORY +CURLE_OPERATION_TIMEOUTED +CURLE_FTP_COULDNT_SET_ASCII +CURLE_FTP_PORT_FAILED +CURLE_FTP_COULDNT_USE_REST +CURLE_FTP_COULDNT_GET_SIZE +CURLE_HTTP_RANGE_ERROR +CURLE_HTTP_POST_ERROR +CURLE_SSL_CONNECT_ERROR +CURLE_BAD_DOWNLOAD_RESUME +CURLE_FILE_COULDNT_READ_FILE +CURLE_LDAP_CANNOT_BIND +CURLE_LDAP_SEARCH_FAILED +CURLE_LIBRARY_NOT_FOUND +CURLE_FUNCTION_NOT_FOUND +CURLE_ABORTED_BY_CALLBACK +CURLE_BAD_FUNCTION_ARGUMENT +CURLE_BAD_CALLING_ORDER +CURLE_INTERFACE_FAILED +CURLE_BAD_PASSWORD_ENTERED +CURLE_TOO_MANY_REDIRECTS +CURLE_UNKNOWN_TELNET_OPTION +CURLE_TELNET_OPTION_SYNTAX +CURLE_SSL_PEER_CERTIFICATE +CURLE_GOT_NOTHING +CURLE_SSL_ENGINE_NOTFOUND +CURLE_SSL_ENGINE_SETFAILED +CURLE_SEND_ERROR +CURLE_RECV_ERROR +CURLE_SHARE_IN_USE +CURLE_SSL_CERTPROBLEM +CURLE_SSL_CIPHER +CURLE_SSL_CACERT +CURLE_BAD_CONTENT_ENCODING +CURLE_LDAP_INVALID_URL +CURLE_FILESIZE_EXCEEDED +CURLE_FTP_SSL_FAILED +CURLE_SEND_FAIL_REWIND +CURLE_SSL_ENGINE_INITFAILED +CURLE_LOGIN_DENIED +CURLE_TFTP_NOTFOUND +CURLE_TFTP_PERM +CURLE_REMOTE_DISK_FULL +CURLE_TFTP_ILLEGAL +CURLE_TFTP_UNKNOWNID +CURLE_REMOTE_FILE_EXISTS +CURLE_TFTP_NOSUCHUSER +CURLE_CONV_FAILED +CURLE_CONV_REQD +CURLE_SSL_CACERT_BADFILE +CURLE_REMOTE_FILE_NOT_FOUND +CURLE_SSH +CURLE_SSL_SHUTDOWN_FAILED +CURLE_AGAIN +|} + +let pr fmt = Printf.ksprintf print_endline fmt + +let () = + let l = String.nsplit all "\n" |> List.map String.strip |> List.filter ((<>) "") in + match List.tl @@ Array.to_list @@ Sys.argv with + | [] | "c"::[] -> + l |> List.iteri begin fun i s -> + match s with + | "CURLE_OK" -> + pr " {\"%s\", %s}," s s + | _ -> + pr "#if HAVE_DECL_%s" s; + pr "#if %s != %d" s i; + pr "#warning error code mismatch: %s != %d" s i; + pr "#endif"; + pr " {\"%s\", %s}," s s; + pr "#else"; + pr " {\"%s\", -1}," s; + pr"#endif"; + end + | "ml"::[] -> l |> List.iter (pr " | %s") + | "configure"::[] -> + Format.set_margin 80; + Format.open_box 0; + l |> List.iter (function "CURLE_OK" -> () | s -> Format.printf "%s,@ " s); + Format.close_box (); + | _ -> failwith "bad usage" diff --git a/examples/Makefile.in b/examples/Makefile.in index 2cf96ea..45da28b 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -18,15 +18,19 @@ OCURLOPTLIB = curl.cmxa unix.cmxa threads.cmxa TARGETS = ocurl oput ominimal ossl ocurl_test_threads opar test_cb_exn test_memory_leaks ifneq (@OCAML_PKG_lwt@,no) +ifneq (@OCAML_PKG_camlp4@,no) TARGETS += test_lwt test_lwt_unit endif +endif ifeq (@OCAMLBEST@,opt) TARGETS += ocurl.opt oput.opt ominimal.opt ossl.opt ocurl_test_threads.opt opar.opt test_cb_exn.opt test_memory_leaks.opt ifneq (@OCAML_PKG_lwt@,no) +ifneq (@OCAML_PKG_camlp4@,no) TARGETS += test_lwt.opt test_lwt_unit.opt endif endif +endif all: $(TARGETS) diff --git a/examples/test_cb_exn.ml b/examples/test_cb_exn.ml index 2656a80..d416199 100644 --- a/examples/test_cb_exn.ml +++ b/examples/test_cb_exn.ml @@ -18,7 +18,8 @@ let () = perform connection; with | CurlException (CURLE_WRITE_ERROR,_,_) -> printf "ok\n%!" - | exn -> printf "E: wrong error: %s : %s\n%!" (Printexc.to_string exn) !error_buffer + | CurlException (error,_,name) -> printf "E: wrong error: %s %s : %s\n%!" name (Curl.strerror error) !error_buffer + | exn -> printf "E: wrong error: %s\n%!" (Printexc.to_string exn) in run (); run (); -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ocaml-maint/packages/ocurl.git _______________________________________________ Pkg-ocaml-maint-commits mailing list Pkg-ocaml-maint-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-ocaml-maint-commits