从Sinatra的管道cURL读取PUT数据

Sua*_*uan 3 curl pipe put request sinatra

我正在重写Sinatra中的一个小型服务器后端,目前客户端通过cURL调用与它进行通信echo "foo" | curl -X PUT -T - http://localhost:8090/.问题是,在我put在Sinatra的方法中request.body.read,即使在我打电话之后rewind,它总是空的.此外,params哈希是完全空的.

奇怪的是,如果我这样做,curl -X PUT -d 'foo' http://localhost:8090/它就会起作用.另外,在node.js中我可以使用request.on('data')request.on('end')函数读取它.

有没有办法PUT在Sinatra 阅读身体?如果可能的话,我想避免更改客户端代码.

wya*_*imo 9

我认为来自客户端的curl命令滥用了-T标志. -T用于上传文件,而不是发送数据.通常,当您不提供目标文件名时,-T将使用本地文件名进行上载.例如,curl -X PUT -T "bar.txt" http://localhost:8090/将本地文件上载bar.txt到远程位置http://localhost:8090/bar.txt.由于您的客户端代码管道stdin而不是指定文件,因此不存在本地文件名.由于您的客户端代码未指定任何目标文件名,因此将产生未定义的结果.我会认为node.js的非标准行为是接受文件上传的内容作为请求体中的数据.

您使用该-d标志的第二个示例是发送数据的正确方法.我真的认为最好的解决方案是更改客户端代码,但如果你愿意,你仍然可以管道stdin.只需使用-d而不是-T像这样:

echo "foo" | curl -X PUT -d @- http://localhost:8090/
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这很有效.如果你想让curl按原样上传数据(保留换行符等),你必须使用`--data-binary`而不是`-d`.此外,curl手册页在`-T`上令人困惑 - 它表示你可以使用`-T -`"来使用stdin而不是给定的文件".我想他们的意思是管道文件_name而不是文件_contents_? (3认同)