如何使用curl CLI将文件上传到我的ruby on rails app?

时间:2012-01-20 15:36:24

标签: ruby-on-rails file file-upload curl

在网络方面,我有两个字段:名称和文档。 Document是一个文件字段,name就是用户想要在应用程序中调用该文件的名称。

以下是我的尝试:

curl -F "media[document]=@a.png" -F "media[name]=api" "http://example.com/medias/create.xml?api_key=123"

但是我收到了InvalidAuthenticityToken错误。 仅当我尝试上载文件/制作媒体对象时才会出现此错误。其他API / xml命令可以工作(不涉及文件的那些)

使用cURL上传文件的正确方法是什么?

编辑: 在上面的curl命令中添加-H“Content-Type:application / xml”会使服务器生成此错误:

/!\ FAILSAFE /!\  Tue Jan 24 08:45:03 -0500 2012
  Status: 500 Internal Server Error
  #<REXML::ParseException: malformed XML: missing tag start
Line: 
Position: 
Last 80 unconsumed characters:
<:??OH?ɽ?H? ???g??yx~t????op?.$?????P&W ??"?

通常使用-d参数提供XML。但我不认为文件可以包含在xml中?也许他们可以? IDK的。

3 个答案:

答案 0 :(得分:9)

如果要从xml创建文件,则应根据需要将xml格式化为data和/或Base64使用CDATA。一旦你有一个格式正确的xml文件,你只需要用curl发送它。

如果您只想上传文件,则无需使用xml界面。你可以打电话:

curl -F "media[document]=@./a.png;type=image/png" -F "media[name]=api" "http://example.com/medias/

对于你的身份验证问题,如果你仍然在这个网址上(我没有在新的rails 3.2.1新应用程序上遇到它),你可以使用常规浏览器访问它,获取cookie信息并发送卷曲。这意味着您将添加到您的命令:

--cookie "csrf-param=authenticity_token" --cookie "csrf-value=XXXXXXX"

或使用convenient script将所有当前的Firefox Cookie从主机发送到curl。

答案 1 :(得分:3)

Rails使用authenticity token来阻止CSRF。它将基于当前用户会话计算的特殊令牌插入到每个表单中,并在请求到达服务器时进行检查。

当您使用curl执行POST请求时,您会收到该错误,因为您没有将有效的真实性令牌传递给服务器。您可以为此方法禁用该保护(注意,禁用它会使此操作对CSRF易受攻击):

protect_from_forgery :except => :some_action

或者您可以使用某些ninja magic将有效的真实性令牌传递给服务器。

另一个选择是基于Rails仅针对具有特定内容类型的请求检查真实性令牌的事实。如果它是一个API并且您在JSON中获得响应,您可以尝试将请求的内容类型设置为application/json,如下所示:

curl -H "Content-Type: application/json" ...

有关详情,请参阅以下链接:onetwothree

答案 2 :(得分:2)

您需要为操作禁用真实性令牌。在控制器中使用它(我假设操作名为create):

protect_from_forgery :except => [:create]

这只发生在POST,PUT或DELETE请求中,这可能是其他请求成功的原因。

如果这是一个API,您将需要完全禁用它。您可以删除protect_from_forgery中的ApplicationController

真实性令牌用于(在某种程度上)确保用户在修改资源时浏览表单。应用程序创建与用户会话关联的随机令牌,并将其放在表单的隐藏字段中。提交表单时,将令牌与存储在会话中的令牌进行比较以进行检查。这在API中没有任何意义。