cURL MIME повреждение данных при запуске на ВМ - PullRequest
0 голосов
/ 21 сентября 2018

Я столкнулся с тем, что кажется очень странной проблемой.

Начнем с того, что это происходит только в 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

1 Ответ

0 голосов
/ 23 сентября 2018

Как я выяснил, эта конкретная ошибка была исправлена ​​в this commit"mime: исправьте считыватель контента для правильной обработки> 16K данных"

...