views:

238

answers:

1

I have some secure images on S3 that I need to load into Flex. I was expecting to be able to do this using signed temporary URLs but can't get it working. I know the URLs I'm generating are correct, because they load fine in my browsers' address bar. Moreover, Flex has no problem loading my images with a non-signed url when they are public, but as soon as I try signing the urls all the images fail, whether public or not.

I've tried image.source = signedURL, image.load(signedURL), etc. If I try loading the file with URLLoader/URLStream, it looks like I'm getting the data OK, but I'm not sure how to translate those results to an Image control.

Is this just an issue with the Image control not being able to recognize signed urls? Do I have to load the image from a byte array? What would that look like?

A: 

This turned out to be a problem in Flex's mx.Image control: When you assign it a url as source, it does some internal decoding/encoding on the url that can screw up the signature if you've already encoded it.

For example, we create a temporary signed url like this ( Taken from as3awss3lib )

url = "http://" + AMAZON_ENDPOINT + "/" + escape(bucketName) + "/" + escape(objectName) + "?AWSAccessKeyId="+this.accessKey+"&Expires="+s+"&Signature="+encodeURIComponent(authString);

This url will work, but when assigning it to Image.source the underlying SWFLoader has an internal function called OSToPlayerURI(url) which breaks the signature.

(NOTE: Creating the temp url without encoding the authString means it will fail half the time, depending on the generated signature's characters- already tried it)

There is a rock-solid (I think) fix, and that's to use the signed url to load the image to a byte array with URLStream, and then assign the ByteArray as the mx.Image source.

I've created a class that encapsulates this: S3Image.as

Hope this helps someone, it was a tricky issue to pin down and undocumented as far as I can tell.

Yarin