在VM上运行时cURL MIME数据损坏

时间:2018-09-21 15:36:02

标签: c libcurl multipart ubuntu-18.04

我遇到了一个看起来很奇怪的问题。

首先,它仅在Windows 10主机顶部的VMWare上运行的Ubuntu 18.04上发生。

我正在使用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进行比较之前将其刷新回去。此时,没有什么区别,但是发送的值与原始文件的内容不同。

如开头所述,这仅发生在非常特定的环境中,即Windows 10上的VMWare Workstation 12上的Ubuntu 18.04。 所述ubuntu的两个不同实例。 在以下位置运行时不会发生这种情况:

  • 同一VMWare上的Centos
  • 所说的Ubuntu内的Docker容器
  • 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

这似乎是卷曲7.56的问题。看起来,无论它是什么,它已经在curl 7.61.1(当前的最新版本)中已修复。甚至进一步的调查显示,修复的确切提交是5f9e2ca09b57d82baf239039835b3b06dc41bbc5

1 个答案:

答案 0 :(得分:0)

我发现,这个特殊的错误已在this commit“ MIME中修复:修复内容读取器以正确处理> 16K数据”