I have a Rails controller with a create method, and I want to POST to it from a Ruby script. When I hit this method from a browser-based POST, the params hash is set appropriately, but when I hit it from my script, the hash is empty. I've already disabled protect_from_forgery, and the method does get called; it just has an empty params. Here is the controller method:
def create
logger.info "GOT: #{request.body.read}"
logger.info "PARAMS: #{params.inspect}"
az = AreaZip.new(params[:area_zip])
if az.save
respond_to { |format|
format.js { render :json => {:id => az.id} }
}
else
logger.warn "FAILED creating AreaZip: #{az.errors.inspect}"
respond_to { |format|
format.js { render :json => {:errors => az.errors} }
}
end
end
Here is the code that does the posting:
def self.post(url, path, params={})
url = "#{url}#{path}"
uri = URI.parse(url)
headers = {
'Content-Type' => 'text/plain; charset=utf-8',
'Authorization' => "Basic #{Base64.encode64('censored:censored').strip}",
}
http = Net::HTTP.new(uri.host, uri.port)
post_data = params.map {|k,v| "#{CGI::escape(k.to_s)}=#{CGI::escape(v.to_s)}" }.join("&")
resp, data = http.post(uri.path, post_data, headers)
return JSON.parse(data)
end
Here is what I see if I post to nc -l -p 12345:
POST /admin/area_zips HTTP/1.1
Accept: */*
Connection: close
Content-Type: text/plain; charset=utf-8
Authorization: Basic sdfnjjsadf[censored]jklsdfsjdfkj
Content-Length: 54
Host: localhost:12345
area_zip%5Bzip%5D=15068-4838&area_zip%5Barea_id%5D=334
If I post to my Rails app, my log shows this:
Started POST "/admin/area_zips" for 127.0.0.1 at Fri Jul 29 09:45:05 -0400 2011
Processing by Admin::AreaZipsController#create as */*
Asking for HTTP basic authentication to reach admin page
GOT: area_zip%5Bzip%5D=15068-6851&area_zip%5Barea_id%5D=334
PARAMS: {"action"=>"create", "controller"=>"admin/area_zips"}
SQL (0.2ms) BEGIN
SQL (0.2ms) ROLLBACK
FAILED creating AreaZip: #<OrderedHash {:area=>["can't be blank"], :zip=>["can't be blank"]}>
Completed 200 OK in 70ms (Views: 41.4ms | ActiveRecord: 1.2ms)
So as you can see, Rails gets the POSTed data, but it's not using it to set up params. Any idea why?
Net::HTTPdocs for recommended ways to do POST: ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTP.html