17 Replies Latest reply on Feb 28, 2011 9:21 AM by BenjaminBelgium

    HTTPService : POST Data + Octet-stream?

    BenjaminBelgium

                           Hi everyone,

       

                      I’m stuck since quite a long time on a problem, looking here and there on forums after a solution but still fragmentary..

                     If you allow me, I’d like to expose it to you people :

       

       

                     My Flex (sdk 3.5) project record a sound and then must send it to a web page. The equivalent in term of form should be exactly like :

            <form method="post" action="http://www.myDomain.be/myFile.php" enctype="multipart/form-data">

                 <table>                                                              

                     <tr><td>data:</td><td><input type="file" name="data"/></td></tr>

                     <tr><td>audioSamplingRate:</td><td><input type="text" name="audioSamplingRate" value="22050"/></td></tr>

                     <tr><td>audioBigEndian:</td><td><input type="text" name="audioBigEndian" value="false"/></td></tr>

                  </table>

               <input type="submit"/>

            </form>

       

                      I try to find the exact equivalent in flex, using HTTPService, or URLLoader, etc… But I don’t manage to do this simple thing : Send my byteArray (as a .RAW file) to the web page along with classic post datas like the above form would send.

                      FWI, I have managed to send the byteArray thanks to a “application/octet-stream” content-type but not to send regular POST data at the same time (GET is working, but shouldn’t be used).

                      I would be infinitely grateful is someone could set me on the right path to the answer

       

      Ps : Sorry for my English, French is my mother language.

        • 1. Re: HTTPService : POST Data + Octet-stream?
          dave cragg Level 2

          Have you looked at the FileReference class for doing this? Its upload() method will send data using multipart/form-data method.

           

          I think you will need to save your audio data to a local file to get this to work. (Look at FileReference.save(). I'm not sure if this works with SDK 3.5. It works with 4.x. The ability to save files locally came with FlashPlayer 10.0)

           

          Any other parameters (e.g audioSamplingRate)  can probably be set on the URLRequest that is used with the upload() method.

           

          (I've not done this before with Flex. So no guarantees.)

          1 person found this helpful
          • 2. Re: HTTPService : POST Data + Octet-stream?
            BenjaminBelgium Level 1

            Thanks a lot for the very fast answer !

             

            In fact, I was hoping that I could avoid this manipulation. I was also hoping to start sending slices of the bytearray while recording (to save time for the user). But I suppose there is no way to combine multipart/form-data with application/octet-stream ? (Many people actually says that)

             

            Anyway, I'm working on a solution to test your idea about fileReference. I will come back with the outcome.

             

             

            [EDIT : 16h47] Don't seems to be easy. fileReference.upload() could be working for a file on my client computer. But this should be transparent for the user. And with fileReference, it seems that he will be prompt to save the file, and prompt again to select it for upload. Maybe someone knows a way of inserting the bytearray in a fileReference and upload it without having the prompt ??  Thanks in advance!   [/EDIT]

            • 3. Re: HTTPService : POST Data + Octet-stream?
              injpix Level 3

              You may want to look into Sockets.  Typically sockets are used to transmit chucks of data to and from the server, binary (eg. ByteArray) or plain-text.  I am not completely familiar using Sockets, but I am currently using them to transmitt data by a POST method.  The Socket libarary that I am using is as3httpclientlib.  They do have an examples page here.  With this libaray, you can send mulitpart/form data.  Perhaps that feature will help you.

               

              If you do use sockets, beware of your socket-policy file (aka, cross-domain file).  I believe you do need to open up a port.  You can read the details here.

              1 person found this helpful
              • 4. Re: HTTPService : POST Data + Octet-stream?
                BenjaminBelgium Level 1

                Thanks you! seeing the examples, I effectively seems that its what I need.

                But there is realy somethings I don't anderstand about compiling libraries because I can't get these kind of project working, I always have missing classes... (I'm not an actual development professional)

                Here, He's missing the FileStream Class, but it's written AIR only, and In the readme (" this library might be more suited for AIR apps.")

                 

                So I don't know if I will reach an happy end with this Or maybe am I Wrong?

                • 5. Re: HTTPService : POST Data + Octet-stream?
                  injpix Level 3

                  I am not a Ruby developer, so I forgot how I successfully built it.  Hopefully this semi-retarded-forum will allow me to attach the SWC file that I compiled on Jan 5, 2011.

                   

                  That comment that you came across, was refering to opening that port I mentioned previously.  Port 843 needs to be opened for Adobe Flash Player.  Adobe AIR applications will access this port regardless of the port listed in the socket-policy file.

                   

                  ps.  it seems that I cannot attached files.  if you send me a message with your email address thru this forum, i will reply back to you with the attached file.

                  • 6. Re: HTTPService : POST Data + Octet-stream?
                    injpix Level 3

                    Well to build it, it seems that you would just use the compc in the command line.  The rake command seems to be just for their testing. So the following command work as it is mentioned in the README.md file.

                     

                    compc -load-config=build-swc.xml

                     

                    But, you may need to edit the build-swc.xml so that the first node pointing to the playerglobal.swc has the correct Flash Player version.  For instance it was following:

                    <path-element>${flexlib}/libs/player/10/playerglobal.swc</path-element>

                     

                    ...then I had to change it to this:

                     

                    <path-element>${flexlib}/libs/player/10.1/playerglobal.swc</path-element>

                    • 7. Re: HTTPService : POST Data + Octet-stream?
                      BenjaminBelgium Level 1

                      Sorry if I'm little slow to understand :s

                      The basis are lacking in my knowledge of Flex Builder 3 ..

                       

                      So far, I have tried to copy-paste the content of the as3httpClient Librairy in a new 'Flex Library Project'.

                      I have tried to enter 'compc -load-config=build-swc.xml' in the compiler argument, but I didn't manage so far, he still tell me that the FileStream base class is missing (And I was thinking that it wasn't so suprising since it's writtent on the adobe documentation that this class is for AIR only)

                      But I certainly doing something very wrong

                      (Gosh I hate to be a novice in these kind of stuff ^^ )

                       

                      Or I'm exectuting the compc -load-config=build-swc.xml command at the wrong place ?

                       

                      Also, you lost me when talking of the <path-element>${flexlib}/libs/player/10/playerglobal.swc</path-element >.  Where can I find the folder resprésented by "${flexlib}" to check for the right file ? (Or have I understand wrong again ? )

                       

                      Thanks you again for your help anyway !!

                      • 8. Re: HTTPService : POST Data + Octet-stream?
                        injpix Level 3

                        The compc for that purpose may only be used in Terminal/ Bash or command-line.  But in order to use it, you will need to set a system environment variable pointing to your Flex SDK (aka. FLEX_HOME).  On a Mac I have the following in my .bash_profile file:

                         

                        export FLEX_HOME=/Applications/Adobe\ Flash\ Builder\ 4/sdks/4.1.0.16248
                        export PATH=$PATH:/opt/local/bin:$FLEX_HOME/bin

                         

                        .bash_profile file is located in the Home directory (/Users/<YOUR COMPUTER NAME>/.bash_profile).  The second line will allow me access to all of the Flex compilers at any location I am at in command-line.  Therefore I can use the compc from command-line.

                         

                        The <path-element> needed to be changed for my setup because I have the following path to playerglobal.swc:

                        /Applications/Adobe\ Flash\ Builder\ 4/sdks/4.1.0.16248/libs/player/10.1/playerglobal.swc

                         

                        ...and *not* what it was expecting:

                         

                        /Applications/Adobe\ Flash\ Builder\ 4/sdks/4.1.0.16248/libs/player/10/playerglobal.swc

                        • 9. Re: HTTPService : POST Data + Octet-stream?
                          BenjaminBelgium Level 1

                          Thanks a lot² for the builded library by email!!!!

                           

                          I feel that it's nearly okay,

                          Just one last very little problem : The script from the multipart exemple of httpClient use 'S3PostOptions' class and he don't find it. I've google for it and added S3PostOptions.as, and added the import, but he still tells me : 'Type was not found or was not a compile-time constant: S3PostOptions'.

                           

                          (Again a very 'Noob' question, sorry :-/ )

                          • 10. Re: HTTPService : POST Data + Octet-stream?
                            Darrell Loverin Level 4

                            When you use the -load-config option you typically use "+=" instead of "=" so that you append to "flex-config.xml" instead of replace it.

                             

                            Try

                            compc -load-config+=build-swc.xml

                             

                             

                            -Darrell

                            • 11. Re: HTTPService : POST Data + Octet-stream?
                              injpix Level 3

                              Those classes are for Amazon S3(Simple Storage Service).

                               

                              Here is an example I came across using as3httpclient for a multipart POST.

                               

                              Update:  And here is an updated link which that article mentions.

                              • 12. Re: HTTPService : POST Data + Octet-stream?
                                BenjaminBelgium Level 1

                                I have tried the article (blog.mikestead), and it seems to work fine !!!!!!!!!!!!

                                Some remaining problems are about audio encodage (it seems) but transmitions is ok!

                                 

                                Thanks a lot !!!! It's such a long time that I'm searching after this solution !

                                 

                                (If I have updates, I will post here. And I will maybe write an article to translate this solution in french, for the french speaking AS community on my blog )

                                • 13. Re: HTTPService : POST Data + Octet-stream?
                                  injpix Level 3

                                  I am glad to hear that you found a solution!  So you can use Mike Stead's code instead of as3httpclient for single multipart POSTs?  Or do you need them both?

                                   

                                  I am not to familiar with audio encoding, but I did come across this web page yesterday when I was trying to find an article for POST methods in Flex.  Listed under the 'Audio Libraries' section of this webpage, are some audio encoders that may help you.

                                   

                                  Yeah, that would be good to translate this info we gathered into your blog.

                                   

                                  ps.  right before I was going to post this very message, I searched for something related online and came across this project.  damn, there is alot of resources out there.  very generous people.

                                  • 14. Re: HTTPService : POST Data + Octet-stream?
                                    dave cragg Level 2

                                    Also glad you found a solution.

                                     

                                    In case it's of any use, I tried a multipart/form-data using URLLoader. I got it to work with a simple example. (Code below). The idea is to set the Content-type of the URLRequest to "multipart/form-data" plus the appropriate part boundary. Then build the data as a ByteArray, adding the appropriate boundary markers and other stuff. In this example, there are three parts. The first two are normal (not file data) parameters named myParam1 and myParam2. The third part is the "file data" named myFile (in this case a simple text file, but using application/octet-stream).

                                     

                                      private const CRLF:String = String.fromCharCode(13) + String.fromCharCode(10);

                                          private const QUOTE:String = String.fromCharCode(34);

                                     

                                          private function fileUpload():void

                                          {

                                            var boundary:String = formBoundary();

                                     

                                            var contentTypeHeader:String = "multipart/form-data; boundary=" + QUOTE +  boundary + QUOTE;

                                     

                                            var partBoundary:String = "--" + boundary;

                                     

                                            var formData:ByteArray = new ByteArray();

                                     

                                     

                                            //first param

                                            formData.writeUTFBytes(partBoundary + CRLF);

                                     

                                            formData.writeUTFBytes("Content-Disposition: form-data; name=" + QUOTE + "myParam1" + QUOTE);

                                            formData.writeUTFBytes(CRLF + CRLF);

                                            formData.writeUTFBytes("myValue1");

                                            formData.writeUTFBytes(CRLF);

                                     

                                            //second param

                                            formData.writeUTFBytes(partBoundary + CRLF);

                                     

                                            formData.writeUTFBytes("Content-Disposition: form-data; name=" + QUOTE + "myParam2" + QUOTE);

                                            formData.writeUTFBytes(CRLF + CRLF);

                                            formData.writeUTFBytes("myValue2");

                                            formData.writeUTFBytes(CRLF);

                                     

                                            //file parameter

                                            formData.writeUTFBytes(partBoundary + CRLF);

                                     

                                            formData.writeUTFBytes("Content-Disposition: form-data; name=" + QUOTE + "myFile" + QUOTE);

                                            formData.writeUTFBytes("; filename=" + QUOTE + "myTextFile.txt" + QUOTE );

                                            formData.writeUTFBytes(CRLF + "Content-Type: application/octet-stream");

                                            formData.writeUTFBytes(CRLF + CRLF);

                                            formData.writeUTFBytes("This is the contents of my text file.");

                                            formData.writeUTFBytes(CRLF);

                                     

                                            //closing boundary

                                            formData.writeUTFBytes(partBoundary + "--");

                                     

                                     

                                            var ur:URLRequest = new URLRequest();

                                            ur.url =  "http://localhost/php/flexMultipart.php";

                                            ur.data = formData;

                                            ur.method = URLRequestMethod.POST;

                                            ur.contentType = contentTypeHeader;

                                     

                                            var loader:URLLoader = new URLLoader();

                                            loader.addEventListener(Event.COMPLETE,loadHandler);

                                            loader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);

                                     

                                            try

                                            {

                                              loader.load(ur);

                                            }

                                            catch (error:Error)

                                            {

                                              trace("error");

                                            }

                                     

                                     

                                          }

                                     

                                          private function loadHandler(e:Event):void

                                          {

                                            //whatever

                                          }

                                     

                                          private function ioErrorHandler(e:IOErrorEvent):void

                                          {

                                            //whatever

                                          }

                                     

                                          private function formBoundary():String

                                          {

                                            var chars:String = "1234567890abcdefghijklmnopqrstuvwxyz";

                                            var boundaryString:String = "";

                                     

                                            for (var k:int = 0; k < 25; k++)

                                            {

                                              boundaryString += chars.charAt(Math.round(Math.random() * 35));

                                            }

                                     

                                            return "__Part__" + boundaryString;

                                          }

                                    • 15. Re: HTTPService : POST Data + Octet-stream?
                                      BenjaminBelgium Level 1

                                      @injpix : Thanks, I will surely look at that.

                                       

                                      I've used the Mike Stead's code like this :

                                       

                                       

                                      public function sendMultiPart(ba:ByteArray):void

                                      {

                                      var variables:URLVariables = new URLVariables();

                                           variables.data = new URLFileVariable(ba, "temp.raw");

                                           variables.isLast = "true";

                                           variables.packetNum = "0";

                                           variables.audioSamplingRate = "22050";

                                       

                                          

                                          

                                           // Build the multipart encoded request and set the url of where to send it

                                           var request:URLRequest = new URLRequestBuilder(variables).build();

                                           request.url = "http://myurl.be/jsppage.do";

                                       

                                          

                                           // Create the loader and transmit the request

                                           var loader:URLLoader = new URLLoader();

                                           loader.addEventListener(Event.COMPLETE, onServerResponse);

                                           loader.addEventListener(IOErrorEvent.IO_ERROR, onServerError);

                                           loader.load(request);

                                       

                                          

                                           // Handle the response

                                           function onServerResponse(event:Event):void

                                           {

                                            var loader:URLLoader = URLLoader(event.target);

                                            trace(loader.data);

                                           }

                                       

                                       

                                      function onServerError(event:IOErrorEvent):void

                                           {

                                            trace("onServerResponse: " + event.target.data);

                                           }

                                       

                                          

                                       

                                      }

                                       

                                       

                                      It seems to work fine (We'll see of this works at 100% when I managed to get my wave audible )

                                       

                                       

                                      @dave craqq :

                                       

                                      I have seen once something like this. Now that you show me a full example, it's seems understandable. But to create it ! What the h**l of a job ^^, Congrat's.

                                      I could put this kind of code in my French article as well (if you allow me ).

                                       

                                       

                                      Anyway, my project will be over in due time, and it's thanks to you all, so again, thanks a lot!!!!

                                      I'll try to find soon the time to write all this and post it, I'll come back to told you if everything is working fine.

                                      • 16. Re: HTTPService : POST Data + Octet-stream?
                                        dave cragg Level 2

                                        Benjamin

                                         

                                        Feel free. My code is fairly crude procedural script to illustrate the process. (It was actually a translation of the same procedure done in another programming environment.) But I'm pretty sure Mike Stead's code is a more elegant and re-usable implementation of something similar.

                                        • 17. Re: HTTPService : POST Data + Octet-stream?
                                          BenjaminBelgium Level 1

                                          Well, unfortunatly, I'm back in the POST Mather :

                                           

                                          I'm now facing a security issue of type :

                                          SecurityError: Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse click or button press.

                                          I have found on this page, that I have to ask for a user interaction in order to call the method that post my recorded byteArray (because send as a file).

                                           

                                          People on the internet find workaround by adding Alert message with button, and so on. But I must automatically send my recorded file at the end of the recording. (Without any user interaction, juste a timer that count a number of second of max recording time).

                                           

                                          Eventualy, haven't you got any idea, either to generate fake user interaction (and I assume it's impossible, or it would be a security breach) or to avoid this security issue?

                                           

                                          Thanks you again in advance