Request Forgery Protection in Rails 2.1
There were some changes to the Request Forgery Protection module to Rails in May (here) that I didn’t know about until I hit my head on them today (reminder to self: keep up with Edge Rails again).
Before, you could make a request to ”/posts.xml” and successfully call any action. The protection safeguarded you only from html and ajax requests that weren’t GETs.
Now, the same response will raise “ActionController::InvalidAuthenticityToken” because it is now looking for the “Content-Type” header instead of the format of your url; in Rails, that’s now request.content_type instead of request.format; and in HTTP, it’s the header “Content-Type: text/xml” instead of “posts.xml”, to specify the mime type of your request data to RequestForgeryProtection.
It’s for sure a smarter way to check for forgery; hopefully everyone can remember to update their api documentation.
Array#inquire 4
class Array
def inquire(val)
include?(val) ? val : first
end
end
Not sure if this has been done before, but it should simplify stuff this:
type = %w(sencha macha kukicha bancha).include?(params[:type]) ? params[:type] : "sencha"
into this:
type = %w(sencha macha kukicha bancha).inquire(params[:type])
Better names for this than inquire? One I thought of was Array#beg, since you don't always get what you ask for. Hm.
Ronin: A Simple Rails Process Logger

(from Apple Dictionary)
Back in the fall at rmbr we were running into some requests that ate up a bunch of our memory. Since we often call a few dozen xml requests at a time, we weren’t exactly sure at first which requests were the cause of the growth.
Since I didn’t have a lot of experience with the already-existing Ruby performance tools out there, I cooked up a really basic plugin that monitors the growth of your Rails handler (server-agnostic, although I’ve only used it with Mongrel). We found the greedy requests and traced the leak to some SQL that was being loaded in one of our views (naughty!) within a few minutes of putting the plugin up on our server.
I finally got around to putting this plugin in my repository, so here is how you can try it out:
script/plugin install http://solid1pxred.com/svn/code/rails/plugins/ronin
Try it locally by running your server likes this:
RONIN=on script/server
And then just tail the log to watch your requests:
tail -f log/ronin.log
The plugin outputs the stats like so:
{ :growth => 0.22, :request_time => 0.187, :start_rss => 23416, :end_rss => 30076, :delta_rss => 6660, :uri => '/zombies/4.xml' }
As you can see it is pretty simple to load the log into irb, eval it, and sort it or do whatever you want with it. I’ve noticed a discrepancy with the request time against the Rails logger, so this is by no means scientific (yet… ?), but it gave me a really good approximation to detect those requests that make your server processes grow.
NOTE: this currently is built for POSIX systems
Altering Request Headers in Rails Integration Tests
def regular_user
open_session do |user|
def user.login(login, pass)
post '/sessions', :login => login, :password => pass
assert_equal 'You Are Logged In On a Browser!!', assigns[:page_title]
end
end
end
All of a sudden you decide to turn this into an iPhone-friendly login page, so you have to check for the HTTP_USER_AGENT header in the request. All you need to do is pass an extra hash of request headers (without the "HTTP_" prefix) into the request method (get, post, put, or delete):
def regular_user
open_session do |user|
def user.login(login, pass)
post '/sessions', { :login => login, :password => pass } , { :user_agent => 'something iPhone something' }
assert_equal 'You Are Logged In On an iPhone!!', assigns[:page_title]
end
end
end
This is a little obvious if you actually check the api for integration testing. But I didn't do that at first :)
Privatize your methods dude! 4
I guess I just feel inclined to post this because I haven't done any Ruby metaprogramming posts before. But let's say that you want to include MyModule in your class, but you want all its instance methods to be private.
PrivateMyModule = MyModule.dup
PrivateMyModule.module_eval "private #{PrivateMyModule.public_instance_methods.map {|m| ":"+m.to_s}.join(',') }"
You can test by grabbing all the private instance methods now from that module:
PrivateMyModule.private_instance_methods
Older posts: 1 2