Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template<typename OptionType>
- void Set_Easy_Opt(CURL* easyHandle, CURLoption option, OptionType value) throw(std::exception)
- {
- CURLcode result = curl_easy_setopt(easyHandle, option, value);
- if (result != CURLE_OK)
- {
- std::ostringstream str;
- str << "curl_easy_setopt FAILED for option: " << option << ", value: " << value
- << " returned: " << (int) result << " " << curl_easy_strerror(result);
- throw std::runtime_error(str.str());
- }
- }
- tm_error_t TransferManager::SetupTransfer(transfer_data& transfer, CURL* handle)
- {
- const long MIN_OPERATION_TIME = 20;
- const long FTP_RESPONSE_TIMEOUT = 90;
- const long CONNECT_TIMEOUT = 60;
- long timeout = difftime(transfer.task.expireTime, std::time(0));
- if (timeout < MIN_OPERATION_TIME)
- {
- LOG_INFO("There is not enough time for the operation: " << timeout
- << " s, minimum is: " << MIN_OPERATION_TIME << " s");
- Fclose(transfer.fileHandle);
- return TM_OP_TOUT;
- }
- long connectTimeout = (timeout > CONNECT_TIMEOUT) ? CONNECT_TIMEOUT : timeout/2;
- long ftpResponseTimeout = (FTP_RESPONSE_TIMEOUT < timeout) ? FTP_RESPONSE_TIMEOUT : (timeout - 1);
- // for now it's only for upload
- if (not transfer.fileHandle) // it can be initial try
- {
- transfer.fileHandle = fopen(transfer.task.GetLocalPath().c_str(), "r");
- if (not transfer.fileHandle)
- {
- LOG_ERROR("CURL: Could not open file handle to: " << transfer.task.GetLocalPath());
- return TM_FILE_ERR;
- }
- }
- try {
- curl_easy_reset(handle);
- transfer.errorBuffer[0] = '\0'; // we clean buffer before every retry of transfer
- Set_Easy_Opt(handle, CURLOPT_ERRORBUFFER, transfer.errorBuffer);
- Set_Easy_Opt(handle, CURLOPT_URL, transfer.task.urlToFile.c_str());
- Set_Easy_Opt(handle, CURLOPT_UPLOAD, 1l);
- Set_Easy_Opt(handle, CURLOPT_APPEND, 1l);
- //Set_Easy_Opt(handle, CURLOPT_RESUME_FROM, -1l); // continue upload
- //Set_Easy_Opt(handle, CURLOPT_RESUME_FROM_LARGE, -1l); // continue upload
- Set_Easy_Opt(handle, CURLOPT_READDATA, transfer.fileHandle);
- std::string userPass = mFtpUser + ":" + mFtpPass;
- Set_Easy_Opt(handle, CURLOPT_USERPWD, userPass.c_str());
- Set_Easy_Opt(handle, CURLOPT_NOSIGNAL, 1l);
- LOG_DEBUG("Setting timeout for task with " << transfer.task.urlToFile
- << ", timeout = " << timeout << ", connect timeout = " << connectTimeout
- << ", ftpResponseTimeout = " << ftpResponseTimeout);
- Set_Easy_Opt(handle, CURLOPT_TIMEOUT, timeout);
- Set_Easy_Opt(handle, CURLOPT_CONNECTTIMEOUT, connectTimeout);
- Set_Easy_Opt(handle, CURLOPT_FTP_RESPONSE_TIMEOUT, ftpResponseTimeout);
- #ifdef CURL_DEBUG_CALLBACK
- Set_Easy_Opt(handle, CURLOPT_VERBOSE, 1l);
- Set_Easy_Opt(handle, CURLOPT_DEBUGFUNCTION, CurlDebugCallback);
- #endif
- Set_Easy_Opt(handle, CURLOPT_LOW_SPEED_TIME, 60l);
- Set_Easy_Opt(handle, CURLOPT_LOW_SPEED_LIMIT, 1l);
- Set_Easy_Opt(handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
- } catch (std::runtime_error const& e) {
- LOG_ERROR("CURL: easy handle could not be configured for server task with url: \""
- << transfer.task.urlToFile << "\", local path: \"" << transfer.task.GetLocalPath()
- << "\", exception: " << e.what());
- if (transfer.errorBuffer[0])
- LOG_ERROR("CURL: ConfigureCurlHandle: curl error buffer: " << transfer.errorBuffer);
- Fclose(transfer.fileHandle);
- return TM_SOFTWARE_ERR;
- }
- CURLMcode curlResult = curl_multi_add_handle(mMultiHandle, handle);
- if (curlResult != CURLM_OK)
- {
- LOG_ERROR("CURL: easy handle could not be added to multi!!!! error code: "
- << (int) curlResult << " " << curl_multi_strerror(curlResult));
- Fclose(transfer.fileHandle);
- return TM_SOFTWARE_ERR;
- }
- return TM_NO_ERR;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement