6 Replies Latest reply on Aug 26, 2006 8:24 AM by Matlus

    HTTPService headers

      it seems that the HTTPService screws up the headers if the XML is formatted in a certain way.


      public class Transactor extends HTTPService
      public function Transactor(rootURL:String){

      public function transact(request:XML):void{
      this.method = "POST";
      this.requestTimeout = 30;
      this.resultFormat = HTTPService.RESULT_FORMAT_E4X;
      this.contentType = HTTPService.CONTENT_TYPE_XML;
      this.url = _location;
      this.makeObjectsBindable = true;
      this.addEventListener(ResultEvent.RESULT, this.onResult, false, 1000);
      this.addEventListener(FaultEvent.FAULT, this.onFault, false, 1000);

      var xml:XML =
      <SERVICE request_type="getMerchantDetails"

      // the above code is supposed to send as POST but it sends as GET??????

      // even stranger! when I cahnge the XML to the example below, it will then send as POST!

      EX 2:
      var xml:XML =
      <SERVICE request_type="getMerchantDetails"
      <EMPTY />

      // notice the only change is the addition of the "EMPTY" tag!

      // IS THIS A BUG?
        • 1. Re: HTTPService headers
          ntsiii Level 3
          You can't use binding braces in AS.

          I am surprised it compiles.

          • 2. Re: HTTPService headers
            adams_chad Level 1
            the braces are not "AS binding" braces but e4x braces. this poplates the xml with dynamic variables, so yes it will compile and work perfectly, just like it currently is.
            • 3. Re: HTTPService headers

              The Flex team is aware of this issue. I had logged this as a bug about a month ago. The issue is really that the HttpService's send() method accepts one of two things:
              1. A dynamic object (and not a typed object)
              2. An xml document.

              At this moment I'm not sure if they're going to address this issue (and a few others I had logged) and if so when. In your case I gues the <EMPTY/> affects the resulting xml (making it a valid xml document and not just a node) that is being sent across and it then complies with what the HttpService object is willing to accept.

              Don't know if you've got there yet, but another issue to be aware of is that the various http related sockets available in Flex (such as HttpService, URLLoader, Loader etc.) can't handle a status code of 500 at the time of a response (typically an error/Exception on the server). This issue is really a limitation of the Flash Player which is in turn bound the limitation some browsers impose on it and so is not really the Flex or Player team's fault and therefore not much they can do about it.

              Here is the issue:
              When the server side responds with a status code of 500 you are not able to get at the "content" (the Http content part) and so you can't really tell what the error was on the server. The various http based sockets on the Flex side do raise the "error" event, so you know there was an error, but you don't know what it is.

              They way this is handled in FDS (Java only) is that their server side framework traps all exceptions, changes the status back to 200 (with a marker of sorts so the client side framework can route the response down the error path.

              I'm using ASP.NET for my server side and so I followed a similar path. On the client side all requests have an addtional header that indicates to the server side that all exceptions must be sent back as status code 200 with a marker and not status code 500s. An Http Module takes care of all the processing. In my case it was a bit complex only because the same service handles, Win32 GUI front-ends, Web browser front ends and now Flex front Ends and each of them have nuances when it comes to displaying exceptions. Of course the Flex side is really the odd ball.

              Hope this info helps.


              • 4. Re: HTTPService headers
                Matlus Level 1
                Just a suggestion...

                I wouldn't extend the HttpService, I'd aggregate it. Further, I'd use a factory method that returns an instance of an object that implements a certain interface (that has the socket level methods you require). This will provide a higher level of decoupling between you primary class and the "socket" it needs to go across the wire.
                • 5. Re: HTTPService headers
                  adams_chad Level 1
                  This sounds interesting, but I'm not quite understanding how this would help. Do you have an example of what your suggesting?
                  • 6. Re: HTTPService headers
                    Matlus Level 1

                    The "suggestion" does not help the issue of the HTTP POST getting converted to GET. It was more about the following:

                    1. It is more a design thing. The primary questions are "is a" versus "has a". My transaction controller "is a " HttpService or my transaction controller "has a" http Service. Since it "is a" transaction controller, "it is NOT" an HttpService. It uses an HttpService (or something that allows it to go remote). Therefore I suggested that your class should not extend the HttpService but rather aggregate it (it "has a" HttpService).

                    2. The second point was about decoupling. In this case you have (today) an HttpService that has some nuances. You don't want these nuances manifesting themselves in "your code". The "code" is about a transaction controller (and not an HttpService). So in such situations, you want to decouple "your code" from the HttpService part of your code. Using a factory method will allow you to decouple the instantiation of (today) and HttpService from your code, allowing decendants of your class to instantiate their own instance of whatever class that replaces HttpService.

                    3. Using an interface further decouples you from class heirarchy. Meaning, tomorrow, you could have an HttpService like object that doesn't have the same ancestry as the current HttpService (take the case of UrlLoader and HttpService today). As a result you'll have to change your class to now work with this new HttpService. On the other hand, today, you could define your own interface with methods you know you need for your transaction controller to go remote. These are a fixed set of methods and your transaction controller doesn't (or shouldn't) care "how" the remote calls are happening or what protocol is being used. Then you define a class that implements these methods by aggregating the HttpService class.

                    So in other words, you might have the following classes/Interfaces:
                    1. TransactionController
                    2. ITransactionControllerRemoteProxy
                    3. TransactionControllerHttpProxy (the class the implements the ITransactionControllerRemoteProxy internally aggregating HttpService).

                    I hope that make things clearer?