Flex, Flash, and HTTP Status Codes

This post was written by jimrobson on April 16, 2009
Posted Under: Flash, Flex

This question comes from a *nix sysadmin (and all-around good guy):

“Jim, do you have a way to make flex handle a richer set of HTTP status codes in a portable way? Without that, I’m hesitant to recommend it for REST deployments.”

This is certainly a reasonable concern. The fact that Adobe still has not addressed this issue after all these years seems truly odd. To get an idea of the amount of trouble this causes, go to the Flex Bug and Issue Tracker at http://bugs.adobe.com/jira/secure/QuickSearch.jspa , type “http status code” in the Quick Search box (upper right corner) and see how many results you get.

Having said that, let us now look at what to do about it. First, note that it is not really a Flex issue per se. Remember, Flex is simply a framework (or tool kit or set of libraries or whatever you like to call it) for building Flash applications, so a Flex application is nothing but a type of Flash application. Therefore, Flex applications necessarily suffer from any weaknesses in the Flash VM. And this particular issue, as I understand it, is a weakness in the Flash runtime.

Knowing where the problem lies is half the battle. Since the problem under consideration lies in the Flash Player, we know that we can’t fix it with Flex code, and so we need to work around it some other way.

[Update: James Ward points out in his comments below that, strictly speaking, this issue has its roots in the way the browsers treat their plugins, which is not always very nice. However, from the Flash/Flex developer's perspective, it makes no practical difference: We still can't fix the problem with ActionScript, and the kind of workarounds discussed here are required whether the problem is in the plugin or in the browsers' plugin API. And even it the problem is in the browsers' plugin API, the end result is a limitation in Flash.]

One approach is to catch your errors with the server-side code and output messages that can be read by any client. Depending on the server technology and the developers working with it, this can be a very easy and effective approach to the problem. With ColdFusion, for example, you can do something as simple as this:

<cftry>
  <!---
    Do whatever processing you
    need to do here, such as a
    <cfquery>
             --->
  <cfoutput>
    <result>
        <error>
            <code>0</code>
        </error>
        <!-- Define the XML
             output here --->
    </result>
  </cfoutput>
  <cfcatch>
    <cfoutput>
        <result>
          <error>
            <code>1</code>
            <message>#cfcatch.Message#</message>
            <type>#cfcatch.Type#</type>
          </error>
      </result>
    </cfoutput>
  </cfcatch>
</cftry>

You can do similar things with Alfresco web scripts, JSP, ASP, PHP, etc. This approach will handle the majority of server-side errors in a way that any UI client could work with. However, it does not cover every scenario, and it may not address the portability aspect of the question that we started with. Besides, you simply do not have this option in every situation (for example, when attaching a Flex UI to an existing application). So we need to go a bit further.

One practice I recommend is writing simple HTML forms to invoke the services. These forms are bare-bones, with no styling and very little attention given to layout; they are purely for functionality. I do this regardless of whether I am writing the server code myself or I am just building the UI to someone else’s code. (Side point: One of the many things I like about Rails is that it builds this scaffolding for you.)

These HTML forms are used in two ways. First, use them to test the server code before running it from the Flash/Flex application. If the application doesn’t work correctly this way, then you know it won’t work from your Flash GUI. Once everything appears to be working from the HTML forms, you are ready to start running the application using the Flash GUI.

Now, if you get an error that Flash is not able to handle, you have an easy way to debug it. Simply enter the same data in your HTML form that was entered in the Flash GUI, submit the form, and see what the error message is. In the vast majority of cases, this will point you to the cause of the error, and hence the solution.

It is true that this requires some extra work on the part of the Flash/Flex developer. And this is really where the answer lies: in the developer.

Every technology has limitations. I will go further, and say that every technology has serious limitations. Even if you go down to something as simple as the hammer, and you think about it a little, you will see that it has serious limitations. This does not prevent us from working with the technology. Rather, if we see a benefit in the technology, we learn to work with it in spite of its limitations.

Having worked with this particular technology since the days of Flash 4, I am very pleased with the progress that Macromedia and Adobe have made, and rarely find reason to complain. However, I do realize that some of the remaining limitations can be frustrating - especially to people who are new to Flash, and find there are things which are very simple in other technologies that are not so simple in Flash. What to do about these things? Again, it comes down to the developer.

The best solution to the HTTP status code issue, and other such issues, is to use Flash/Flex developers who have the experience and/or tenacity to make the technology work in spite of its limitations. In the hands of such people, Flash can work wonders, and the non-Flash team members do not feel particularly burdened by the fact that Flash is being used for the UI.

On the other hand, if you are building large, complex applications with inexperienced Flash developers, then your entire team is going to feel the pain. But that is the same with every technology you use in your development and deployment. If you have  inexperienced DBAs, Java developers, Alfresco developers, or sysadmins, everyone suffers.

Twenty-five years ago, when I bought my first 22-oz Estwing , I found it to be unwieldy and tiring. It was much harder to swing than my old 16-oz hammer, and the guys I worked with got some laughs (and some frustration) watching me make my blunders with it. However, I had seen how effective it could be in the hand of an experienced carpenter. So, even though it caused me a lot of pain - to the point of losing a fingernail - I kept using it, and eventually found it to be indispensable. And, in the end, I was much more of an asset to the crew than I had been previously. It is a great tool.

Flash and Flex are great tools, too.

Reader Comments

The root of the problem is not with Flash Player but with the browser’s plugin API. So it really requires browsers to fix this. Until then the best way to deal with this is using a proxy server like BlazeDS. Another possible option is to use a socket based AS3 HTTP client:
http://code.google.com/p/as3httpclientlib/

Hope that helps.

-James (Adobe)

#1 
Written By James Ward on April 16th, 2009 @ 11:04 pm

@James,

 
Thanks for the clarification as to where the root of the problem is. Now that you say it, I remember hearing it before. :-)
 

Just to clarify, BlazeDS is not under consideration here; the question has to do with making Flex clients work with simple REST services.

 
Thanks, too, for pointing out as3httpclientlib. I was not aware of that project. However, since it uses the Flash Player’s socket API, I believe it requires some server setup - http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html - which would make it unpalatable to my sysadmin friend who asked the question. It also makes it useless for hooking up to pre-existing services, or any service where I don’t have access to the server.

 
The issue, as I understand it, is that I can’t build a Flash (Flex) client that simply works with REST services (existing or new) the way other clients do. If I build an HTML-based client (ColdFusion, JSP, PHP, etc.), then I can handle HTTP 500 messages in a rational way, and I can distinguish between 500, 404, 403, and 401. I can’t do that with a Flash client, because when the server returns an HTTP 500, my Flash client does not get it. So unless I create some other way to see the error, I never know which error is occurring.

#2 
Written By jimrobson on April 17th, 2009 @ 8:23 am

James, you’re right in that the IE version of flash does seem to have more visibility into the http status codes but I’m not sure I see how a browser vendor is responsible for the flash plugin’s abilities. The browsers themselves read and parse http headers quite well.

The AS3 http client is a good option but does require the (dubious at best) “security” enhancement of setting up a special, unsupported by adobe, service to spit out an xml file in a made-up-protocol exchange. In my mind, it also proves the point above about browsers not being responsible for making flash work as an http client.

BlazeDS does work well in a tightly-coupled deployment where you are talking at a java class level, but its capabilities to talk REST are proving about as good as the flash browser plugin’s. :) Also BlazeDS’s deployment overhead is an unlucky surprise for someone developing a non-java app.

Thanks for the answer, Jim. Let’s hope flash 11 has full http support!

#3 
Written By matt sporleder on April 17th, 2009 @ 8:39 am

Looks like a little more explanation is necessary…

1) BlazeDS is not just for AMF. It also has a proxy service which allows Flex apps to get around the status code limitations.

2) This really is a browser limitation. The networking stack that plugins in the browser use is limited. Flash could use it’s own networking stack (like Socket does) but then you loose the browser cookies, proxy server settings, etc. And unfortunately the NPAPI hasn’t changed very much in the past 10 or so years. All browser plugins that use NPAPI’s networking stack have this problem - not just Flash Player.

I hope that helps.

-James

#4 
Written By James Ward on April 17th, 2009 @ 9:02 am

@James,
I think BlazeDS and LCDS are great products, and I would love to see many more deployments of both. And it is understood that they do more than AMF. But, they really only provide a solution if you are building a new application from the ground up (or are at least willing to make a substantial investment of time on the server-side), and if you are using Java. Remember, the question that started this thread was looking for a portable solution.

The goal, as I see it, is to be able to build a Flash/Flex UI to any RESTful service, whether it is new or existing, whether it is Java or .NET or PHP or Rails, and have your Flash/Flex client understand all of the standards-compliant messages that come from the server, whether they are HTTP 2xx or 4xx or 5xx.

#5 
Written By jimrobson on April 17th, 2009 @ 9:51 am

You can do exactly that! Just startup BlazeDS on a server (maybe even use stax.net to make it super easy) and then set your HTTPService to use that server as it’s proxy to the RESTful service of your choice. Then there is no need to change the RESTful service and you get non-200 HTTP responses.

-James

#6 
Written By James Ward on April 17th, 2009 @ 1:17 pm

@James,

I grant what you are saying, and it is great, no doubt about it. In fact, I am glad that you pointed it out. But it still requires something on a server somewhere - maybe not the same server that hosts the services you want to access, but it’s still a server - which means you have to be concerned about maintenance, scalability, etc. If you just want to build a client that accesses these services, without having to provide a server component, then you have to work around the lack of non-200 responses.

#7 
Written By jimrobson on April 17th, 2009 @ 8:59 pm

Yup. So here is a business idea… Create a proxy service in the cloud that anyone could use to proxy any RESTful API. :)

-James

#8 
Written By James Ward on April 18th, 2009 @ 1:25 pm

BTW: Here is a Flex bug where Matt Chotin (PM for Flex SDK) points out more details about the problem and it’s status:
http://bugs.adobe.com/jira/browse/SDK-11841

“This works today with Flash Player 10 and IE. Firefox 3.1 is expected to also expose the fix, and other browser vendors will eventually address their version of the [NPAPI] to support.”

-James

#9 
Written By James Ward on April 18th, 2009 @ 1:30 pm

One other solution would be to write your own RestfulHttpChannel/RestfulMessageResponder and tunnel your request through FABridge/XmlHttpRequest (remember to map 1223 -> 204/NoContent on the way back).

You can get this to work in a few days of what seems an unending cargo cult programming (be prepared for a few long debugging sessions of the existing channel framework code). However the poor documentation and no high level doc on how to properly implement a channel makes developing this solution in production quality rather challenging :(

#10 
Written By SebiF on May 1st, 2009 @ 11:57 am

@Sebif,

That’s an interesting approach. Thanks for sharing!

#11 
Written By jimrobson on May 1st, 2009 @ 12:47 pm
Next Post: I’m Back