Apparently Rails 2.1 has the nifty ability to throw a 500 Internal Server Error with the message “IP spoofing attack?!” under certain circumstances.
Unfortunately, those circumstances include a common Apache/Mongrel deployment and Yahoo’s crawler, Slurp, trying to index your site. It’s possible Apache/Mongrel isn’t required; I’m unsure.
The key is that Slurp includes both a Client-IP header (HTTP_CLIENT_IP by the time it hits Rails) and an X-Forwarded-For header (HTTP_X_FORWARDED_FOR). When both are present, Rails assumes something evil is happening and voluntarily dies. Neat.
Such a header can be relied on only if it was set by a trusted proxy. Otherwise, it’s hard to know if it was spoofed. The difficulty is for Rails to know which one, if any, was set by a trusted proxy.
I deploy Rails in a common Apache w/mod_proxy_balancer and Mongrel setup. Apache uses X-Forwarded-For natively, so that’s the one I want to trust. To make Rails happy, I’ve just told Apache to delete the Client-IP header if present.
Adding RequestHeader unset Client-IP to the virtual host configuration seems to do the trick.
This does require mod_headers to be enabled in Apache.
I updated my limited_sessions plugin to improve support for Rails 2.1. It should maintain backwards compatibility.
The change surrounds Rails 2.1’s new partial updates support. Basically, it’s turned off for sessions so the session is kept current and doesn’t expire if the user is active.
the active_scaffold plugin for rails can be useful at times. as is typical of a large library, when it doesn’t do quite what you want, you have to start overriding parts of it.
unfortunately, there aren’t a lot of documented options to doing this with active_scaffold—at least not in the published docs. the code comments discuss more available options. so, what follows is an attempt to document some of those options.
i have used some of these, but not all of them. i don’t promise they work as advertised or even at all.
these are helper methods that can be created for a specific controller.
when to define: to do custom rendering of the form widget for a particular column
when to define: to do custom rendering of the record value
when to override: if you want to substitute a different default sanitization method for all columns. default is h(value).
when to override: if the ActiveScaffold is used as a component on another controllers page
when to override: define additional conditions to be used when querying a recordset
when to override: to extend creation of @record in the new method, perhaps to add default values
when to override: when a hook is needed into the create method
when to override: when customizing handling of authorization for new/create methods
when to override: to customize the process of actually destroying a record
when to override: when customizing handling of authorization for delete/destroy methods
when to override: when customizing handling of authorization for the show_search method
when to override: when customizing handling of authorization for index/table/update_table/row/list methods
when to override: when customizing handling of authorization for the show_search method
when to override: to customize how the parent/source record is found when nesting
when to override: when customizing handling of authorization for the show_search method
when to override: change the default finding of @record for show
when to override: when customizing handling of authorization for the show method
when to override: change the default finding of @record for edit
when to override: if you need to inject data into the record before the update is saved
when to override: when customizing handling of authorization for edit/update methods
when to override: to extend or customize the logic for determining class names of other ActiveScaffold controllers to facilitate nested controllers build on AR relationships
when to define: to indicate what associations should not be followed by active scaffold’s update mechanism
when to define: to indicate what associations should be followed only by active scaffold’s update mechanism
it’s time to announce my second plugin for ruby on rails, limited_sessions.
it’s been publicly available for several days, so i guess it’s time that i actually talk about it.
this came out of a need to manage sessions more intelligently than rails does by default. all of these is built as an extension to ActiveRecordStore, so sessions must be stored in the db. features:
as usual, details are on the project page.
the restful scaffolding generator for rails uses various http status codes when sending results back to the client.
i was adding some additional methods and wanted to use status codes myself, so i went looking for a list of them. i didn’t readily find it in the docs and ended up looking through the source to action controller.
they’re stored in this array:
ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE
type (or paste) that into script/console and you’ll have the full list (which is quite long).
in ruby’s CGI::Session module, sessions are stored as a block of seeming junk, like this: “BMZWRlcm1hbiBCb25kaW5nIENvb”. it’s actually an encoded format which is all well and fine until you need to read something out of it for debugging purposes.
if you are using rails’ ActiveRecordStore, the contents of a session can be read fairly simply. since this relies on an AR model called Session, which your app most likely doesn’t have, we’ll create that too.
so, fire up
script/consoleand input the following:
class Session < ActiveRecord::Base ; end CGI::Session::ActiveRecordStore::Session.unmarshal(Session.find(:first).data)
that will dump the contents of the first session. :first can be replaced with any valid option to AR’s #find method.
dump all of the sessions with something like:
Session.find(:all).collect {|s| CGI::Session::ActiveRecordStore::Session.unmarshal(s.data)}
my first public rails plugin is ready to go. called db_log_cleaner, it’s a more complete version of another plugin called postgre_log_cleaner.
it filters out selected log messages from both postgres and mysql to help keep development.log cleaner.
details are on the project page.
i was recently sharing with someone how to make multiple uploads work with the attachment_fu plugin. as an aside, attachment_fu is the successor to acts_as_attachment. if you were planning to use acts_as_attachment, upgrade your plans and use attachment_fu instead.
multiple file uploads are actually fairly straight forward.
first, in the view:<%= file_field_tag 'attachment_data[]' %>
put as many of these in the view as desired. it’s also easy to cause an arbitrary number of them to be added via javascript by the user’s browser.
then, in the controller:@attachment = Attachment.new params[:attachment_data] ||= [] params[:attachment_data].each do |file| @attachment = Attachment.create({:uploaded_data => file}) unless file == "" end
Attachment is my model for uploaded file—substitute as appropriate. as this isn’t a complete how-to for attachment_fu, i won’t get into configuring attachment_fu or the model here.
that’s it. that wasn’t so painful, eh?
i’ve been rewriting the software backend for this site. it has been my intention, once that was partly done, to begin to discuss more technical stuff here, including code samples—most likely for rails stuff.
that’s all fine and well, but you can’t just post code snippets in black and white. no, this is a technicolor world now and that would never do. so i’ve been on a quest to figure how how to make my shiny, new rails backend parse the code blocks and introduce them to my box of 64 (!) crayolas. (as an aside, i’m pretty sure i wasn’t the only one at age 7 who thought his world would be complete if only i could get a 64-color crayola set—much better than my set of 16.)anyway, i won’t get into lots of details at this point (although i can if somebody wants me to), but in case you need to do the same thing, here are a few jumping off points.
the most common solution seems to be to use the syntax gem. you’ll need to roll your own interface between it and rails, although rails weenie can offer some help.
syntax will recognize ruby, yaml, and xml by default. if you need something more robust, UltraViolet looks interesting although it would certainly have a heavier memory footprint. it leverages textmate bundles so it should be able to interpret/colorize nearly anything that is even semi-common, and then some.
i’m sure there are more options—add them to the comments if you know of something.
the site has a new look today. it also has a new backend to power the whole thing. the last one turned out to be a temporary endeavor as it was my first attempt at a rails application. given some of the newb mistakes i made, it made more sense to start over. so i did.
the design is hopefully less wearying to the eye. there’s still more work to do on that, however.
lastly, i hope to begin to post a bit more often now that this is in place. this will be home to primarily technical discussions/writings.