Can AS3 do REST, or not?
June 12th, 2007
I just finished reading Thijs van der Vossen’s article, Flex can’t do REST, and I figured I’d weigh in a with a few of my experiences given that I’ve been doing quite a bit of playing with Rails, Actionscript 3, the Flex framework and Air (previously Apollo).
First and foremost, Thijs is correct and Harris Reynolds must either have a hidden agenda or is kidding himself (perhaps both?).
The issue they’re both talking about lies outside the realm of Flex classes, and right down at the Flash Player level. Brian Riggs’ article that was linked to by Thijs, Making HTTP calls in ActionScript 3, refers to the problematic class as being “AS3’s HTTPService class”, which might have throw people onto the wrong trail. The issue is with flash.net.URLLoader (Flash), not mx.HTTPService (Flex).
So what is this “issue”? It’s all in the response headers, actually. While you can get access to the response codes by listening to the HttpStatusEvent.HTTP_STATUS event when using URLLoader, it’s not going to help you with getting access to response headers. I’d put money on the fact that Adobe is unwilling to provide access to the headers because the functionality is not available in all browsers. Their opinion – as a guess – is that the Flash plugin should operate in an identical fashion across all browsers.
Sucks to be us.
The “proof” of all this can be seen when you take a look at the Air API docs for the HTTPStatusEvent class. There’s a responseHeaders property which spits out an array of URLRequestHeader objects…exactly what we want.
Perhaps someone from Adobe could give us a run-down of whether this the product of internal policies regarding Flash plugin behaviour across browsers?
June 12th, 2007 at 04:16 AM
The documentation for flash.events.HTTPStatusEvent states that ‘some Flash Player environments may be unable to detect HTTP status codes; a status code of 0 is always reported in these cases.’
Then lower it states that ‘a value of 0 can be generated in any player (for example, if a malformed URL is requested), and a value of 0 is always generated by the Flash Player plug-in when it is run in the following browsers, which do not pass HTTP status codes to the player: Netscape, Mozilla, Safari, Opera, and Internet Explorer for the Macintosh.’
So, it seems that you can only get the status when you’re running inside Internet Explorer on Windows.
Just wondering, have you been able to get the flash.events.HTTPStatusEven.responseHeaders when you’re running in an environment where the status code is not passed to the player?
Finally, I’m interested to hear how you’ve worked around this issues when using Flex with Rails.
June 12th, 2007 at 11:04 AM
@Thijs: There really isn’t any workaround other than building a URLLoader equivalent with XMLSocket, and proxying all requests through a domain with a valid cross-domain policy file.
As for ‘0’ status codes…you’re correct. I’ve written up a quick example (source / SWF).
June 12th, 2007 at 07:00 PM
Thanks, that’s my impression at this time too.
September 7th, 2007 at 12:55 AM
Nathan,
I read your comments about HTTPStatusEvent and I’ve been playing around with AIR which has no dependence on browsers. Despite the documentation, I am not receiving proper status property values for URLLoader calls, nor am I receiving any values in the responseHeaders property. I am tracing using Wireshark and receive 302 temp moves responses, yet the status reported is always 200. There appear to be no 200 responses in the trace. Perhaps I am missing some background on how the response codes are generated? Also, I trace the responseHeaders and despite a 302 response with headers seen by Wireshark, flex, or AIR does not pick them up. Have you had any success with using httpStatusEvents with AIR?
September 11th, 2007 at 08:32 AM
@Danny: I haven’t been playing with Air recently, however from my previous testing I’m pretty sure that this was working.
The only change on the web front is that newer versions of the Flash Player (certainly those supplied with the Flex 3 beta) now support the
responseHeadersproperty on instances ofHTTPStatusEvent.January 12th, 2008 at 05:09 PM
I am working on an as3 http/https client @ http://code.google.com/p/as3httpclientlib/
With a Socket class you can implement any protocol (including TLS). Currently you can’t detect stream output progress, but hopefully they will fix it soon.
January 14th, 2008 at 01:05 PM
@Gabe: I wasn’t aware this was possible without special smarts on the server end?
From my testing, I found it was impossible to make a
Socketconnection back to port 80 of the host that served the SWF. i.e. a SWF loaded fromhttp://www.atnan.com/example.swfcannot open a socket to port 80 ofatnan.com. The Flash Player will send the string<policy-file-request/>.to the web server which is then of course treated as a malformed HTTP request.All my attempts to request help from Adobe have been met with bugs closed as “Not a bug”, and verbal feedback saying “that should work”. I’ve pretty much given up on it for that reason.
March 3rd, 2008 at 09:16 PM
thanks for a really interesting discussion guys. i have had exactly the same experience. i guess i will have to look into the XMLsocket. Do you guys know if anyone has published a class that handles this?
best regards, vlad
September 24th, 2009 at 11:29 PM
I have published my recent Actionscript library rest-arm. It can do all rest actions in an easy way. check it
http://code.google.com/p/rest-arm/
November 6th, 2009 at 05:08 AM
@Danny AIR is using the webkit HTTP stack. HTTP stacks may use local caches and other smarts just like browsers do. There are HTTP status codes that are handled in the HTTP stack, transparent forwarding and codes that instruct the client to retrieve responses from local caches are a prime example for those. Especially all the 3xx codes may be handled before the response is returned from the HTTP stack to the AIR application. So don’t rely on seeing these 3xx status codes. In the 302 case you can check the “Location” response header to detect that the response came from another location than the requested URL. Also, check the wireshark trace for a subsequent request to another URL to validate my guess.
Joerg