From: Yuval Lifshitz Date: Mon, 6 Apr 2020 09:50:37 +0000 (+0300) Subject: rgw/http: add timeout to http client X-Git-Tag: v14.2.22~36^2~3^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=68d412181fecdfeaff281810c19c3c761cc42573;p=ceph.git rgw/http: add timeout to http client also, prevent "Expect: 100-continue" from being sent when not needed Signed-off-by: Yuval Lifshitz (cherry picked from commit dd49cc83078c7e268ce3de7ab0bfbf3035ed5d50) Conflicts: src/rgw/rgw_http_client.cc - nautilus uses Mutex::Locker - instead of two-argument cond.Wait, nautilus needs a while loop src/rgw/rgw_http_client.h --- diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 18f7a4ad43a..bb487581523 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -80,7 +80,9 @@ struct rgw_http_req_data : public RefCountedObject { } #endif Mutex::Locker l(lock); - cond.Wait(lock); + while (!done) { + cond.Wait(lock); + } return ret; } @@ -529,16 +531,25 @@ int RGWHTTPClient::init_request(rgw_http_req_data *_req_data) curl_easy_setopt(easy_handle, CURLOPT_ERRORBUFFER, (void *)req_data->error_buf); curl_easy_setopt(easy_handle, CURLOPT_LOW_SPEED_TIME, cct->_conf->rgw_curl_low_speed_time); curl_easy_setopt(easy_handle, CURLOPT_LOW_SPEED_LIMIT, cct->_conf->rgw_curl_low_speed_limit); - if (h) { - curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, (void *)h); - } curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, send_http_data); curl_easy_setopt(easy_handle, CURLOPT_READDATA, (void *)req_data); if (send_data_hint || is_upload_request(method)) { curl_easy_setopt(easy_handle, CURLOPT_UPLOAD, 1L); } if (has_send_len) { - curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE, (void *)send_len); + // TODO: prevent overflow by using curl_off_t + // and: CURLOPT_INFILESIZE_LARGE, CURLOPT_POSTFIELDSIZE_LARGE + const long size = send_len; + curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE, size); + if (method == "POST") { + curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDSIZE, size); + // TODO: set to size smaller than 1MB should prevent the "Expect" field + // from being sent. So explicit removal is not needed + h = curl_slist_append(h, "Expect:"); + } + } + if (h) { + curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, (void *)h); } if (!verify_ssl) { curl_easy_setopt(easy_handle, CURLOPT_SSL_VERIFYPEER, 0L); @@ -546,6 +557,7 @@ int RGWHTTPClient::init_request(rgw_http_req_data *_req_data) dout(20) << "ssl verification is set to off" << dendl; } curl_easy_setopt(easy_handle, CURLOPT_PRIVATE, (void *)req_data); + curl_easy_setopt(easy_handle, CURLOPT_TIMEOUT, req_timeout); return 0; } diff --git a/src/rgw/rgw_http_client.h b/src/rgw/rgw_http_client.h index eabe8a8519d..ac6d9861640 100644 --- a/src/rgw/rgw_http_client.h +++ b/src/rgw/rgw_http_client.h @@ -100,6 +100,8 @@ protected: param_vec_t headers; + long req_timeout{0L}; + RGWHTTPManager *get_manager(); int init_request(rgw_http_req_data *req_data); @@ -183,6 +185,12 @@ public: verify_ssl = flag; } + // set request timeout in seconds + // zero (default) mean that request will never timeout + void set_req_timeout(long timeout) { + req_timeout = timeout; + } + int process(optional_yield y=null_yield); int wait(optional_yield y=null_yield);