Starting a new blog 1

One is such a lonely number ;) . This weekend I launched a new blog:The ‘Pit Stop at http://arpitmathur.com. Unlike Code Zen (this blog), where I have tried really hard to keep personal commentary to a minimum and make it as developer focused as I could with a lot of source code and tips for web development, the new one is going to be more on my opinions on (among other things) the social web and the evolution of the online experience from a geek’s point of view. More on the why here. In the meanwhile, this blog will remain the outlet for all my developer focussed stuff (I am still a coder at work).

Do let me know what you think and please add The ‘Pit Stop to your feed readers.

Cheers

Code Zen added to RIA.alltop.com 0

Yup. This blog is now aggregated by Guy Kawasaki’s latest project: alltop.com. Specifically, http://ria.alltop.com, the channel dedicated to Rich Internet Applications. I share the space with some pretty big guns in the RIA domain, so thats pretty exciting :) . For those not in the know, alltop is a site aggregating top shelf content from across the web across different subjects, and present them in an easy to scan layout (very popurls, which I love ;) ). So do check out the different channels on alltop.com and see if you like it.

Dayum, have to up the quality of my posts now. No pressure, no pressure …

Debugging crossdomain issues: Following HTTP 302s 4

Flash's crossdomain access policies have always been one of the things developers have always complained against. The specification keeps changing, even with minor updates to the Flash Players (actually I dont really know what counts as a major release in Flash Player land, all releases are point-point-point releases like 9.0.124.0, making them look really minor). I lost more than 2 days on cross domain issues last week before I finally figured it out. So I figured blogging this could help someone else not waste as much time as I did.

If you are reading this post, also check out my previous crossdomain entry as well, which talks about setting up the Flash logging as well as the newly introduced content-type strictness that broke my last app.

In this particular entry I want to talk about how Flash handles HTTP 302 headers while loading images using a Loader, as well as certain tricks to debug crossdomain related issues. While Flash does load images from outside its security sandbox, it does not give you access to the BitmapData of those images which is what I was trying to do.

Whats HTTP 302 ?
HTTP 302 http header tells the browser that the content has been moved temporarily to a different URL. When the browser receives this message it immediately tries the new url. The header is explained in more detail here.

Why is this a problem ?
The problem occurs when you try to load a resource from a url that may redirect to a url outside the security sandbox of the swf. Although Flash automatically calls the new url, it does not use any loaderContext. The LoaderContext object is the optional argument to a URLRequest when making data request calls using a Loader that tells Flash Player to look for a crossdomain.xml file. The first thing that usually causes errors is that the developer forgets to pass this argument. As far as I remember, AS2 used to look for crossdomain files automatically when making cross-domain calls but AS3 does not. But even when you pass this parameter to a Loader's load function, if the url automatically redirects using 302, the Flash player does not use the LoaderContext in the subsequent call.

The solution:
The way to resolve this (and I only found this after way too long), is to look at the url of LoaderInfo object of the Loader object (Loader.contentLoaderInfo). This data is populated with the new redirected-to URL at the time when the Loader fires the HTTPStatusEvent (and all events following that). Your code needs to check if the final url was different from the original url and if so, load the new URL again, using a LoaderContext that makes the loader look for a crossdomain.xml. The code looks something like this:

Actionscript:
  1. public function ImageLoadTest(){
  2.           l = new Loader()
  3.           l.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete)
  4.           addChild(l);
  5.           load(imageURL);
  6.         }   
  7. private function onLoadComplete(event:Event):void{
  8.         try{
  9.             trace( Bitmap(l.content).bitmapData)
  10.         }catch(e:Error){
  11.             trace('Cannot access bitmap of image due to crossdomain issues');
  12.              load(l.contentLoaderInfo.url);
  13.                 }
  14.     }
  15.  
  16. private function load(url:String):void{
  17.         var context:LoaderContext = new LoaderContext(true)
  18.         l.load(new URLRequest(url), context);
  19.     }

This seems a little idiotic, and makes every load takes twice as long, not to mention consume twice the bandwidth. If anyone knows another way to do this, let me know. However if you do not know the location of the final server up until the time of loading, then this seems to be the only way.

Setting up Flex Builder projects to surface cross domain errors:

The worst part of this bug is that it will never surface when you are developing the code using Flex Builder, since by default, Flex Builder uses the file protocol (file://) to reference the html and swfs, and at this time, all http calls regardless of domains, are allowed. So this bug came up only during the QA phase and seriously jeopardized my project. The way you *should* develop Flex/AS3 projects in Flex Builder is to switch the location of the output folder of your project to the documentRoot of a locally running HTTP server (Macs come with Apache 2 built in, and its an easy install for Windows), and then use the http:// protocol to reference the file. Make sure to change the host file on your machine to reference that page as a subdomain of the project's final web location. Now all security sandbox errors will come up as you develop your app in the trace console window of Flex Builder

Flex Builder Web Project

Verify crossdomain files with Charles:
I use Charles, an http proxy, to monitor the http behavior of my application. Charles comes with a very nifty feature called local mappings that lets you load local files when the browser makes certain calls. I ended up using this to load crossdomain files sitting on my desktop everytime Flash made certain http requests for them, really a great tool considering the schema has changed a bit in the last few versions of the Flash Player.

Charles Local Files

And of course enabling Flash Player logs is absolutely essential while debugging Flash Player cross domain issues.