views:

168

answers:

0

Hi

I am wondering if there is a way to set two different write callback functions in libcurl. The problem is that I'm currently using libcurl to communicate with amazon s3 for various operations, creating buckets, uploading, deleting and downloading objects. The problem is with the download function, I have set a callback function to write the data in binary to a file and its working fine. At the same time, if there was an error in downloading due to credentials mismatch or internal s3 error I want that error xml returned from Amazon to be stored in a string to parse the Xml and get the error message. Here is a snippet from the download function and the write callback I'm using to write the file.

int GetFile(LPCTSTR lpszBucketName, LPCTSTR lpszRemoteFilePath, LPCTSTR lpszLocalFilePath, CURL_PROGRESS m_pCallBack, LPVOID pVoid)
{
        //<some local variables and string manipulation/conversion>
        //...
    m_CurlCode = curl_easy_setopt(curl, CURLOPT_FAILONERROR, false);
if(m_CurlCode != CURLE_OK)
 return GS_AMAZONS3_COULD_NOT_SET_CURL_OPTION;

    m_CurlCode = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
    if(m_CurlCode != CURLE_OK)
     return COULD_NOT_SET_CURL_OPTION;

    m_CurlCode = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    if(m_CurlCode != CURLE_OK)
     return COULD_NOT_SET_CURL_OPTION;

    m_CurlCode = curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, m_pCallBack);
    if(m_CurlCode != CURLE_OK)
     return COULD_NOT_SET_CURL_OPTION;

    m_CurlCode = curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, pVoid);
    if(m_CurlCode != CURLE_OK)
     return COULD_NOT_SET_CURL_OPTION;

    FILE* f = _tfopen(wLocalFilePath.c_str(), _T("wb+"));
    m_CurlCode = curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
    if(m_CurlCode != CURLE_OK)
     return COULD_NOT_SET_CURL_OPTION;

    m_CurlCode = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteFileCallcack);
    if(m_CurlCode != CURLE_OK)
     return COULD_NOT_SET_CURL_OPTION;

    m_CurlCode = curl_easy_setopt(curl, CURLOPT_HTTPGET, true); // HTTP GET
    if(m_CurlCode != CURLE_OK)
     return COULD_NOT_SET_CURL_OPTION;
        //...

}

this is the function I'm using to write to the file

//Wrirte File Callback
size_t WriteFileCallcack(void* data, size_t blockSize, size_t numBlocks, void* userPtr)
{
    cout << "Write_File being called" << endl;
    FILE* locFile = static_cast<FILE*>(userPtr);
    return _fwrite_nolock(data,blockSize,numBlocks,locFile);
}

and this is the function that I use in all other APIs to store the amazon response in a string

size_t writeCallback(void* data, size_t blockSize, size_t numBlocks, void* userPtr)
{
    cout << "Write_data being called" << endl;
    string* userString = static_cast<string*>(userPtr);
    (*userString).append(reinterpret_cast<const char*>(data), blockSize*numBlocks);
    return blockSize*numBlocks;
}

So is there a way to check if the response was actually an error xml rather than the actual file data or is there a way in curl to set two write callbacks at the same time.