Diff for /parser3/src/classes/curl.C between versions 1.74 and 1.79

version 1.74, 2024/11/04 03:53:25 version 1.79, 2026/07/13 21:42:16
Line 1 Line 1
 /** @file  /** @file
         Parser: @b curl parser class.          Parser: @b curl parser class.
   
         Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com)          Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
         Authors: Konstantin Morshnev <moko@design.ru>          Authors: Konstantin Morshnev <moko@design.ru>
 */  */
   
Line 45  typedef void (*t_curl_formfree)(struct c Line 45  typedef void (*t_curl_formfree)(struct c
 #define GLINK(name) f_##name=(t_##name)lt_dlsym(handle, #name);  #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";  #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();          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(!handle){
                 if(const char* result=lt_dlerror())                  if(const char* result=lt_dlerror())
Line 136  public: Line 141  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;  bool curl_linked = false;
 const char *curl_status = 0;  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){  static void temp_curl(void (*action)(Request&, MethodParams&), Request& r, MethodParams& params){
         if(!curl_linked)          if(!curl_linked)
                 curl_status=dlink(curl_library);                  curl_status=dlink(pa_strdup(curl_library));
   
         if(curl_status == 0){          if(curl_status == 0){
                 curl_linked=true;                  curl_linked=true;
                 Temp_curl temp_curl;                  Temp_curl temp_curl;
                 action(r,params);                  action(r,params);
         } else {          } 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);                  throw Exception("curl", 0, "failed to load curl library %s%s", curl_status, hint);
         }          }
 }  }
Line 164  static void _curl_session(Request& r, Me Line 176  static void _curl_session(Request& r, Me
 }  }
   
 static void _curl_version_action(Request& r, MethodParams& ){  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){  static void _curl_version(Request& r, MethodParams& params){
Line 554  static void curl_setopt(HashStringValue: Line 566  static void curl_setopt(HashStringValue:
                         // 'library' parser option                          // 'library' parser option
                         if(!curl_linked){                          if(!curl_linked){
                                 curl_library=v.as_string().taint_cstr(String::L_FILE_SPEC);                                  curl_library=v.as_string().taint_cstr(String::L_FILE_SPEC);
                                   if(!curl_library[0])
                                           curl_library=CURL_LIBRARY;
                         } else                           } else 
                                 throw Exception("curl", 0, "failed to set option '%s': already loaded", key.cstr());                                  throw Exception("curl", 0, "failed to set option '%s': already loaded", key.cstr());
                         break;                          break;
Line 630  static Value *curl_getinfo(const String: Line 644  static Value *curl_getinfo(const String:
                 case CurlInfo::CURL_HTTP_VERSION:{                  case CurlInfo::CURL_HTTP_VERSION:{
                         long l=0;                          long l=0;
                         CURL_GETINFO(l);                          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();          return VVoid::get();
Line 725  static void _curl_load_action(Request& r Line 739  static void _curl_load_action(Request& r
         CURL_SETOPT(CURLOPT_WRITEFUNCTION, curl_writer, "curl writer function");          CURL_SETOPT(CURLOPT_WRITEFUNCTION, curl_writer, "curl writer function");
         CURL_SETOPT(CURLOPT_WRITEDATA, &body, "curl write buffer");          CURL_SETOPT(CURLOPT_WRITEDATA, &body, "curl write buffer");
   
           char error[CURL_ERROR_SIZE+1]="";
           CURL_SETOPT(CURLOPT_ERRORBUFFER, error, "curl error buffer");
   
         if(options().is_post && !options().has_content_length){          if(options().is_post && !options().has_content_length){
                 // libcurl bug walkaround. Prior to 7.38 (Debian Jessie) curl passed Content-length: -1                  // libcurl bug walkaround. Prior to 7.38 (Debian Jessie) curl passed Content-length: -1
                 // after that no Content-length header is passed, that hangs request to nginx.                  // after that no Content-length header is passed, that hangs request to nginx.
Line 753  static void _curl_load_action(Request& r Line 770  static void _curl_load_action(Request& r
                                 check_file_size(response.content_length, new String(options().url)); break;                                  check_file_size(response.content_length, new String(options().url)); break;
                         default: break;                          default: break;
                 }                  }
                 throw Exception( PA_DEFAULT(ex_type, "curl.fail"), new String(options().url), "%s", f_curl_easy_strerror(res));                  throw Exception( PA_DEFAULT(ex_type, "curl.fail"), new String(options().url), "%s", error[0] ? error : f_curl_easy_strerror(res));
         }          }
   
         // assure trailing zero          // assure trailing zero
Line 784  static void _curl_load_action(Request& r Line 801  static void _curl_load_action(Request& r
   
         long http_status = 0;          long http_status = 0;
         if(f_curl_easy_getinfo(curl(), CURLINFO_RESPONSE_CODE, &http_status) == CURLE_OK){          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;          VHash* vtables=new VHash;
         result.fields().put("tables", vtables);          HASH_PUT_CSTR(result.fields(), "tables", vtables);
   
         for(Array_iterator<HTTP_Headers::Header> i(response.headers); i; ){          for(Array_iterator<HTTP_Headers::Header> i(response.headers); i; ){
                 HTTP_Headers::Header header=i.next();                  HTTP_Headers::Header header=i.next();
Line 804  static void _curl_load_action(Request& r Line 821  static void _curl_load_action(Request& r
   
         // filling $.cookies          // filling $.cookies
         if(Value *vcookies=vtables->hash().get("SET-COOKIE"))          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);          r.write(result);
 }  }

Removed from v.1.74  
changed lines
  Added in v.1.79


E-mail: