使用curl发布Gzip数据

时间:2013-12-11 19:18:23

标签: perl curl gzip

我试图使用系统curl将gzip压缩数据发布到服务器但我最终会遇到奇怪的错误

`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 个答案:

答案 0 :(得分:4)

添加"是朝着正确方向迈出的一步,但您并未认为$data可能包含"$等。您可以使用{ {3}}解决这个问题。

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`;

或者你可以完全避开外壳。

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字节的字符串,这可能是一个gzip压缩文件。我认为你的方法存在固有的缺陷。

您是否知道可以通过String::ShellQuote访问libcurlcurl的胆量)?

答案 1 :(得分:3)

我没有成功地让curl直接从stdin读取数据,但是进程替换确实有效,例如:

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

此技术不再需要首先写入临时文件。

答案 2 :(得分:0)

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