Я столкнулся с тем, что кажется очень странной проблемой.
Начнем с того, что это происходит только в Ubuntu 18.04, который работает на VMWare поверх хоста Windows 10.
Я отправляюмногокомпонентный запрос с использованием CURL, и как только размер данных, передаваемых в curl_mime_data, превышает определенную величину, он повреждается таким образом, что определенное смещение перезаписывается с начала, например, «abcdefgh» становится «abcabcabc».
Я вижу эти поврежденные данные как на принимающей стороне, так и в Wireshark на отправителе, поэтому они действительно отправляются таким образом.Мне удалось воспроизвести поведение, используя игрушечную программу, приведенную ниже:
#include <fstream>
#include <iostream>
#include <memory>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <assert.h>
#include <curl/curl.h>
int main(int argc, char **argv)
{
curl_global_init(0);
CURL *curl = curl_easy_init();
curl_mime *form = nullptr;
curl_mimepart *field = nullptr;
CURLcode res = CURLE_OK;
form = curl_mime_init(curl);
std::ifstream t("test.json");
if (!t.good())
{
return 1;
}
std::string str;
t.seekg(0, std::ios::end);
str.reserve(t.tellg());
t.seekg(0, std::ios::beg);
str.assign(std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>());
size_t totalsize = 0;
{
field = curl_mime_addpart(form);
res = curl_mime_data(field, (const char *)str.c_str(), str.size());
{
FILE *f = fopen("out.json", "w");
fprintf(f, "%s", str.c_str());
fclose(f);
}
res = curl_mime_name(field, "response");
assert(res == CURLE_OK);
}
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_URL, "http://1.2.3.4");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
res = curl_easy_perform(curl);
assert(res == CURLE_OK);
curl_mime_free(form);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
Здесь я читаю пример файла для отправки с диска и сбрасываю его перед передачей в curl для сравнения.На данный момент нет никакой разницы, но отправляемое значение отличается от содержимого исходного файла.
Как упоминалось в начале, это происходит только в очень специфической среде, которая на Ubuntu 18.04 onVMWare Workstation 12 на Windows 10. Два разных экземпляра упомянутой Ubuntu по этому вопросу.ЭТОГО НЕ происходит при работе на:
- Centos на том же контейнере VMWare
- Docker внутри упомянутой Ubuntu
- Хост-машина Windows
У меня нет идей, где искать или что может быть причиной этого.Я использую libcurl 7.56 и gcc 7.3.0
Не могли бы вы дать мне несколько идей?Я неправильно использую libcurl?Что еще может быть не так или стоит попробовать?
Обновление
Только что протестировал его на Ubuntu 16.04, и данные тоже были повреждены.Что касается данных, которые я использую, вот оригинальный файл json https://www.dropbox.com/s/gfk0b61tyel68wu/test.json?dl=0 и то, что я получаю от Wireshark https://www.dropbox.com/s/dwlzwhn755c51cf/bad.json?dl=0 Проблема начинается со строки 779. (это случайный json, созданный jsonгенератор, а не реальные данные)
Обновление 2
Похоже, это проблема curl 7.56.Похоже, что бы это ни было, это уже исправлено в curl 7.61.1 (самое последнее на данный момент).Даже дальнейшее расследование показывает, что точный коммит, в котором он был исправлен, равен 5f9e2ca09b57d82baf239039835b3b06dc41bbc5