c - 是否可以使用 libcurl 同时下载和发布 multipart/form-data 同一文件?

标签 c http pipe multipartform-data libcurl

也许这是一个愚蠢的问题,因为我正在试验libcurl,而且也可能是不可能做到的情况。让我首先向您描述我想要实现的行为。

假设我想下载一些文件,我可以分段请求这个文件,直到得到整个文件。现在,每次我获得其中一个片段或 block 时,我都想将其上传到另一台服务器,而不是将这些数据存储到临时文件中。两台服务器都是 HTTP 服务器,第二台仅接受文件上传,使用带有 multipart/form-data 的 POST。 我有一个想法,但我无法实现它,并且仍然不确定它是否可能。我的想法是模仿我在 question 中找到的解决方案,但这里他们使用命令行 curl 来完成此操作,第二个服务器是 FTTP 服务器。

所以我们的想法是创建一个管道,并使用这个管道将片段传递到负责上传的部分。让我们给你看一个草图,以防你因我蹩脚的英语而迷失方向: data flow

也许根本不需要管道,因为libcurl允许您访问正在下载的这些数据 block ,就像 getinmemory example 中那样。 ,但我不知道是否可以将这些片段传递到一个 multipart/form-data 请求中,而不将数据存储到文件中,然后告诉 libcurl 上传该文件。

正如我之前所说,我尝试使管道的此解决方案起作用,但无法使其起作用。让我展示我不完整的代码,以便您获得具体的想法:

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <curl/curl.h>

#define WE 1
#define RE 0



/*down_up video*/
CURLcode down_up(void)
{
  CURLcode ret;
  const char *url_down = "http://localhost:4000/static/videos/1.mp4";
  const char *url_up = "http://localhost:4000/upload";

  int pdf[2]; /*write end and read end*/

  if(pipe(pdf) == -1)
    errExit("pipe");

  pid_t pid = fork();
  switch(pid) {
  case -1:
    errExit("ok");
  case 0:
    /*closing unused WE in child proccess*/
    if(close(pdf[WE]) == -1)
      errExit("Close");
    break;
  default:
    /*parent process*/
    /*closing the RE on parent proccess*/
    if(close(pdf[RE]) == -1)
      errExit("Close");
    break;
  }

  switch(pid) {
  case -1:
    errExit("ok");
  case 0:
    /*child process*/
    CURL *curl_up;
    curl_up = curl_easy_init();
    curl_easy_setopt(curl_up, CURLOPT_URL, url_up);
   /*upload file with multipart/form-data, reading chunks from pipe*/

    break;
  default:
    /*parent process*/
    CURL *curl_down;
    curl_down = curl_easy_init();
    curl_easy_setopt(curl_down, CURLOPT_URL, url_down);
    /*download file, and writing pieces into the pipe*/

    break;
  }


  curl_easy_cleanup(curl_down);
  curl_easy_cleanup(curl_up);
  curl_down = NULL;
  curl_up = NULL;
  return ret;
}

int main(void)
{
  CURLcode ret;
  ret = download_upload();
  if(ret != CURLE_OK)
    return 1;
  return 0;
}

这里我尝试使用父进程下载,并使用子进程上传。为了将数据从父进程传递到子进程,我关闭了父进程中PIPE的读取端(RE),并且还关闭了子进程中写入PIPE的结束(WE)。我们得到这样的东西:

pipe after fork

但仍然不知道如何协调这一切。这可能吗?

最佳答案

是的,这当然是可能的。

基本功能可以像这样工作。两个线程:

  1. 文件的下载将其存储在内存中,或多或少附加到缓冲区中。我们称之为“下载缓冲区”。如果下载缓冲区变得太大,现实生活中的实现可能会暂停传输。即,如果上传端比下载端慢得多。

  2. 多部分 formpost 中的文件上传是在单独的线程中完成的,并使用 libcurl 的 CURLOPT_MIMEPOST创建帖子正文的选项。从内存上传文件的部分是用curl_mime_data_cb创建的。 ,以便当 libcurl 想要上传该部分的数据时调用您提供的回调函数。然后,您的回调将提供步骤 1 中提到的“下载缓冲区”中的数据。如果没有可用数据,回调可能会一直等到有数据才返回。

关于c - 是否可以使用 libcurl 同时下载和发布 multipart/form-data 同一文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68240299/

相关文章:

c++ - 如何在 C++ 中避免 GOTO

c - 机器人的微 Controller 选择和编程

java - W3C validator 返回 HTTP 500,尽管它可以在浏览器中运行

http - 当由于特定原因不允许 DELETE 操作时返回哪个 HTTP 状态码

Qt multipart post问题

c - 在C中获取冒号后的数字

在 scilab 中从 xcos 生成 C/C++ 代码

C DLL 和新数据服务进程之间基于云的 IPC

node.js - 为什么两个进程之间的管道数据太大时看起来会被截断?

linux - Bash oneliner with pipes 和 if condition giving error