Curlpp, неполные данные из запроса

Я использую Curlpp для отправки запросов различным веб-сервисам для отправки и получения данных. До сих пор это работало нормально, так как я использовал его только для отправки/получения данных JSON.

Теперь у меня есть ситуация, когда веб-сервис возвращает zip-файл в двоичной форме. Здесь я столкнулся с проблемой, когда полученные данные не являются полными.

Сначала я настроил Curl на запись любых данных в поток ostringstream с помощью параметра WriteStream, но это оказалось неправильным подходом, поскольку данные содержали нулевые символы, и, таким образом, данные останавливались на первом нулевом символе.

После этого вместо использования WriteStream я использовал WriteFunction с функцией обратного вызова. Проблема в этом случае в том, что эта функция всегда вызывается 2 или 3 раза, независимо от количества данных. Это приводит к тому, что всегда есть несколько фрагментов данных, которые не кажутся первой частью файла, хотя данные всегда содержат PK в качестве первых двух символов, что указывает на zip-файл.

Я использовал несколько инструментов, чтобы убедиться, что данные полностью отправляются в мое приложение, поэтому это не проблема веб-сервиса.

Вот код. Обратите внимание, что такие параметры, как имя хоста, порт, заголовки и почтовые поля, устанавливаются в другом месте.

string requestData;

size_t WriteStringCallback(char* ptr, size_t size, size_t nmemb)
{
    requestData += ptr;
    int totalSize= size*nmemb;
    return totalSize;
}

const string CurlRequest::Perform()
{
    curlpp::options::WriteFunction wf(WriteStringCallback);
    this->request.setOpt( wf );
    this->request.perform();

    return requestData;
}

Я надеюсь, что кто-нибудь может помочь мне с этой проблемой, потому что я исчерпал какие-либо идеи о том, как это исправить, а также потому, что curlpp плохо документирован (и еще хуже, поскольку веб-сайт curlpp исчез).


person Edwin    schedule 14.05.2012    source источник


Ответы (2)


Проблема с кодом заключается в том, что данные помещаются в std::string, несмотря на наличие данных в двоичном (ZIP) формате. Я бы рекомендовал поместить данные в поток (или двоичный массив). Вы также можете зарегистрировать обратный вызов для получения заголовков ответа и действовать в WriteCallback в соответствии с "Content-type".

curlpp::options::HeaderFunction для регистрации обратного вызова для получения заголовков ответов.

person Amed    schedule 12.11.2012

std::string не проблема, но конкатенация:

requestData += ptr;

Строка C (ptr) завершается нулем, если ввод содержит нулевые байты, ввод будет усечен. Вы должны обернуть его в строку, которая знает длину своих данных:

requestData += std::string(ptr, size*nmemb);
person Köga    schedule 25.07.2014