Reputation: 11
I'm trying to use curl to upload a file to my small Ruby on Rails application.
Here is the insert.html.haml
= form_for :my_result, :url=>{:action=> 'save'}, :html => {:multipart=>true} do |f|
= f.file_field :myfile
= submit_tag 'submit'
The "save" action will be invoked when the form is submitted. But the RoR action to view the form is the "insert" action.
I can view the "insert" form with a browser and then submit my file with no problem.
But I need to submit the file using curl.
When I do a curl -F [email protected] -F commit="submit" URL/insert
, I only get back the "insert" form in HTML.
It doesn't seem to invoke the actual "save" action.
Started POST "/my_results/insert" for 10.15.120.173 at 2013-01-10 10:53:22 -0800
...
Rendered my_results/insert.html.haml within layouts/application (2.9ms)
I'm new to RoR and curl. I'd appreciate any help.
Thanks!
Upvotes: 1
Views: 1361
Reputation: 4088
I'm just taking a guess here, but your POST
probably isn't making it through due to Rails requiring a csrf
authenticity token, which isn't being sent with your curl request.
In the console where you see the result of your POST
there is probably a line that says something along the lines of WARNING: Cannot verify authenticity token.
When you create a form using a Rails helper such as form_for
, Rails automatically creates a hidden field with a generated csrf
token for its value. That way, when the form submits, if the token coming in with the form and the token that Rails is expecting don't match, the request will fail.
You can read up on how to use curl with Rails here.
Here is a link to the Wikipedia article on Cross Site Request Forgery.
Also, please let me know if this is at all relevant to your issue. I'm just assuming that's the cause since I've tried POSTing with curl before and had the same problem
Upvotes: 2
Reputation: 2128
To upload the file, you must mimic the request that happens when the form is submitted.
The form's action is defined as
:url=>{:action=> 'save'}
which transaltes to
<form action="/save" method="POST">
So you should POST to /save
Second point, Rails automatically prefixes the fields names with the name of the object that is passed to form_for
.
If you look at the HTML source of /insert
, the file input looks like
<input name="my_result[myfile]" type="file" />
This explains the the structure of the params
hash :
{
"my_result" => {
"my_file" => [the file]
}
}
which allows to access the form fields values under params[:my_result]
In summary : POST to /save
and name the field my_result[my_file]
:
curl -F my_result[my_file][email protected] URL/save
Upvotes: 3