HTTP Authentication for HTTP/GET requests using ActionScript 3

I am working on ActionScript3 API for Bloglines services, which requires HTTP Authentication for its two of the services. I was not able to set the header of a HTTP/GET request. Macromedia Flash Player allows you set the header only for POST requests. I discussed this issues with Ted Patrick and he told me how I can us Socket to achieve the desired and he was very kind to give a me code-snippet, which got me started. Thanks Ted.

Finally, I could implement a class(HTTPURLLoader) which allows me to:

  • Add request-headers
  • Do HTTP Authentication for GET URLs
  • Handle HTTP status messages
  • Read the complete response header

It basically connects to a HTTP server on port 80(hardcoded for now) and sends an HTTP/1.0 request so that server closes the connection immediately after response. I could use HTTP/1.1 to keep connection alive and do things. But then closing connection would require some more logic, either a timeout logic if there is no activity on socket then close the connection, or find the end delimiter of response and then close. So I chose the easiest approach :)

I am still working on it and there is a lot(bugs-fixing, optimization, code-commenting, removing hardcoded stuff etc) to be done. I just wanted to share whatever I have done so far. I think, idea is more important than the implementation.
Anyways, I also implemented Base64 in AS3 and also OPML parser for Bloglines. I would soon upload the entire Bloglines AS3 API source.

Download the code:

Usage:-

<mx:Application xmlns:mx="http://www.macromedia.com/2005/mxml" creationComplete="onAppInit()">
<mx:Script>
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import com.abdulqabiz.net.HTTPURLLoader;
import com.abdulqabiz.crypto.Base64;
private var loader:HTTPURLLoader;
private var END_POINT:String = "http://rpc.bloglines.com/";
//you need to set your email/password required for Bloglines access.
private var email:String = "YOUR_EMAIL_FOR_BLOGLINES";
private var password:String = "YOUR_BLOGLINES_PASSWORD";
private function onAppInit()
{
loader = new HTTPURLLoader();
loader.addEventListener("complete", onComplete);
loader.addEventListener("httpStatus", onHTTPStatus);
loader.addEventListener("progress", onProgress);
//for simplicity,not handling following three events.
//loader.addEventListener("close", onClose);
//loader.addEventListener("ioError", onIOError);
//loader.addEventListener("securityError",onSecurityError);
}
private function onComplete(event:Event)
{
//headers stroed as name-value(hash map)
var rh:Object = HTTPURLLoader(event.target).responseHeaders;
var str:String = "";
for(var p:String in rh)    str+= p + ":" + rh[p] + "\n";
console.text+="Response Headers: \n" + str + "\n\n";
//data property holds the content
console.text+="Body Content:\n" + HTTPURLLoader(event.target).data + "\n\n";
}
private function onProgress(event:ProgressEvent)
{
//bytesTotal is not accurate, and its 0 if server doesn't send Content-Length header.
console.text+= "Event: progress:-\n" + "bytesLoaded: " + event.bytesLoaded + "\n\n";
}
private function onHTTPStatus(event:HTTPStatusEvent)
{
//if httpStatus is 401, 403, 404, 500, 501, socket is closed.
console.text+= "Event: httpStatus (" + event.status + ")\n\n";
}
private function loadURL()
{
var request:URLRequest = new URLRequest();
//call listsubs method of Bloglines
request.url = END_POINT + "listsubs";
var credentials:String = Base64.encode(email + ":" + password);
//create HTTP Auth request header
var authHeader:URLRequestHeader = new URLRequestHeader("Authorization","Basic " + credentials);
//add the header to request
request.requestHeaders.push(authHeader);
//make the request.
loader.load(request);
}
</mx:Script>
<mx:Button label="Load URL" click="loadURL()"/>
<mx:TextArea id="console" width="100%" height="100%"/>
</mx:Application>
  • marc

    nice work…. very useful….

  • venkatn

    i am trying to upload files using fielreference.upload(). how do i use basic authentication using as3 script i dont find Base64 in as3 api.

    i have gone through the livedocs help . its mentioned that with filereference , urlrequestheader does not work . is that true.

    i cant use u r example because i dont find api classes.

    abdul please help me

  • Ravi Shankar

    Hi,

    Excellent, I am new to FLEX n I am doing a project while learning. This example was really helped me as my situation required this solution.

    I need to access local filesystem using FLEX web application, could you help me out to solve this problem or any alternative solution will be appreciated. As I know FLEX (WEB) should not support filesystem access.

    Thanks a lot,
    Ravi Shankar

    • http://www.abdulqabiz.com/blog/ Abdul Qabiz

      Hi Ravi

      As far as I know, Flash Player 10 allows local file access (read-only). You can prompt user to browse a file and content of that can be read in actionscript. I don’t think, you can write to client machine without using any signed-code (applet, activex, javascript, etc).

    • Ravi Shankar

      Yes, I think you might be right. I know about flash.net.FileReference class and I have used earlier in my code.

      I have tried to use JScript but I am not an expert in that. I am planning to use Java/.Net code with Flex Remoting. If you don’t mind could you give me a sample on JScript which creates/deletes a file. This will really help to avoid the dependencies.

      Thanks,
      Ravi Shankar

    • http://www.abdulqabiz.com/blog/ Abdul Qabiz

      Hi Ravi

      As far as I know, Flash Player 10 allows local file access (read-only). You can prompt user to browse a file and content of that can be read in actionscript. I don’t think, you can write to client machine without using any signed-code (applet, activex, javascript, etc).

  • suprasannachoudhury

    I have always used ‘xmlns:mx=”http://www.adobe.com/2006/mxml” ‘ instead of

    ‘xmlns:mx=”http://www.macromedia.com/2005/mxml”‘ .And the later one doesnt produce a result also.. can you suggest ..
    And one more thing is , i ‘m not able to ship a weather webservice out side flex builder .Its giving ‘security error accessing url’ . Even i ahve added crossdomain policy file also

  • rajeswarimypati

    I am getting error while running the example. error is:

    Error #2044: Unhandled securityError:. text=Error #2048: Security sandbox violation: file://C:Documents and Settingsu21743My DocumentsFlex Builder 3HTTPURLLoader_V2bin-debugHTTURLLoader_Simple_Test.swf cannot load data from rpc.bloglines.com:80.
    Error #2044: Unhandled ioError:. text=Error #2031: Socket Error. URL: rpc.bloglines.com

    Please suggest me.

  • http://www.motionsensorcamera.info Motion Sensor Camera

    that’s really useful

  • Malvakian

    Its works !!!
    I need change only this :
    var credentials:String = Base64.encode(email + “:” + password);

    TO ->

    var encoder : Base64Encoder = new mx.utils.Base64Encoder();
    encoder.insertNewLines = false;
    encoder.encode(email + “:” + password);

    var credentials:String = encoder.toString();

  • http://www.flyruby.com Fly Ruby

    That happens to be a particularly interesting and targeted piece of writing. Though my opinion may differ from that of the writer, I know that that is great webpage. I will certainly join Feed for this fantastic and distinctive blog website.

  • http://www.bronzependantlights.net/designer-pendant-lights designer pendant lights

    Thanks
    for information, I’ll always keep updated here!
     

  • http://www.facebook.com/nuwaus Nuwan Pradeep

    Great, thanks you!

  • wuiyang

    i want to use custom headers like (“X-HEADER-1″, “123456789″), (“X-HEADER-2″, “abcdefghi”), so i change

    var authHeader:URLRequestHeader = new URLRequestHeader(“Authorization”,”Basic ” + credentials);
    to
    var authHeader:URLRequestHeader = new URLRequestHeader(“X-HEADER-1″,”123456789″);
    var authHeader:URLRequestHeader = new URLRequestHeader(“X-HEADER-2″,”abcdefghi”);?

  • http://www.abdulqabiz.com Abdul Qabiz

    Flash Player has some security sandbox restrictions, which doesn’t allow you to connect to any arbitrary port. If you want to connect ports lower than 1024, you need to have a socket-policy-file. Unfortunately, bloglines doesn’t have that, hence connecting to rpc.bloglines.com:80 would not work.

    Socket Policy Documentations:-

    http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security_04.html
    http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html

    This was one of the reasons, I didn’t release my bloglines actionscript library, which was the main reason for creating HTTPURLLoader (as3httpclient – http://code.google.com/p/as3httpclient).