使用curl发布Gzipped数据

4

我正在尝试使用系统curl将压缩后的数据发送到服务器,但我一直遇到奇怪的错误。

`curl -sS -X POST -H "Content-Type: application/gzip" --data-binary $data $url`

给出
curl: no URL specified!

并且

`curl -sS -X POST -H "Content-Type: application/gzip" --data-binary "$data" $url`

提供
sh: -c: line 0: unexpected EOF while looking for matching `"'
sh: -c: line 1: syntax error: unexpected end of file
3个回答

4

在正确的方向上迈出了一步,添加",但您没有考虑到$data可能包含"$等。您可以使用String::ShellQuote来解决这个问题。

use String::ShellQuote qw( shell_quote );

my $cmd = shell_quote(
   curl => (
      '-sS',
      '-X' => 'POST',
      '-H' => 'Content-Type: application/gzip',
      '--data-binary' => $data,
      $url,
   ),
);

my $output = `$cmd`;

或者你可以完全避免使用shell。

my @cmd = (
   curl => (
      '-sS',
      '-X' => 'POST',
      '-H' => 'Content-Type: application/gzip',
      '--data-binary' => $data,
      $url,
   ),
);

open(my $pipe, '-|', @cmd) or die $!;
my $output = do { local $/; <$pipe> };
close($pipe);

如果您实际上不需要捕获输出,以下方法也完全避免了 shell:

system(
   curl => (
      '-sS',
      '-X' => 'POST',
      '-H' => 'Content-Type: application/gzip',
      '--data-binary' => $data,
      $url,
   ),
);

话虽如此,我不认为您能够发送包含NUL字节的字符串,而压缩文件很可能会有这种情况。我认为您的方法本质上是有缺陷的。

您知道吗,libcurlcurl的核心)可以通过Net::Curl::Easy访问吗?


我在使用Net::Curl::Easy时遇到了问题,无法正确验证ssl证书,所以我尝试使用系统curl。 - Kevin
哦,他们使用同一个库来做那件事! - ikegami

4

我没有成功地让curl直接从标准输入读取数据,但是使用进程替换却可以,例如:

curl -sS -X POST -H "Content-Type: application/gzip" --data-binary @<(echo "Uncompressed data" | gzip) $url

这种技术可以避免先写入临时文件的必要。

0

这是因为您的二进制数据包含各种垃圾,包括引号和空字节,这会使 shell 混淆。尝试将您的数据放入某个文件并发布该文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接