--- parser3/src/classes/curl.C 2024/09/07 16:30:26 1.71 +++ parser3/src/classes/curl.C 2026/04/25 13:38:46 1.78 @@ -1,7 +1,7 @@ /** @file Parser: @b curl parser class. - Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com) Authors: Konstantin Morshnev */ @@ -18,7 +18,7 @@ #include "pa_http.h" #include "ltdl.h" -volatile const char * IDENT_CURL_C="$Id: curl.C,v 1.71 2024/09/07 16:30:26 moko Exp $"; +volatile const char * IDENT_CURL_C="$Id: curl.C,v 1.78 2026/04/25 13:38:46 moko Exp $"; class MCurl: public Methoded { public: @@ -45,15 +45,20 @@ typedef void (*t_curl_formfree)(struct c #define GLINK(name) f_##name=(t_##name)lt_dlsym(handle, #name); #define DLINK(name) GLINK(name) if(!f_##name) return "function " #name " was not found"; -static const char *dlink(const char *dlopen_file_spec) { +static const char *dlink(char *dlopen_file_spec) { pa_dlinit(); - lt_dlhandle handle=lt_dlopen(dlopen_file_spec); + lt_dlhandle handle; + do { + char *next=lsplit(dlopen_file_spec, ','); + handle=lt_dlopen(dlopen_file_spec); + dlopen_file_spec=next; + } while (!handle && dlopen_file_spec); if(!handle){ if(const char* result=lt_dlerror()) return result; - return "can not open the dynamic link module"; + return "cannot open the dynamic link module"; } DLINK(curl_easy_init); @@ -136,20 +141,27 @@ public: } }; +#ifdef WIN32 +#define CURL_LIBRARY "libcurl" LT_MODULE_EXT +#else +#define CURL_LIBRARY "libcurl" LT_MODULE_EXT ",libcurl" LT_MODULE_EXT ".4" +#endif + bool curl_linked = false; const char *curl_status = 0; -const char *curl_library="libcurl" LT_MODULE_EXT; + +const char *curl_library=CURL_LIBRARY; static void temp_curl(void (*action)(Request&, MethodParams&), Request& r, MethodParams& params){ if(!curl_linked) - curl_status=dlink(curl_library); + curl_status=dlink(pa_strdup(curl_library)); if(curl_status == 0){ curl_linked=true; Temp_curl temp_curl; action(r,params); } else { - const char *hint=strcmp(curl_library, "libcurl" LT_MODULE_EXT) ? "" : " (at first call ^curl:options[ $.library[correct.libcurl" LT_MODULE_EXT ".name] ])"; + const char *hint=strcmp(curl_library, CURL_LIBRARY) ? "" : " (before use, call ^curl:options[ $.library[correct.libcurl" LT_MODULE_EXT ".name] ])"; throw Exception("curl", 0, "failed to load curl library %s%s", curl_status, hint); } } @@ -164,7 +176,7 @@ static void _curl_session(Request& r, Me } static void _curl_version_action(Request& r, MethodParams& ){ - r.write(*new VString(*new String(f_curl_version(), String::L_TAINTED))); + r.write(*new VString(f_curl_version())); } static void _curl_version(Request& r, MethodParams& params){ @@ -399,7 +411,7 @@ static void curl_form(HashStringValue *v CURLFORM_PTRCONTENTS, curl_transcode(String(tvalue->get(t)->get(0)->cstr()), r), CURLFORM_END); } - } else if(VFile* fvalue=static_cast(i.value()->as("file"))){ + } else if(VFile* fvalue=dynamic_cast(i.value())){ // file f_curl_formadd(&options().f_post, &f_last, CURLFORM_PTRNAME, key, @@ -554,6 +566,8 @@ static void curl_setopt(HashStringValue: // 'library' parser option if(!curl_linked){ curl_library=v.as_string().taint_cstr(String::L_FILE_SPEC); + if(!curl_library[0]) + curl_library=CURL_LIBRARY; } else throw Exception("curl", 0, "failed to set option '%s': already loaded", key.cstr()); break; @@ -630,7 +644,7 @@ static Value *curl_getinfo(const String: case CurlInfo::CURL_HTTP_VERSION:{ long l=0; CURL_GETINFO(l); - return new VString(*new String(curl_http_version_name(l), String::L_TAINTED)); + return new VString(curl_http_version_name(l)); } } return VVoid::get(); @@ -784,11 +798,11 @@ static void _curl_load_action(Request& r long http_status = 0; if(f_curl_easy_getinfo(curl(), CURLINFO_RESPONSE_CODE, &http_status) == CURLE_OK){ - result.fields().put("status", new VInt(http_status)); + HASH_PUT_CSTR(result.fields(), "status", new VInt(http_status)); } VHash* vtables=new VHash; - result.fields().put("tables", vtables); + HASH_PUT_CSTR(result.fields(), "tables", vtables); for(Array_iterator i(response.headers); i; ){ HTTP_Headers::Header header=i.next(); @@ -804,7 +818,7 @@ static void _curl_load_action(Request& r // filling $.cookies if(Value *vcookies=vtables->hash().get("SET-COOKIE")) - result.fields().put(HTTP_COOKIES_NAME, new VTable(parse_cookies(r, vcookies->get_table()))); + HASH_PUT_CSTR(result.fields(), HTTP_COOKIES_NAME, new VTable(parse_cookies(r, vcookies->get_table()))); r.write(result); }