Bookmarklet hackers: You should know about this false positive XSS in Chrome and how to workaround it.

Recently I ran into a problem working with the Vodpod bookmarklet on Google Chrome. My popup window was throwing a Javascript error, and it turned out to be this security error:

Refused to execute a JavaScript script. Source code of script found within request."

I googled around and couldn’t figure out what was going on. Finally I figured out the problem, and it’s right there in the error. The issue was that my bookmarklet was passing an embed code for a video in the POST to my popup window. Then server side I was spitting that embed code out into the Javascript included on my page. This is a no-no for Chrome – it checks all the Javascript in your loaded page for any code that matches data in the POST. If it finds a match it assumes you’ve got an XSS attack and it prevents that code from being inserted into the new page.

The workaround was to have the bookmarklet encode the embed codes, and then decode those values on the server side before rendering my page. This way the POST data doesn’t match the new page source (POST data is encoded, page source is not). Simple.

Fix for Posterous bookmarklet coming right up. This is undoubtedly a Chrome bug, but we all have to live with it.

5 quotes by the creator of PHP, Rasmus Lerdorf: I don't like programming, and I'm not a real programmer.

  • I really don't like programming. I built this tool to program less so that I could just reuse code.
  • PHP is about as exciting as your toothbrush. You use it every day, it does the job, it is a simple tool, so what? Who would want to read about toothbrushes?
  • I was really, really bad at writing parsers. I still am really bad at writing parsers. We have things like protected properties. We have abstract methods. We have all this stuff that your computer science teacher told you you should be using. I don't care about this crap at all.
  • There are people who actually like programming. I don't understand why they like programming.
  • I'm not a real programmer. I throw together things until it works then I move on. The real programmers will say "yeah it works but you're leaking memory everywhere. Perhaps we should fix that." I'll just restart apache every 10 requests.

Hat tip @igrigorik

Go Ruby!

Uninstalling and reinstalling all ruby gems


sudo gem list | cut -d" " -f1 > gem_list.txt
cat gem_list.txt | xargs sudo gem uninstall -aIx
cat gem_list.txt | xargs sudo gem install

This is useful if you ever want to just reset your gems and clean them up. Or if you upgrade to Snow Leopard and want to make sure all your native gems are in decent shape (since Snow Leopard is 64-bit).

How Superfeedr built Analytics using MongoDB

We weren’t quite sure how to build these analytics. We slowly established a set of requirements and constraints

  • Zero performance impact
  • Fully decoupled from the current infrastructure
  • Results at most hourly
  • Data is more important than graphs
  • Easily-extensible, in case we want to measure more things

This is a really interesting tech read by our friend Julien from Superfeedr.

We've been experimenting with MongoDB in-house as well. It'll be interesting how things shake out over the next year w.r.t. nosql implementations... We're also using Redis and have found that to be much faster / more reliable, though simpler in some respects.

Inspect a live running Ruby process

Are you still adding printf/puts calls and restarting your app to figure what went wrong? Sometimes, the problem is hard to reproduce, or you only discover it in production. You've got a process that exhibits the bug, but you didn't run it under ruby-debug, so there's no choice but kill it and reproduce after adding some code to inspect your program, right?

Sure not. Jamis Buck blogged about how to use GDB to inspect a live Ruby process, and showed how to get a stack-trace using Ruby's C API and some GDB scripting:

(gdb) set $ary = (int)backtrace(-1)
(gdb) set $count = *($ary+8)
(gdb) set $index = 0
(gdb) while $index < $count
>  x/1s *((int)rb_ary_entry($ary, $index)+12)
>  set $index = $index + 1
>end

But it gets much easier than that. How about this:

(gdb) eval "caller"

or

(gdb) eval "local_variables"

Once you've opened that door, you get a full-powered Ruby interpreter inside GDB. Ruby's introspection capabilities do the rest. Local variables, instance variables, classes, methods, Ruby threads, object counts... evil eval can bring us pretty far. You can find the scripts to turn GDB into a sort of IRB that can attach to running processes below.

This turned out to be massively useful today while debugging some errors with the Facebook API on our live site -- it was causing zombie passenger workers.

There's something about using GDB to find problems with production instances just makes you feel cool.

ProtoMultiselect, through the magic of @github, you have grown up! Git+github = open source game changer.

Proof positive that Git and Github has changed the game when it comes to open source. I had happened upon the ProtoMultiselect code back about a year ago when we first implemented Posterous Tagging. It's an amazing little bit of JS that gives you a Mail.app / Facebook selector-like textbox. Essential.

I love autocomplete functionality, and this was one of the most complete open source autocompletes available. It was a pretty unclean codebase -- we had to do quite a bit of hacking to get it working for our tagging. (But it works!)

I hadn't thought about it until lately -- but now we're re-examining all old JS and also planning some cool functionality around address books that will require more multi-select autocomplete UI. Enter Github.


I had found thewebfellas's version of ProtoMultiselect, and from there, clicking on the Network tab, I found who else had picked up the trail, since that original repo had gone cold on March 24th. dvsandersluis picked it up... between March 24th and now, an amazing array of cleanups and fixes had gotten into this codebase. I was astonished at how much had changed between the hacky code snippet off an outdated blog post from last year to the clean, up-to-date version of today.

I forked off dvandersluis and added my own bit (a piece that we need to properly support tagging) --

And now I've also submitted back to the tree in the form of my own fork. I needed something, the codebase didn't do it, and I added it.

Code is living. It's how open source was meant to be. Github, you rock.

Resque to the rescue. But a gotcha: Don't forget to refresh those ActiveRecord connections

Offline queuing has been a huge issue with sites that grow to scale. I know it has been for Posterous. There are a billion options, and its totally opaque which ones are good for what.

Resque was recently open sourced by Chris Wanstrath (@defunkt) and friends at our favorite place to store code. It runs against redis, has amazing logging and forking, and is designed to be resilient under heavy load.

We recently implemented Resque for a bunch of processes around data denormalization (for your subscriptions and notifications), moving away from Workling/Starling completely. It fits perfectly, and gives us great transparency into both the queue and what happened.

After about a day, we started noticing a lot of errors showing up in the log saying Mysql::Error: MySQL server has gone away. Wild. Turns out Resque doesn't do anything special with ActiveRecord, so even though you might set up the parent proc to have your Rails environment running, there's nothing that takes care of those procs the way ActionController does.

Simple fix: We make all our tasks subclass our BaseTask, and instead of implementing self.perform(), we implement self.perform_delegate(), which our BaseTask wraps. And we call verify_active_connections! which is your friend if you want your connections to automatically reconnect if they die.




  class BaseTask
    
    def self.perform(*args)
      ActiveRecord::Base.verify_active_connections!
      self.perform_delegate(*args)
    end
    
    def self.perform_delegate(*args) # override this
    end
    
  end


Other than this little nit, we've found Resque to be phenomenal. Recommended.

Why the process-monitoring ruby 'god' broke

We were having all kinds of weird problems with god, and had to resort to weird hacky solutions to try to make it work. Turns out, there's a reason for it. If you try to do all sorts of shell-like actions in the commands for start/stop/restart, god ends up throwing it all in a shell process, e.g. sh -c your_cmd.

But then god gets the pid to the SHELL process and not your_cmd. And when you want to restart, it ends up killing the shell command and leaving you with zombie, orphaned, totally untracked processes that you have to kill -9 manually. Gruesome.

So in short, this stuff you should AVOID:


w.start = "cd #{RAILS_ROOT} && QUEUE=#{name} rake do:mytask"

This is OK:


w.dir = RAILS_ROOT
w.env = {'QUEUE'=> name}
w.start = "rake do:mytask"

And knowing is half the battle!

EDIT: You could also think of using Bluepill, which is God without the insane memory leak (which apparently is fixed in some hacker's dev branch!) It's in use at Serious Business, and they are one hardcore operation. http://github.com/arya/bluepill

Which acts_as_solr should I use? Mattmatt's acts_as_solr, naturally.

script/plugin install git://github.com/mattmatt/acts_as_solr.git

A note about the acts_as_solr codebase: it all started with an innocent hack that I posted to the solr-user list. It got picked up [editor 3/18/09: respectfully added a special mention of Thiago Jackiw] by Thiago and he turned it  into a serious general purpose ActiveRecord modeling plugin hosted at RubyForge, and now exists as numerous git repository forks. The currently best maintained version is Mathias Meyer’s branch.

Rails plugins have an incredibly short half-life. The creators of acts_as_solr, railsfreaks.com, seem to have disappeared. Luckily, open source can be picked up by new baton carriers.

Thanks mattmatt. You rock.