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

时间:2022-12-08 20:45:30

On the web side of things, I have two fields: name, and document. Document is a file field, and name is just what the user wants to call the file in the app.

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

Here is what I have tried:

这是我尝试过的:

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

but I get an InvalidAuthenticityToken Error. This error only occurs when I try to upload a file / make a media object. The other API / xml commands work (the ones not involving files)

但我得到一个InvalidAuthenticityToken错误。仅当我尝试上载文件/制作媒体对象时才会出现此错误。其他API / xml命令有效(不涉及文件的那些)

what is the correct way to upload a file using cURL?

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

EDIT: adding -H "Content-Type: application/xml" to the above curl command make the server generate this error:

编辑:在上面的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 ??"?

normally the XML is supplied using the -d argument. but I don't think files can be included in xml? maybe they can? idk.

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

3 个解决方案

#1


9  

If you want to create file from xml, you should format your xml to use data, either Base64 and/or CDATA, depending of your needs. Once you have a corretly formatted xml file, you just have to send it with curl.

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

If you just want to upload file, you don't need to use an xml interface. You can just call :

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

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

For your authentification problem, if you still have it on this url (I do not encounter it on a new rails 3.2.1 fresh app), you can access it with a regular browser, get the cookie information and send it with curl. It means that you will add to your command :

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

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

Or use a convenient script to send all your current Firefox cookies from an host into curl.

或者使用方便的脚本将所有当前的Firefox cookie从主机发送到curl。

#2


3  

Rails uses authenticity token to prevent CSRF. It inserts special token calculated based on current user's session into every form and checks it when request comes to the server.

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

When you perform POST request using curl you get that error as you're not passing valid authenticity token to the server. You can either disable that protection for you method like that (note, that disabling it will make this action vulnerable for CSRF):

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

protect_from_forgery :except => :some_action

or you can use some ninja magic to pass valid authenticity token to the server.

或者您可以使用一些忍者魔法将有效的真实性令牌传递给服务器。

Another option is based on the fact that Rails checks authenticity token only for requests with certain content types. If it's an API and you're getting response in JSON you can try setting content type of the request to application/json like that:

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

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

See these links for more information: one, two, three.

有关更多信息,请参阅这些链接:一,二,三。

#3


2  

You need to disable authenticity token for the action. Use this in your controller (I'm assuming the action is named create):

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

protect_from_forgery :except => [:create]

This only happens with POST, PUT or DELETE requests, that's probably why other request are successful.

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

If this is an API you will want to disable this entirely. You can remove protect_from_forgery in you ApplicationController.

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

The authenticity token is used to (somewhat) ensure that the user goes through the form when modifying resources. The application creates a random token associated with the user session and puts it in a hidden field of the form. When the form is submitted the token is compared with the one stored in the session to made the check. This won't have any sense in an API.

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

#1


9  

If you want to create file from xml, you should format your xml to use data, either Base64 and/or CDATA, depending of your needs. Once you have a corretly formatted xml file, you just have to send it with curl.

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

If you just want to upload file, you don't need to use an xml interface. You can just call :

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

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

For your authentification problem, if you still have it on this url (I do not encounter it on a new rails 3.2.1 fresh app), you can access it with a regular browser, get the cookie information and send it with curl. It means that you will add to your command :

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

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

Or use a convenient script to send all your current Firefox cookies from an host into curl.

或者使用方便的脚本将所有当前的Firefox cookie从主机发送到curl。

#2


3  

Rails uses authenticity token to prevent CSRF. It inserts special token calculated based on current user's session into every form and checks it when request comes to the server.

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

When you perform POST request using curl you get that error as you're not passing valid authenticity token to the server. You can either disable that protection for you method like that (note, that disabling it will make this action vulnerable for CSRF):

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

protect_from_forgery :except => :some_action

or you can use some ninja magic to pass valid authenticity token to the server.

或者您可以使用一些忍者魔法将有效的真实性令牌传递给服务器。

Another option is based on the fact that Rails checks authenticity token only for requests with certain content types. If it's an API and you're getting response in JSON you can try setting content type of the request to application/json like that:

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

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

See these links for more information: one, two, three.

有关更多信息,请参阅这些链接:一,二,三。

#3


2  

You need to disable authenticity token for the action. Use this in your controller (I'm assuming the action is named create):

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

protect_from_forgery :except => [:create]

This only happens with POST, PUT or DELETE requests, that's probably why other request are successful.

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

If this is an API you will want to disable this entirely. You can remove protect_from_forgery in you ApplicationController.

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

The authenticity token is used to (somewhat) ensure that the user goes through the form when modifying resources. The application creates a random token associated with the user session and puts it in a hidden field of the form. When the form is submitted the token is compared with the one stored in the session to made the check. This won't have any sense in an API.

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