curl-library
curl_easy_perform does not return if the readfunc_callback returns
Date: Thu, 14 Nov 2013 13:00:03 -0800
I am building a wrapper around curl that uploads data using HTTP PUT using
the chunked transfer encoding.
The code flow is
Constructor->
public:
HttpFragmentSink(const std::string &uri)
: m_uri(uri), m_curl(0), m_chunk(0), m_data(0, 0)
{
// Setup curl connection.
std::cout << "Opening sink uri: " << m_uri << std::endl;
if(0 == (m_curl = curl_easy_init())){
throw std::bad_alloc();
}
curl_easy_setopt(m_curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(m_curl, CURLOPT_PUT, 1L);
curl_easy_setopt(m_curl, CURLOPT_URL, m_uri.c_str());
m_chunk = curl_slist_append(m_chunk, "Transfer-Encoding: chunked");
m_chunk = curl_slist_append(m_chunk, "Expect:");
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, m_chunk);
curl_easy_setopt(m_curl, libcurl verbose debug, 1L);
curl_easy_setopt(m_curl, CURLOPT_READFUNCTION, read_callback);
curl_easy_setopt(m_curl, CURLOPT_READDATA, &m_data);
}
>>The constructor sets up the curl handle to upload data to the http server.
std::streamsize write(char* data, const ssize_t len)
{
if(!m_data.finished()) {
throw std::exception();
}
m_data = DataDesc(data, len);
std::cout << "calling curl_easy_perform for " << data << std::endl;
int ret = curl_easy_perform(m_curl);
if(CURLE_OK != ret) {
return -1;
}
if(!m_data.finished()) {
return m_data.sent();
}
return len;
}
>>The write function attempts to send one chunk.
>> The client of this class calls write and write calls curl_easy_perform.
>> curl_easy_perform calls the 'read_callback' function.
>> When read_callback returns CURL_READFUNC_PAUSE, I expect
curl_easy_perform to return. However that does not happen and write hangs.
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void
*userdata)
{
std::cout << "read callback called. (" << ptr << ", " << size << ", "
<< nmemb << ", " << userdata << ")" << std::endl;
HttpFragmentSink::DataDesc *pData =
reinterpret_cast<HttpFragmentSink::DataDesc*>(userdata);
if(pData->endOfXfer()) {
std::cout << "read callback returning 0." << std::endl;
return 0;
}
if(pData->finished()) {
std::cout << "read callback returning PAUSE." << std::endl;
return CURL_READFUNC_PAUSE;
}
ssize_t data2Xfer = std::min(static_cast<ssize_t>(size * nmemb),
pData->getXferLen());
memcpy(ptr, pData->getXferStart(), data2Xfer);
pData->advance(data2Xfer);
std::cout << "read callback returning " << data2Xfer << std::endl;
return data2Xfer;
}
Is the curl_easy_perform supposed to return when the read callback function
returns CURL_READFUNC_PAUSE?
If yes, how to get around the problem?
-- Dheeraj Protection of our environment is our responsibility.
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-11-14