Tagged: HTTP

Easy Multipart file uploads / POSTs using URLStream or AS3HttpClientLib

When working on a cross runtime Zinc/AIR method method of posting files to a remote server, I came across Mike Stead’s URLFileVariable and URLRequestBuilder classes which makes the process of uploading multiple files (or ByteArray’s of data) via an HTTP POST much easier. Click here get his code

The basic concept is this: assuming you have one or more ByteArray’s of file data and the filenames to go with them, you prepare one or more URLFileVariable’s. The URLFIleVariable’s are added to the URLVariables as follows:

// create the standard "URLVariables"
var vars:URLVariables = new URLVariables(); 
// lets set a ByteArray of JPG data with the filename "myFile.jpg" against the POST variable "file1"
vars.file1 = new URLFileVariable(myByteArray, "myFIle.jpg");

Now at this point, as in my case, I am passing these URLVariables to either an AIR implementation of an HTTP client (using URLStream) or a Zinc implementation (using AS3HttpClientLib). This was all described here in another post.

In my AIR implementation of an HTTP client abstraction I use an URLStream and the code that deals with the URLVariables works something like the following.


/* Standard URLStream code that interacts with URLVariables
which contain Mike Stead's URLFIleVariables and uses his URLRequestBuilder */

var stream:URLStream = new URLStream();

// [ REGISTER for your stream listeners here...

/* use Mike Stead's URLRequestBuilder to properly build the 
URLRequest and encode it to contain all the multi-part data and filenames in the "vars" created above */
var req:URLRequest = new URLRequestBuilder(vars).build();

// ensure a POST because URLRequestBuilder only specifies POST if the variables contains files.
req.method = URLRequestMethod.POST; 

// define some URL to post to
req.url = "http://my.something.com.xyz/url_to_post_to.xyz";

// fire off the POST
stream.load(req);

// as the load completes, your event handlers for the stream should take over

Now on the other hand, if you happen to be using AS3HttpClientLib (as described in one of my other posts) you will be coding the equivalent of the URLStream code above, however using AS3HttpClientLib as follows. Here we do not use the URLRequestBuilder but simply manually retrieve the appropriate information from Mike’s URLFileVariable instance.

....

// our AS3HttpClientLib HttpClient
var client:HttpClient = new HttpClient();

...
// [Remember to setup your "client" event hooks as described in the AS3HttpClientLib docs here]

// create a new POST request
var postReq:HttpRequest = new Post();

// lets create an Array to hold all the different "parts" of this multipart post
var parts:Array = new Array();

/* lets push the URLFileVariable we created earlier into the parts Array 
according to how AS3HttpClientLib expects it, as a Part object. Here
we are simply creating a new Part and populating it with the data
that we defined up above when we created the URLFileVariable */

parts.push(new Part("file1",vars.file1.data, "application/octet-stream", [{name:"filename",value:vars.file1.name}]));

// create a multipart that points to the "parts" Array
var mp:Multipart = new Multipart(parts);
postReq.setMultipart(mp);
					
// create a URI
var uri:URI = new URI("http://my.something.com.xyz/url_to_post_to.xyz");	

// fire off the request
client.request(uri,postReq);

Thanks again to Mike Stead’s UrlFileVariable and URLRequestBuilder classes for helping me make an generic HTTP multipart post process easier and I hope my post will give those reading some help along the way on implementing their own.

Advanced HTTP operations in Flex outside of AIR

I am currently pretty deep into a Flex/AS3 RIA desktop app project whereby I have several advanced needs. Such as to download partial files to the desktop (byte-range requests), execute HEAD requests to get remote file sizes, execute multipart POSTs, talk to some REST apis, and finally be able to read any write HTTP headers….. outside of AIR? Good luck with URLStream, URLRequest, URLRequestMethod and URLRequestHeader

Due to security sandbox restrictions, unless your application is running within Adobe AIR you are restricted to simple GETs and POSTs. You are also NOT allowed to touch the following headers:

Accept-Charset, Accept-Encoding, Accept-Ranges, Age, Allow, Allowed, Authorization, Charge-To, Connect, Connection, Content-Length, Content-Location, Content-Range, Cookie, Date, Delete, ETag, Expect, Get, Head, Host, Keep-Alive, Last-Modified, Location, Max-Forwards, Options, Origin, Post, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, Public, Put, Range, Referer, Request-Range, Retry-After, Server, TE, Trace, Trailer, Transfer-Encoding, Upgrade, URI, User-Agent, Vary, Via, Warning, WWW-Authenticate, x-flash-version.

That’s basically all of the ones I needed to touch…..so what to do? In my case I was developing some file management functionality that runs in both Adobe AIR as well as MDM Zinc. Amongst other protocols such as FTP, I needed to be able to pull file updates over HTTP as well (+authentication, HEAD checks etc). So I had to create an generic IHttpClient interface abstraction which then allowed me to implement runtime specific clients. So for the AIR side of things I was good to go by using all of Adobe’s URL* classes right out of the box and they work great for the AirHttpClient implementation of my interface. However for my Zinc client I was still stuck, until I ran across a fantastic little HTTP library out there that provides a custom HTTP library built on top of the Flex socket stack.

The AS3 library that ended up being used in my ZincHttpClient was: as3httpclientlib. as3httpclientlib solved all of my problems when running outside of the AIR environment. With as3httpclientlib you can do all of the following and more:

* GET, HEAD, PUT, POST, DELETE
* multipart/form-data (PUT and POST)
* HTTPS support using AS3Crypto TLS
* Post with application/x-www-form-urlencoded
* Reading chunked (Transfer-Encoding)

If you have the need to access a bit more advanced HTTP functionality and need to do it outside of the AIR runtime. I HIGHLY recommend as3httpclientlib. I have put this library through the works doing byte range requests, HEAD requests, header manipulation and downloading and posting all sorts of file sizes, the library works great. My only note is that it is a tad slower than URLStream based HTTP downloads under Adobe AIR, regardless, this little HTTP library is worth it. Kudos to the AS3HttpClientLib team!