@@ -1484,10 +1484,8 @@ class CurlIo::CurlImpl : public Impl {
14841484 public:
14851485 // ! Constructor
14861486 CurlImpl (const std::string& url, size_t blockSize);
1487- // ! Destructor. Cleans up the curl pointer and releases all managed memory.
1488- ~CurlImpl () override ;
14891487
1490- CURL* curl_; // !< libcurl pointer
1488+ std::unique_ptr< CURL, decltype (&curl_easy_cleanup)> curl_; // !< libcurl pointer
14911489
14921490 // METHODS
14931491 /* !
@@ -1521,18 +1519,12 @@ class CurlIo::CurlImpl : public Impl {
15211519 */
15221520 void writeRemote (const byte* data, size_t size, size_t from, size_t to) override ;
15231521
1524- // NOT IMPLEMENTED
1525- CurlImpl (const CurlImpl&) = delete ; // !< Copy constructor
1526- CurlImpl& operator =(const CurlImpl&) = delete ; // !< Assignment
15271522 private:
15281523 long timeout_; // !< The number of seconds to wait while trying to connect.
15291524};
15301525
1531- CurlIo::CurlImpl::CurlImpl (const std::string& url, size_t blockSize) : Impl(url, blockSize), curl_(curl_easy_init()) {
1532- if (!curl_) {
1533- throw Error (ErrorCode::kerErrorMessage, " Unable to init libcurl." );
1534- }
1535-
1526+ CurlIo::CurlImpl::CurlImpl (const std::string& url, size_t blockSize) :
1527+ Impl(url, blockSize), curl_(curl_easy_init(), curl_easy_cleanup) {
15361528 // The default block size for FTP is much larger than other protocols
15371529 // the reason is that getDataByRange() in FTP always creates the new connection,
15381530 // so we need the large block size to reduce the overhead of creating the connection.
@@ -1548,54 +1540,54 @@ CurlIo::CurlImpl::CurlImpl(const std::string& url, size_t blockSize) : Impl(url,
15481540}
15491541
15501542int64_t CurlIo::CurlImpl::getFileLength () {
1551- curl_easy_reset (curl_); // reset all options
1552- curl_easy_setopt (curl_, CURLOPT_URL, path_.c_str ());
1553- curl_easy_setopt (curl_, CURLOPT_NOBODY, 1 ); // HEAD
1554- curl_easy_setopt (curl_, CURLOPT_WRITEFUNCTION, curlWriter);
1555- curl_easy_setopt (curl_, CURLOPT_SSL_VERIFYPEER, 0L );
1556- curl_easy_setopt (curl_, CURLOPT_SSL_VERIFYHOST, 0L );
1557- curl_easy_setopt (curl_, CURLOPT_CONNECTTIMEOUT, timeout_);
1558- // curl_easy_setopt(curl_, CURLOPT_VERBOSE, 1); // debugging mode
1543+ curl_easy_reset (curl_. get () ); // reset all options
1544+ curl_easy_setopt (curl_. get () , CURLOPT_URL, path_.c_str ());
1545+ curl_easy_setopt (curl_. get () , CURLOPT_NOBODY, 1 ); // HEAD
1546+ curl_easy_setopt (curl_. get () , CURLOPT_WRITEFUNCTION, curlWriter);
1547+ curl_easy_setopt (curl_. get () , CURLOPT_SSL_VERIFYPEER, 0L );
1548+ curl_easy_setopt (curl_. get () , CURLOPT_SSL_VERIFYHOST, 0L );
1549+ curl_easy_setopt (curl_. get () , CURLOPT_CONNECTTIMEOUT, timeout_);
1550+ // curl_easy_setopt(curl_.get() , CURLOPT_VERBOSE, 1); // debugging mode
15591551
15601552 /* Perform the request, res will get the return code */
1561- if (auto res = curl_easy_perform (curl_); res != CURLE_OK) { // error happened
1553+ if (auto res = curl_easy_perform (curl_. get () ); res != CURLE_OK) { // error happened
15621554 throw Error (ErrorCode::kerErrorMessage, curl_easy_strerror (res));
15631555 }
15641556 // get status
15651557 int serverCode;
1566- curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &serverCode); // get code
1558+ curl_easy_getinfo (curl_. get () , CURLINFO_RESPONSE_CODE, &serverCode); // get code
15671559 if (serverCode >= 400 || serverCode < 0 ) {
15681560 throw Error (ErrorCode::kerFileOpenFailed, " http" , serverCode, path_);
15691561 }
15701562 // get length
15711563 curl_off_t temp;
1572- curl_easy_getinfo (curl_, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &temp); // return -1 if unknown
1564+ curl_easy_getinfo (curl_. get () , CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &temp); // return -1 if unknown
15731565 return temp;
15741566}
15751567
15761568void CurlIo::CurlImpl::getDataByRange (size_t lowBlock, size_t highBlock, std::string& response) {
1577- curl_easy_reset (curl_); // reset all options
1578- curl_easy_setopt (curl_, CURLOPT_URL, path_.c_str ());
1579- curl_easy_setopt (curl_, CURLOPT_NOPROGRESS, 1L ); // no progress meter please
1580- curl_easy_setopt (curl_, CURLOPT_WRITEFUNCTION, curlWriter);
1581- curl_easy_setopt (curl_, CURLOPT_WRITEDATA, &response);
1582- curl_easy_setopt (curl_, CURLOPT_SSL_VERIFYPEER, 0L );
1583- curl_easy_setopt (curl_, CURLOPT_CONNECTTIMEOUT, timeout_);
1584- curl_easy_setopt (curl_, CURLOPT_SSL_VERIFYHOST, 0L );
1569+ curl_easy_reset (curl_. get () ); // reset all options
1570+ curl_easy_setopt (curl_. get () , CURLOPT_URL, path_.c_str ());
1571+ curl_easy_setopt (curl_. get () , CURLOPT_NOPROGRESS, 1L ); // no progress meter please
1572+ curl_easy_setopt (curl_. get () , CURLOPT_WRITEFUNCTION, curlWriter);
1573+ curl_easy_setopt (curl_. get () , CURLOPT_WRITEDATA, &response);
1574+ curl_easy_setopt (curl_. get () , CURLOPT_SSL_VERIFYPEER, 0L );
1575+ curl_easy_setopt (curl_. get () , CURLOPT_CONNECTTIMEOUT, timeout_);
1576+ curl_easy_setopt (curl_. get () , CURLOPT_SSL_VERIFYHOST, 0L );
15851577
1586- // curl_easy_setopt(curl_, CURLOPT_VERBOSE, 1); // debugging mode
1578+ // curl_easy_setopt(curl_.get() , CURLOPT_VERBOSE, 1); // debugging mode
15871579
15881580 if (lowBlock != std::numeric_limits<size_t >::max () && highBlock != std::numeric_limits<size_t >::max ()) {
15891581 auto range = stringFormat (" {}-{}" , lowBlock * blockSize_, (highBlock + 1 ) * (blockSize_ - 1 ));
1590- curl_easy_setopt (curl_, CURLOPT_RANGE, range.c_str ());
1582+ curl_easy_setopt (curl_. get () , CURLOPT_RANGE, range.c_str ());
15911583 }
15921584
15931585 /* Perform the request, res will get the return code */
1594- if (auto res = curl_easy_perform (curl_); res != CURLE_OK) {
1586+ if (auto res = curl_easy_perform (curl_. get () ); res != CURLE_OK) {
15951587 throw Error (ErrorCode::kerErrorMessage, curl_easy_strerror (res));
15961588 }
15971589 int serverCode;
1598- curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &serverCode); // get code
1590+ curl_easy_getinfo (curl_. get () , CURLINFO_RESPONSE_CODE, &serverCode); // get code
15991591 if (serverCode >= 400 || serverCode < 0 ) {
16001592 throw Error (ErrorCode::kerFileOpenFailed, " http" , serverCode, path_);
16011593 }
@@ -1618,11 +1610,11 @@ void CurlIo::CurlImpl::writeRemote(const byte* data, size_t size, size_t from, s
16181610 scriptPath = hostInfo.Protocol + " ://" + hostInfo.Host + scriptPath;
16191611 }
16201612
1621- curl_easy_reset (curl_); // reset all options
1622- curl_easy_setopt (curl_, CURLOPT_NOPROGRESS, 1L ); // no progress meter please
1623- // curl_easy_setopt(curl_, CURLOPT_VERBOSE, 1); // debugging mode
1624- curl_easy_setopt (curl_, CURLOPT_URL, scriptPath.c_str ());
1625- curl_easy_setopt (curl_, CURLOPT_SSL_VERIFYPEER, 0L );
1613+ curl_easy_reset (curl_. get () ); // reset all options
1614+ curl_easy_setopt (curl_. get () , CURLOPT_NOPROGRESS, 1L ); // no progress meter please
1615+ // curl_easy_setopt(curl_.get() , CURLOPT_VERBOSE, 1); // debugging mode
1616+ curl_easy_setopt (curl_. get () , CURLOPT_URL, scriptPath.c_str ());
1617+ curl_easy_setopt (curl_. get () , CURLOPT_SSL_VERIFYPEER, 0L );
16261618
16271619 // encode base64
16281620 size_t encodeLength = (((size + 2 ) / 3 ) * 4 ) + 1 ;
@@ -1632,22 +1624,18 @@ void CurlIo::CurlImpl::writeRemote(const byte* data, size_t size, size_t from, s
16321624 const std::string urlencodeData = urlencode (encodeData.get ());
16331625 auto postData = stringFormat (" path={}&from={}&to={}&data={}" , hostInfo.Path , from, to, urlencodeData);
16341626
1635- curl_easy_setopt (curl_, CURLOPT_POSTFIELDS, postData.c_str ());
1627+ curl_easy_setopt (curl_. get () , CURLOPT_POSTFIELDS, postData.c_str ());
16361628 // Perform the request, res will get the return code.
1637- if (auto res = curl_easy_perform (curl_); res != CURLE_OK) {
1629+ if (auto res = curl_easy_perform (curl_. get () ); res != CURLE_OK) {
16381630 throw Error (ErrorCode::kerErrorMessage, curl_easy_strerror (res));
16391631 }
16401632 int serverCode;
1641- curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &serverCode);
1633+ curl_easy_getinfo (curl_. get () , CURLINFO_RESPONSE_CODE, &serverCode);
16421634 if (serverCode >= 400 || serverCode < 0 ) {
16431635 throw Error (ErrorCode::kerFileOpenFailed, " http" , serverCode, path_);
16441636 }
16451637}
16461638
1647- CurlIo::CurlImpl::~CurlImpl () {
1648- curl_easy_cleanup (curl_);
1649- }
1650-
16511639size_t CurlIo::write (const byte* data, size_t wcount) {
16521640 if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) {
16531641 return RemoteIo::write (data, wcount);
0 commit comments