views:

3968

answers:

2

We currently have a Java applet that generates a lot of data and uploads it to our servers. One of the upload methods we have is to use an HTTP POST to our server, the contents of which are just the raw data (no multipart encoding or anything).

I'm looking at implementing a Flex app that does the same thing, but I don't see a way to duplicate that network behavior. All the HTTP-related network classes in Flex seem to work under the assumption that you're simply making a request. I don't see a way to actually set the payload of the POST (other than setting a couple query parameters, which wouldn't work here).

What I'd really like is to be able to initiate an HTTP POST, but then be able to write to the connection like I would a socket. Is this possible without having to write my own HTTP implementation on top of the Socket class? Is there any way to set the payload of an HTTP POST within Flex?

Clarification: Being able to create a data buffer and send that to the server is sufficient (which it looks like is possible). It would be better if I could treat the connection as a socket and send data to it over time, instead of all at once, but that isn't strictly required.

+1  A: 

It sounds like you're sort of asking two questions. Yes, there is a way to set the payload of an HTTP POST within Flex, and to upload files of any format to your server:

private function doPost():void
{
    var yourData:ByteArray = new ByteArray();
    var encoder:Base64Encoder = new Base64Encoder();

    for (var i:int = 0; i < 10000; i++)
     yourData.writeByte(i);

    yourData.position = 0;
    encoder.encodeBytes(yourData);

    var req:URLRequest = new URLRequest("http://yourdomain.com/yourservice.ext");
    req.method = URLRequestMethod.POST;

    var postData:URLVariables = new URLVariables();
    postData.userData = encoder.flush();

    req.data = postData;

    var loader:URLLoader = new URLLoader();
    loader.dataFormat = URLLoaderDataFormat.BINARY;
    loader.addEventListener(Event.COMPLETE, loader_complete);
    loader.load(req);
}

private function loader_complete(event:Event):void
{
    trace("Upload complete!");
}

... but it also sounds like you want to connect, keep the connection open and then write to it arbitrarily "like a socket"; if that's the case, then other than using the Socket classes for that purpose, I don't believe there's a built-in mechanism, no. Hope it helps nonetheless!

Christian Nunciato
I looked at the URLRequest documentation. What's the gain in using URLVariables? The docs seem to suggest you could just do req.data = yourData and it would work. What's the difference?
Herms
Depends on how you'll be reading the posted data. Above, I'm just assuming the usual scenario, wherein some page receives the bytes by name (e.g., Request.Form["userData"], etc.); URLVariables just makes that easier. But I don't think it's required, no -- I've just always used it for that purpose.
Christian Nunciato
No names. It's treated as a raw data stream. So if I'm understanding correctly, I'd need to set the data to be the byte array directly and not use URLVariables, right?
Herms
That's right. Check out the docs -- the URLLoader.data property specifically: "The URLRequest API offers binary POST support [....] If the object is a ByteArray object, the binary data of the ByteArray object is used as POST data." It ought to work out fine for you.
Christian Nunciato
A: 

I think this does not work anymore because of some security issues implemented in Flash Player 10.

Ionel