| 247 | } |
| 248 | |
| 249 | bool HTTPClient::submit() { |
| 250 | if (IsNullOrEmpty(url_)) |
| 251 | return false; |
| 252 | |
| 253 | int absoluteTimeout = std::max(0, 3 * static_cast<int>(read_timeout_ms_.count())); |
| 254 | |
| 255 | curl_easy_setopt(http_session_, CURLOPT_NOSIGNAL, 1); |
| 256 | // setting it to 0 will result in the default 300 second timeout |
| 257 | curl_easy_setopt(http_session_, CURLOPT_CONNECTTIMEOUT_MS, std::max(0, static_cast<int>(connect_timeout_ms_.count()))); |
| 258 | curl_easy_setopt(http_session_, CURLOPT_TIMEOUT_MS, absoluteTimeout); |
| 259 | |
| 260 | if (read_timeout_ms_.count() > 0) { |
| 261 | progress_.reset(); |
| 262 | curl_easy_setopt(http_session_, CURLOPT_NOPROGRESS, 0); |
| 263 | curl_easy_setopt(http_session_, CURLOPT_XFERINFOFUNCTION, onProgress); |
| 264 | curl_easy_setopt(http_session_, CURLOPT_XFERINFODATA, (void*)this); |
| 265 | }else{ |
| 266 | // the user explicitly set it to 0 |
| 267 | curl_easy_setopt(http_session_, CURLOPT_NOPROGRESS, 1); |
| 268 | } |
| 269 | if (headers_ != nullptr) { |
| 270 | headers_ = curl_slist_append(headers_, "Expect:"); |
| 271 | curl_easy_setopt(http_session_, CURLOPT_HTTPHEADER, headers_); |
| 272 | } |
| 273 | |
| 274 | curl_easy_setopt(http_session_, CURLOPT_URL, url_.c_str()); |
| 275 | logger_->log_debug("Submitting to %s", url_); |
| 276 | if (callback == nullptr) { |
| 277 | content_.ptr = &read_callback_; |
| 278 | curl_easy_setopt(http_session_, CURLOPT_WRITEFUNCTION, &utils::HTTPRequestResponse::recieve_write); |
| 279 | curl_easy_setopt(http_session_, CURLOPT_WRITEDATA, static_cast<void*>(&content_)); |
| 280 | } |
| 281 | curl_easy_setopt(http_session_, CURLOPT_HEADERFUNCTION, &utils::HTTPHeaderResponse::receive_headers); |
| 282 | curl_easy_setopt(http_session_, CURLOPT_HEADERDATA, static_cast<void*>(&header_response_)); |
| 283 | if (keep_alive_probe_.count() > 0) { |
| 284 | const auto keepAlive = std::chrono::duration_cast<std::chrono::seconds>(keep_alive_probe_); |
| 285 | const auto keepIdle = std::chrono::duration_cast<std::chrono::seconds>(keep_alive_idle_); |
| 286 | logger_->log_debug("Setting keep alive to %" PRId64 " seconds", keepAlive.count()); |
| 287 | curl_easy_setopt(http_session_, CURLOPT_TCP_KEEPALIVE, 1L); |
| 288 | curl_easy_setopt(http_session_, CURLOPT_TCP_KEEPINTVL, keepAlive.count()); |
| 289 | curl_easy_setopt(http_session_, CURLOPT_TCP_KEEPIDLE, keepIdle.count()); |
| 290 | } |
| 291 | else{ |
| 292 | logger_->log_debug("Not using keep alive"); |
| 293 | curl_easy_setopt(http_session_, CURLOPT_TCP_KEEPALIVE, 0L); |
| 294 | } |
| 295 | res = curl_easy_perform(http_session_); |
| 296 | if (callback == nullptr) { |
| 297 | read_callback_.close(); |
| 298 | } |
| 299 | long http_code; |
| 300 | curl_easy_getinfo(http_session_, CURLINFO_RESPONSE_CODE, &http_code); |
| 301 | http_code_ = http_code; |
| 302 | curl_easy_getinfo(http_session_, CURLINFO_CONTENT_TYPE, &content_type_str_); |
| 303 | if (res == CURLE_OPERATION_TIMEDOUT) { |
| 304 | logger_->log_error("HTTP operation timed out, with absolute timeout %dms\n", absoluteTimeout); |
| 305 | } |
| 306 | if (res != CURLE_OK) { |