是否可以使用 libcurl 同时下载 POST 和 multipart/form-data 相同的文件?
Is it possible to download and POST with multipart/form-data same file simultaneously, with libcurl?
也许这是一个愚蠢的问题,因为我正在试验 libcurl,而且也可能是不可能的情况。让我先描述一下我想要实现的行为。
假设我想下载一些文件,我可以逐个请求这个文件,直到我得到整个文件。现在,不是将这些数据存储到临时文件中,而是每次我得到其中一个片段或块时,我都想将其上传到另一台服务器。两台服务器都是HTTP服务器,第二台只接受文件的上传,使用了POST和multipart/form-data
。
我有一个想法,但我无法让它发挥作用,而且仍然不确定它是否可能。我的想法是模仿我在 question 中找到的解决方案,但这里他们使用命令行 curl 来完成,第二台服务器是 FTTP 服务器.
所以想法是创建一个管道,并使用这个管道将片段传递给负责上传的部分。让我们给你看一张草图,以防你被我糟糕的英语弄糊涂了:
也许根本不需要 pipe,因为 libcurl 允许您访问您正在下载的这些数据块,就像在 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;
}
我在这里尝试使用 parent process
下载并使用 child process
上传。为了将数据从父进程传递到子进程,我关闭了 parent process
中 PIPE 的 Read end(RE),并关闭了 在child process
中写入PIPE的end(WE)。我们得到这样的结果:
但仍然不知道如何安排这一切。这可能吗?
是的,这当然是可能的。
基本功能可以像这样工作。两个线程:
文件的下载将其存储在内存中,或多或少附加到缓冲区。我们称它为“下载缓冲区”。如果下载缓冲区变得太大,现实生活中的实现可能会暂停传输。即如果上传端比下载端慢很多。
multipart formpost文件的上传是在一个单独的线程中完成的,并且使用了libcurl的CURLOPT_MIMEPOST option to create the post body. The part that uploads the file from memory is created with curl_mime_data_cb,所以当libcurl要上传数据时会调用你提供的回调函数对于那部分。然后,您的回调将提供来自步骤 1 中提到的“下载缓冲区”的数据。如果没有可用数据,回调可能只是等到它之前有数据 returns.
也许这是一个愚蠢的问题,因为我正在试验 libcurl,而且也可能是不可能的情况。让我先描述一下我想要实现的行为。
假设我想下载一些文件,我可以逐个请求这个文件,直到我得到整个文件。现在,不是将这些数据存储到临时文件中,而是每次我得到其中一个片段或块时,我都想将其上传到另一台服务器。两台服务器都是HTTP服务器,第二台只接受文件的上传,使用了POST和multipart/form-data
。
我有一个想法,但我无法让它发挥作用,而且仍然不确定它是否可能。我的想法是模仿我在 question 中找到的解决方案,但这里他们使用命令行 curl 来完成,第二台服务器是 FTTP 服务器.
所以想法是创建一个管道,并使用这个管道将片段传递给负责上传的部分。让我们给你看一张草图,以防你被我糟糕的英语弄糊涂了:
也许根本不需要 pipe,因为 libcurl 允许您访问您正在下载的这些数据块,就像在 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;
}
我在这里尝试使用 parent process
下载并使用 child process
上传。为了将数据从父进程传递到子进程,我关闭了 parent process
中 PIPE 的 Read end(RE),并关闭了 在child process
中写入PIPE的end(WE)。我们得到这样的结果:
但仍然不知道如何安排这一切。这可能吗?
是的,这当然是可能的。
基本功能可以像这样工作。两个线程:
文件的下载将其存储在内存中,或多或少附加到缓冲区。我们称它为“下载缓冲区”。如果下载缓冲区变得太大,现实生活中的实现可能会暂停传输。即如果上传端比下载端慢很多。
multipart formpost文件的上传是在一个单独的线程中完成的,并且使用了libcurl的CURLOPT_MIMEPOST option to create the post body. The part that uploads the file from memory is created with curl_mime_data_cb,所以当libcurl要上传数据时会调用你提供的回调函数对于那部分。然后,您的回调将提供来自步骤 1 中提到的“下载缓冲区”的数据。如果没有可用数据,回调可能只是等到它之前有数据 returns.