You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by David Coleman <da...@hotmail.com> on 2012/04/25 16:47:00 UTC

HTTPService woes

Hi list,

I have a question.  Are there great differences between HTTPService for Apache Flex and the code for Adobe SDK 4.6?

I've run into a devil of a problem with it.  Apparently it simply swallows all headers and does not allow them to be sent to the server.  (in the past I've always used XML-RPC, AMF, etc, but now I'm trying to create a simple light-weight system of my own and I want to get an AsyncToken which URLLoader makes neigh impossible to manage).  I'm going to be patching the Adobe SDK version of HTTPService tonight (hopefully it's not too deep of a rabbit hole).  So when i'm done shaving my yak, is this something that the list might be interested in as an improvement to the sdk?

Or (perhaps) there is already some kind soul who has fixed this in Apache Flex?  Maybe i could patch my project w/the new code?

-Dave
 		 	   		  

RE: HTTPService woes

Posted by David Coleman <da...@hotmail.com>.
Oh yeah, i found it.

in the file:

mx.messaging.channels::DirectHTTPChannel.as at line 174:

    override protected function internalSend(msgResp:MessageResponder):void
    {
        var httpMsgResp:DirectHTTPMessageResponder = DirectHTTPMessageResponder(msgResp);
        var urlRequest:URLRequest;

        try
        {
            urlRequest = createURLRequest(httpMsgResp.message);
            // for some really strange reason, in THIS scope, the urlRequest object does not compile
            // if you try to access the manageCookies property.  Even in the FB IDE, it does not show
            // that property available.  HOWEVER; if you debug, the object DOES contain that property.
            // so I am casting down to an object which is dynamic, accessing the property, setting it to
            // false, which causes the flash player to NOT override the cookies and VIOLA!!!
            // Cookie enabled HTTPService calls.
            (urlRequest as Object).manageCookies = false;
            // end modification
        }
        catch(e: MessageSerializationError)
        {
            httpMsgResp.agent.fault(e.fault, httpMsgResp.message);
            return;
        }

        var urlLoader:URLLoader = httpMsgResp.urlLoader;
        urlLoader.addEventListener(ErrorEvent.ERROR, httpMsgResp.errorHandler);
        urlLoader.addEventListener(IOErrorEvent.IO_ERROR, httpMsgResp.errorHandler);
        urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, httpMsgResp.securityErrorHandler);
        urlLoader.addEventListener(Event.COMPLETE, httpMsgResp.completeHandler);
        urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpMsgResp.httpStatusHandler);
        urlLoader.load(urlRequest);
    }

I have tested it, using the following method:

    import mx.rpc.http.HTTPService;
    
    public class DebuggablePHPService extends EventDispatcher {
        public function DebuggablePHPService(target:IEventDispatcher=null) {
            super(target);
        }
        
        protected function configureZendServiceDebugCookies(service:HTTPService):void {
            service.headers = {
                Cookie: 
                    'start_debug=1'                                                 + ';' +
                    'debug_fastfile=1'                                              + ';' +
                    'ZendDebuggerCookie=192.168.2.3:10137:0||084|77742D65|88432508' + ';' +
//                    'debug_stop=1'                                                  + ';' +
                    'debug_coverage=1'                                              + ';' +
                    'use_remote=1'                                                  + ';' +
                    'send_sess_end=1'                                               + ';' +
                    'debug_session_id=27333395'                                     + ';' +
                    'debug_start_session=1'                                         + ';' +
                    'debug_port=10137'                                              + ';' +
                    'send_debug_header=1'                                           + ';' +
                    'debug_jit=1'                                                   + ';' +
                    'original_url='+ service.url                                    + ';' +
                    'debug_host=192.168.2.3,127.0.0.1'
            };
        }

I am using zend server community edition, and this works perfectly, causing my Zend IDE to launch in debug mode and stop at breakpoints in my php services.  Now I can work on extracting the session from the response to the httpService when i login and then i can come up with a way to create a static "session" that some extended HTTPSessionService can use to maintain a header based session with a server after an initial login.

Of course now I am compiling against an Adobe flex 4.6 sdk with the rpc.swc file removed in the compile config, and linking against a custom project made up of the rpc/src folder with the version.as files removed since a generic flex lib project complained about the file and didn't want to compile the lib... (I really just hacked it apart to get to the solution finding asap - i'm sure there were cleaner ways to modify the sdk).  I'd really like to try against the Apache Flex SDK, but frankly i'm in a 1 month rush development and don't have much time for experimenting (other than this session service layer which is critical).

Cheers Everyone!
Dave
 		 	   		  

RE: HTTPService woes

Posted by David Coleman <da...@hotmail.com>.
My most curious finding is that at the HTTPDirectChannel level, the URLRequest did not permit compilation of the manageCookies property which ultimately allowed the original headers to pass with no further modifications.  Why at this level does the URLRequest not contain compile when accessing a property which clearly exists in the class definition and even more clearly exists in the object instance itself when inspecting the variable in the debugger!?
 		 	   		  

Re: HTTPService woes

Posted by Jarosław Szczepankiewicz <js...@gmail.com>.
As far as I know, the limitation of using only GET / POST is from old
netscape plugin api, adobe cannot make more that api gives. Plugin api
does not allow passing something other that GET / POST. In our
application (flex with REST) we used tunneling by using POST with
custom headers, please take a look at:

X-HTTP-Method-Override

2012/4/26 Brett Adam <bp...@gmail.com>:
> Michael et. al:
>
> It's not just the player. There's definitely evildoing in the HTTPService classes as well.
>
> A long long time ago I became very unhappy with the HTTPService class and friends that constantly fought me at every turn.
>
> All I wanted was a nice, clean pathway to making RESTful calls from my Flex apps.
>
> Oh, but yes. I wanted headers. I wanted PUT and DELETE. I wanted my own content-types. I wanted things that (apparently) I should not want.
>
> GET's were being stripped of headers. GET requests of novel content types were turned into POST requests. POST requests with no body were turned back into GET requests. PUT and DELETE were turned into POST.
>
> Perversions abounded.
>
> I thought maybe it was just Flash Player in the browser that was living with constraints. But AIR was similarly damaged.
>
> After much workaround effort with nasty POST "tunneling" strategies inspired by the RoR community (?_method=GET !!!! ) I hacked my way into the bowels of the darn HTTPService layer and cobbled a monkey patch to force URLLoader to honor the originally requested method after all the other HTTPxxx classes had done their worst.
>
> I wrote a few posts back when…   http://verveguy.blogspot.com/2008/07/truth-about-flex-httpservice.html
>
> I've attached a slightly trimmed down set of files that implement my hack-around (removing unrelated stuff).  I note that this solves the method problem, but not necessarily the header issues.
>
> Since I trimmed them, I may have busted something compilation-wise. Sorry, but I don't have a clean way to test this independently at the moment.
>
> Let me know if this makes sense. The basic thrust is to ultimately insert a subclass of URLLoader way down deep in the call chain that puts the HTTP method *back* to whatever was originally requested after it's been willfully changed by the innards of Adobe's implementation.
>
> Yes, it would be much cleaner to fix this in the SDK. There's quite a lot of special case logic in the SDK classes that would need to be carefully unraveled and/or purged. Plenty of "oh, if this, then whack the method to be GET" and stuff that frankly, I can't see any good reason for these days. I'm *assuming* it was ancient browser limitations that led to what smells like legacy code.
>
> It would be almost fun to fix this properly in the SDK now that it's more open than before. Happy to help anyone game to take that on - with a first request that there be strong unit tests in place before we begin.
>
>
>
>
> -- Brett
>
>
> On Apr 25, 2012, at 3:43 PM, Michael A. Labriola wrote:
>
>>> I most certainly will, Justin.  This has been a dismaying experience to find that the flagship service class has such a glaring glitch.
>>
>> I fear that, when looking deeper, you may find it is the Flash Player and not the service class that is your root cause, but I would be very happy to be wrong.
>>
>> Mike
>>
>>
>
>

Re: HTTPService woes

Posted by Brett Adam <bp...@gmail.com>.
Michael et. al:

It's not just the player. There's definitely evildoing in the HTTPService classes as well.

A long long time ago I became very unhappy with the HTTPService class and friends that constantly fought me at every turn.

All I wanted was a nice, clean pathway to making RESTful calls from my Flex apps.

Oh, but yes. I wanted headers. I wanted PUT and DELETE. I wanted my own content-types. I wanted things that (apparently) I should not want.

GET's were being stripped of headers. GET requests of novel content types were turned into POST requests. POST requests with no body were turned back into GET requests. PUT and DELETE were turned into POST.

Perversions abounded.

I thought maybe it was just Flash Player in the browser that was living with constraints. But AIR was similarly damaged.

After much workaround effort with nasty POST "tunneling" strategies inspired by the RoR community (?_method=GET !!!! ) I hacked my way into the bowels of the darn HTTPService layer and cobbled a monkey patch to force URLLoader to honor the originally requested method after all the other HTTPxxx classes had done their worst.

I wrote a few posts back when…   http://verveguy.blogspot.com/2008/07/truth-about-flex-httpservice.html

I've attached a slightly trimmed down set of files that implement my hack-around (removing unrelated stuff).  I note that this solves the method problem, but not necessarily the header issues.

Since I trimmed them, I may have busted something compilation-wise. Sorry, but I don't have a clean way to test this independently at the moment.

Let me know if this makes sense. The basic thrust is to ultimately insert a subclass of URLLoader way down deep in the call chain that puts the HTTP method *back* to whatever was originally requested after it's been willfully changed by the innards of Adobe's implementation. 

Yes, it would be much cleaner to fix this in the SDK. There's quite a lot of special case logic in the SDK classes that would need to be carefully unraveled and/or purged. Plenty of "oh, if this, then whack the method to be GET" and stuff that frankly, I can't see any good reason for these days. I'm *assuming* it was ancient browser limitations that led to what smells like legacy code.

It would be almost fun to fix this properly in the SDK now that it's more open than before. Happy to help anyone game to take that on - with a first request that there be strong unit tests in place before we begin.


RE: HTTPService woes

Posted by "Michael A. Labriola" <la...@digitalprimates.net>.
>I most certainly will, Justin.  This has been a dismaying experience to find that the flagship service class has such a glaring glitch.

I fear that, when looking deeper, you may find it is the Flash Player and not the service class that is your root cause, but I would be very happy to be wrong.

Mike

 		 	   		  

RE: HTTPService woes

Posted by David Coleman <da...@hotmail.com>.
I most certainly will, Justin.  This has been a dismaying experience to find that the flagship service class has such a glaring glitch.
 		 	   		  

Re: HTTPService woes

Posted by Justin Mclean <ju...@classsoftware.com>.
Hi,

> I have a question.  Are there great differences between HTTPService for Apache Flex and the code for Adobe SDK 4.6?
There are no differences at the moment. So if you do come up with anything please share it here.

Thanks,
Justin

RE: HTTPService woes

Posted by David Coleman <da...@hotmail.com>.
No, I'm trying to establish a persistent session login using cookies from an AIR app to a CakePHP backend.  The AsyncToken is because I want to be able to create a service stack using an object as a hash map which stores the invocation parameters of the service call in a stack using the tokenID.

the idea is that I do 

FooService.getInstance().getSomeRelatedStuff(objThatStuffWillRelateTo:BlahObj,success:Function,failure:Function):AsyncToken {
...
var token:AsyncToken = service.send();
FooService.callStack[token.tokenID] = obj;
}

then when i get a response, i can use the asynctoken to go back to the service call stack and access the same data that I used to invoke the service which generated the result which I am processing...  In that way i don't have to search through a bunch of arrays to find the same object again, i just save the pointer to the data that I used to fire off the call and then do whatever i need with it.

But the darn HTTPService class is blasting all my attempts to use cookies, so i can't pass the session id's etc... to the php, which means that I can't use authentication only service calls, which is totally distasteful and insecure.

All of my googling indicates that this is a known and hated issue with HTTPService.  Any thoughts here?  I'm about to chase this one down and kill it with a prejudice if I can do so w/o wasting too much time.

-Dave
 		 	   		  

Re: HTTPService woes

Posted by Avinash Narayanan <av...@gmail.com>.
Hi David,

If this is something to do with file upload, I can help. What exactly are
you trying to do? I've used URLLoader but not with async tokens.

Thanks
Avinash Y


On Wed, Apr 25, 2012 at 8:17 PM, David Coleman <
david_coleman_007@hotmail.com> wrote:

>
> Hi list,
>
> I have a question.  Are there great differences between HTTPService for
> Apache Flex and the code for Adobe SDK 4.6?
>
> I've run into a devil of a problem with it.  Apparently it simply swallows
> all headers and does not allow them to be sent to the server.  (in the past
> I've always used XML-RPC, AMF, etc, but now I'm trying to create a simple
> light-weight system of my own and I want to get an AsyncToken which
> URLLoader makes neigh impossible to manage).  I'm going to be patching the
> Adobe SDK version of HTTPService tonight (hopefully it's not too deep of a
> rabbit hole).  So when i'm done shaving my yak, is this something that the
> list might be interested in as an improvement to the sdk?
>
> Or (perhaps) there is already some kind soul who has fixed this in Apache
> Flex?  Maybe i could patch my project w/the new code?
>
> -Dave
>