是否可以从管道上传带有cURL的文件?

v64noz0r  于 2023-03-08  发布在  其他
关注(0)|答案(1)|浏览(142)

我的意思是发布一个标准的文件上传表单。在这种情况下,通常的命令行包含这个开关:

-F "Filedata=@filename.zip"

然而,当我尝试输入由linux命令“mkfifo”创建的命名管道时,例如“mkfifofilename.zip“,我总是在生产者端收到错误消息:

curl: (23) Failed writing body (1856 != 16384)

而且一些错误信息出现在fifo的消费者端。我在生产者端用另一个curl命令喂我的fifo,例如:

curl http://example.com/archive.zip > filename.zip

在消费者方面:

curl http://example.com/fileupload.php -F "file=@filename.zip"

当我在fifo的消费者端传递一个Content-Length HTTP头时,我在生产者端没有得到错误消息,但在消费者(上传)端仍然出现错误消息,上传失败。

curl http://example.com/fileupload.php -F "file=@filename.zip" -H "Content-Length: 393594678"

我也尝试过给cURL文件上传一个未命名的管道,导致cURL从stdin读取数据(标记为@-),例如:

curl -# http://example.com/archive.zip | curl -# http://example.com/fileupload.php -F "file=@-"

在这种情况下,上传成功,但下载和上传进度不同步,我可以看到太分离的哈希标记进度指示器,一个用于下载,一个用于上传,相当连续,而不是同时操作。在顶部的远程文件总是命名为“-",但这对我来说不是一个问题,可以稍后重命名。
进一步通知:我在Ruby命令行IRB / Pry会话中尝试了上述方法,并且注意到当我使用Ruby命令“system”调用管道结构时:

system %Q{curl -# http://example.com/archive.zip | curl -# http://example.com/fileupload.php -F "file=@-"}

在本例中,我只能看到一个散列标记进度指示器,因此我认为管道可以正常工作,但在第二个示例中,我可以看到两个连续的散列标记进度指示器,如下所示:

%x{curl -# http://example.com/archive.zip | curl -# http://example.com/fileupload.php -F "file=@-"}
lqfhib0f

lqfhib0f1#

是的,这是可能的!
默认情况下,curl会检查所有提供的参数,计算出所有相关组件(包括文件)的大小,并在构造的POST请求中发送它们。这意味着curl会检查本地文件的大小,因此当您使用fifo时会中断。因此您需要做一些事情!

为fifo分块

通过告诉curl它应该使用分块编码而不是提前提供完整的大小来进行POST,curl将改为以流的方式读取文件,并且只允许它在读取文件(fifo)时显示为所需的任何大小。
您可以通过设置chunked头来实现这一点,curl使用chunked头作为请求分块的信号。

curl -H "Transfer-Encoding: chunked" -F file=@fifo https://example.com

警告

这不是curl默认行为的原因是这要求接收者使用HTTP/1.1或更高版本(curl在从服务器得到响应之前不知道是哪个版本)。

来自标准输入的表单

当从stdin执行formpost时,curl将在执行POST之前首先从内存中的stdin读取整个文件,以获取内容的大小,从而可以将其包含在POST请求中。

相关问题