This was one of those things that had me reeling in pain a month ago. I couldn’t figure out what exactly was wrong…and I’ve run into this problem twice! The symptom was ActionMailer, which in turn is using Rails TMail extensions, didn’t seem to be downloading attachment correctly on the server. It worked correctly on my development machine, but when I run it on the production server, it just didn’t want to work. All attachments would be two bytes. I had suspected a host of other things, but I’ll spare you the stupidity. It’s a long chain from mail attachment to webpage, and it took a lot of work to narrow it down to Rail’s TMail extensions.
It ends up that this is only an issue if base64.so is on the user’s system. According to this two year old post on Textdrive, ActionMailer’s TMail will choose between two implementations of base64, a C one or a Ruby one, based on the existence of the library base64.so
The problem is, the ruby version assumes that a string will return, and the C version assumes an array will return. And because of that, calling first() on a string only gives the first byte or two, as opposed to calling first on an array, which gives the first element (a string)
I hotfixed it, because I couldn’t get a plugin to work and override the classes. I didn’t spend too much time with it, so if anyone else wants to show me how to do the plugin for this simple fix, I’d be happy to learn.
In base64.rb in the rails directory (I froze my rails in my vendors directory) I changed the code to:
def rb_decode( str, strict = false )
And subsequently, in unquoter.rb
class << self
def unquote_base64_and_convert_to(text, to, from)
convert_to(Base64.decode(text), to, from)
That should fix your problems for now. I was using rails 1.2.0 and it still hasn’t been fixed. I know someone else submitted a patch for it already (Rails bug #7861). Tip!