--- parser3/src/classes/curl.C 2017/11/28 20:48:37 1.57 +++ parser3/src/classes/curl.C 2018/08/24 16:31:06 1.60 @@ -17,7 +17,7 @@ #include "pa_http.h" #include "ltdl.h" -volatile const char * IDENT_CURL_C="$Id: curl.C,v 1.57 2017/11/28 20:48:37 moko Exp $"; +volatile const char * IDENT_CURL_C="$Id: curl.C,v 1.60 2018/08/24 16:31:06 moko Exp $"; class MCurl: public Methoded { public: @@ -81,11 +81,13 @@ struct ParserOptions : public PA_Allocat struct curl_httppost *f_post; FILE *f_stderr; - // stuff to walkaround curl content-length bugs + // if response content-length check required + bool no_body; + // stuff to walkaround curl request content-length bugs bool is_post; bool has_content_length; - ParserOptions() : filename(0), content_type(0), is_text(true), charset(0), response_charset(0), url(0), f_post(0), f_stderr(0), is_post(false), has_content_length(false){} + ParserOptions() : filename(0), content_type(0), is_text(true), charset(0), response_charset(0), url(0), f_post(0), f_stderr(0), no_body(false), is_post(false), has_content_length(false){} ~ParserOptions() { f_curl_formfree(f_post); if(f_stderr) @@ -170,6 +172,7 @@ struct CurlOption : public PA_Allocated{ CURL_URLENCODE, // url-encoded string CURL_URL, CURL_INT, + CURL_NO_BODY, CURL_POST, CURL_POSTFIELDS, CURL_FORM, @@ -223,7 +226,7 @@ public: CURL_OPT(CURL_POST, POST); CURL_OPT(CURL_INT, HTTPGET); - CURL_OPT(CURL_INT, NOBODY); + CURL_OPT(CURL_NO_BODY, NOBODY); CURL_OPT(CURL_STRING, CUSTOMREQUEST); CURL_OPT(CURL_POSTFIELDS, POSTFIELDS); // hopefully is safe too @@ -338,7 +341,6 @@ public: CURL_INF(CURL_DOUBLE, STARTTRANSFER_TIME); CURL_INF(CURL_DOUBLE, TOTAL_TIME); CURL_INF(CURL_HTTP_VERSION, HTTP_VERSION); - CURL_INF(CURL_INT, PROTOCOL); CURL_INF(CURL_STRING, SCHEME); } @@ -470,6 +472,13 @@ static void curl_setopt(HashStringValue: res=f_curl_easy_setopt(curl(), opt->id, value_int); break; } + case CurlOption::CURL_NO_BODY:{ + // integer curl option + long value_int=(long)v.as_double(); + res=f_curl_easy_setopt(curl(), opt->id, value_int); + options().no_body=value_int != 0; + break; + } case CurlOption::CURL_POST:{ // integer curl option long value_int=(long)v.as_double(); @@ -586,13 +595,12 @@ static void _curl_options(Request& r, Me #define CURL_GETINFO(arg) \ if((res=f_curl_easy_getinfo(curl(), info->id, &arg)) != CURLE_OK){ \ - throw Exception("curl", 0, "failed to get %s info: %s", key.cstr(), f_curl_easy_strerror(res)); \ + if (fail_on_error) \ + throw Exception("curl", 0, "failed to get %s info: %s", key.cstr(), f_curl_easy_strerror(res)); \ + return 0; \ } -static Value *curl_getinfo(const String::Body &key, CurlInfo *info=0) { - if(info==0 && !(info=curl_infos->get(key))) - throw Exception("curl", 0, "called with invalid parameter '%s'", key.cstr()); - +static Value *curl_getinfo(const String::Body &key, CurlInfo *info, bool fail_on_error=false) { CURLcode res; switch (info->type){ case CurlInfo::CURL_STRING:{ @@ -624,17 +632,21 @@ static void _curl_info(Request& r, Metho curl_infos=new CurlInfoHash(); if(params.count()==1){ const String &name=params.as_string(0, "name must be string"); - r.write(*curl_getinfo(name)); + CurlInfo *info=curl_infos->get(name); + if(info==0) + throw Exception("curl", 0, "called with invalid parameter '%s'", name.cstr()); + r.write(*curl_getinfo(name, info, true)); } else { VHash& result=*new VHash; for(CurlInfoHash::Iterator i(*curl_infos); i; i.next() ){ - result.get_hash()->put(i.key(), curl_getinfo(i.key(), i.value())); + Value *value=curl_getinfo(i.key(), i.value()); + if(value) + result.get_hash()->put(i.key(), value); } r.write(result); } } - class Curl_buffer{ public: char *buf; @@ -677,7 +689,7 @@ static int curl_header(char *data, size_ result->clear(); } else { result->add_header(header); - if(result->content_length>pa_file_size_limit) + if(result->content_length>pa_file_size_limit && !options().no_body) return 0; } }