From: Yuval Lifshitz Date: Mon, 6 Apr 2020 09:50:37 +0000 (+0300) Subject: rgw/http: add timeout to http client X-Git-Tag: v15.2.13~11^2~7^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=30e1aca7978fa7fcdb281394a155e7c52cab6ea9;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) --- diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc index 44e5bb615f5c0..623cf4c53c389 100644 --- a/src/rgw/rgw_http_client.cc +++ b/src/rgw/rgw_http_client.cc @@ -88,7 +88,7 @@ struct rgw_http_req_data : public RefCountedObject { } #endif std::unique_lock l{lock}; - cond.wait(l); + cond.wait(l, [this]{return done==true;}); return ret; } @@ -541,16 +541,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); @@ -558,6 +567,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 2ebb80dfa0757..840ff88fe97d9 100644 --- a/src/rgw/rgw_http_client.h +++ b/src/rgw/rgw_http_client.h @@ -53,6 +53,8 @@ protected: param_vec_t headers; + long req_timeout{0L}; + RGWHTTPManager *get_manager(); int init_request(rgw_http_req_data *req_data); @@ -136,6 +138,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); int wait(optional_yield y);