Flash, cookies, swfuploader and cisco loadbalancers = Fun!

Picture the situation:

We deploy a fancy new flash upload mechanism based on swfupload – users get to see a nice progress line for their massive 5mb photo uploads.

In QA environment, it works perfectly.

In Live, sometimes it just doesn’t work… images seem to disappear once uploaded. How can this be?

The answer lies in our use of a load balancer in front of our 3 web servers. We have a Cisco css of some number, and we make sure that your browser sticks to one of the servers using a specific cookie. All is well.

Enter flash. MacroDobe, in their wisdom, have arranged so that flash doesn’t send session cookies reliably if at all

This royally screws our flash upload mechanism. Your web browser talks to server #1 – your flash player talks to server #2 perhaps. Result, your file goes to the ‘wrong’ server! you expect to see it on #1.

Now, you can use a different load balancing mechanism – cookieurl – this will use cookies if it finds it and if not, will look for the instruction in the URL of the request. So in theory, you add “?server=www1″ to the end of your URL, tell the load balancer to use cookieurl and you are off the to the races, right?

Not quite. The Load balancer will use the url as *fallback* only. What if flash gives it a cookie – but (dun-dun-duuuuuuunnnn!) The Wrong Cookie! Back to square one.

In device conversation form it goes like this:
- flash: hey, I need to post to this URL.
- load balancer: ok, but first, do you have a cookie?
- flash: oh, no. I don’t have one.
- load balancer: well then I see that you have a special URL that says “goto server 1″ – I’m going to send you to server 1
- flash: great, here I go to server 1.
- apache: welcome to server one! Here, have a cookie (server=www1)
- flash: Hey thanks! I love cookies. nom nom nom.

now, flash has it’s own cookie, server 1. Web browser has a cookie. Flash has a cookie. Are they the same? Probably. Will they always be the same? uh… maybe not. If not, then eventually the conversation goes like this:

- flash: hey, I need to post to this URL
- load balancer: ok, but first, do you have a cookie?
- flash: oh, yeah, I got one – server=www1
- load balancer: ok, off you go to server www1
- web browser (which may be on server www2 now): hey, where the hell is my file?

The Solution:

Tell your load balancer “hey, for urls that look like this: /flash_image_upload/ use the following load balance option: search for specific domain names or information in the http header.” (a.k.a – our original cunning plan of ?server=www1)

Shout out to mike wise from rackspace for this – hey, fanatical idea :)

So, a quick rewrite:
RewriteRule ^/flash_image_upload/$ imageuploader.php [nocase,last,qsa]
* qsa gives me the ability to pass through the ?server=www1

Now, for specific uploads from flash – the URL is what decides the server being used. And what determines the URL? The cookie in your web browser – “/imageuploader.php?server=”.$_COOKIE['server']

Let’s see if it works…

G

UPDATE: No, it didn’t work. Sadly, the way rules in the loadbalancer are applied, it wouldn’t allow a mix and match of cookie based rules with url based urls. It’s either or.

In the end, the somewhat less elegant solution was to make a wildcard dns entry, that allowed each server in the pool to be referenced directly. E.g. www1.www.website.com – and rules in the loadbalancer to direct traffic to the appropriate box. So now, swfuploader sends it’s files *directly* to the server that the user’s web browser is talking to.

I don’t like this solution nearly as much because it requires that the load balancer have not only knowledge of all the servers living behind it (not a problem) but *also* have specified rules directing traffic to those servers (a problem if you are looking to dynamically scale, for example in the cloud). Adding rules to load balancer devices can be scripted, no doubt, but it’s not an option with our load balancers, managed by RS.

This entry was posted in computing, zootoo. Bookmark the permalink.