Skip to content

Instantly share code, notes, and snippets.

@abdul
Last active August 29, 2015 14:16
Show Gist options
  • Save abdul/3152e2af038cfc391ce9 to your computer and use it in GitHub Desktop.
Save abdul/3152e2af038cfc391ce9 to your computer and use it in GitHub Desktop.
/**
* @class Base64
* @author Abdul Qabiz (http://www.abdulqabiz.com)
* @version 1.0
* @requires ActionScript 3.0 and Flash Player 8.5 (atleast)
*
* @credits Based on Aardwulf Systems'(www.aardwulf.com) Javascript implementation.
* (http://www.aardwulf.com/tutor/base64/base64.html)
*
**/
package com.abdulqabiz.crypto
{
public class Base64
{
private static const KEY_STR:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
//Base64:encode(..) encodes a string to a base64 string
public static function encode(input:String):String
{
var output:String = "";
var chr1:uint, chr2:uint, chr3:uint;
var enc1:uint, enc2:uint, enc3:uint, enc4:uint;
var i:uint = 0;
var length:uint = input.length;
do{
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2))
{
enc3 = enc4 = 64;
}
else if (isNaN(chr3))
{
enc4 = 64;
}
output+= KEY_STR.charAt(enc1) + KEY_STR.charAt(enc2) + KEY_STR.charAt(enc3) + KEY_STR.charAt(enc4);
}while (i < length);
return output;
}
//Base64:decode(..) decodes a base64 string
public static function decode(input:String):String
{
var output:String = "";
var chr1:uint, chr2:uint, chr3:uint;
var enc1:int, enc2:int, enc3:int, enc4:int;
var i:uint = 0;
var length:uint = input.length;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test:RegExp = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input))
{
throw new Error("There were invalid base64 characters in the input text.\n" +
"Valid base64 characters are A-Z, a-z, 0-9, '+', '/', and '='\n" +
"Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do{
enc1 = input.indexOf(input.charAt(i++));
enc2 = input.indexOf(input.charAt(i++));
enc3 = input.indexOf(input.charAt(i++));
enc4 = input.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output+= String.fromCharCode(chr1);
if (enc3 != 64)
{
output+= String.fromCharCode(chr2);
}
if (enc4 != 64)
{
output+= String.fromCharCode(chr3);
}
}while(i < length);
return output;
}
}
}
/**
_________________________________________________________________________________________________________________
HTTPURLLoader is small http client for GET requests and header manipulation.
@class HTTPURLLoader (public)
@author Abdul Qabiz (mail at abdulqabiz dot com)
@version 1.01 (3/5/2007)
@availability 9.0+
@usage<code>new HTTPURLLoader ();</code>
@example
<code>
httpURLLoader = new HTTPURLLoader ();
</code>
__________________________________________________________________________________________________________________
*/
package com.abdulqabiz.net
{
import flash.net.*;
import flash.events.*;
import flash.system.Security;
import flash.errors.EOFError;
import flash.utils.*;
import mx.utils.StringUtil;
dynamic public class HTTPURLLoader extends EventDispatcher
{
//Events
[Event(name="close", type="flash.events.Event.CLOSE")]
[Event(name="complete", type="flash.events.Event.COMPLETE")]
[Event(name="open", type="flash.events.Event.CONNECT")]
[Event(name="ioError", type="flash.events.IOErrorEvent.IO_ERROR")]
[Event(name="securityError", type="flash.events.SecurityErrorEvent.SECURITY_ERROR")]
[Event(name="progress", type="flash.events.ProgressEvent.PROGRESS")]
[Event(name="httpStatus", type="flash.events.HTTPStatusEvent.HTTP_STATUS")]
//class attributes
private var _httpPort:uint = 80;
private var socket:Socket;
private var _request:URLRequest;
public var _httpRequest:String;
public var _httpServer:String;
private var headerComplete:Boolean = false;
private var _header:Object;
private var _data:String = "";
private var _bytesLoaded:int = 0;
private var _bytesTotal:int = 0;
private var headerTmp:String = "";
private var _httpVersion:Number;
private var _httpStatusCode:int;
private var _httpStatusText:String;
public function HTTPURLLoader(request:URLRequest = null)
{
//doesn't really need it here, as load(..) requires request
_request = request;
// create http-socket
socket = new Socket();
//subscribe to events
socket.addEventListener( "connect" , onConnectEvent , false , 0 );
socket.addEventListener( "close" , onCloseEvent , false, 0 );
socket.addEventListener( "ioError" , onIOErrorEvent , false, 0 );
socket.addEventListener( "securityError" , onSecurityErrorEvent , false, 0 );
socket.addEventListener( "socketData" , onSocketDataEvent , false , 0 );
}
/*__________________________________________________________________________________________________________________
Public Methods
__________________________________________________________________________________________________________________
*/
public function load(request:URLRequest):void
{
_request = request;
if(parseURL())
{
try
{
socket.connect(_httpServer, _httpPort);
}
catch (e:Error)
{
}
}
else
{
throw new Error("Invalid URL");
}
}
public function close():void
{
if(socket.connected)
{
socket.close();
dispatchEvent(new Event(Event.CLOSE));
}
}
/*__________________________________________________________________________________________________________________
Public Properties
__________________________________________________________________________________________________________________
*/
public function get data():String
{
return _data;
}
public function get header():Object
{
return _header;
}
public function get bytesLoaded():int
{
return _bytesLoaded;
}
public function get bytesTotal ():int
{
return _bytesTotal;
}
/*__________________________________________________________________________________________________________________
Private Methods
__________________________________________________________________________________________________________________
*/
private function onConnectEvent(event:Event):void
{
sendHeaders();
dispatchEvent(new Event(Event.CONNECT));
}
private function onCloseEvent(event:Event):void
{
dispatchEvent(new Event(flash.events.Event.COMPLETE));
}
private function onIOErrorEvent(event:IOErrorEvent):void
{
dispatchEvent(event);
}
private function onSecurityErrorEvent(event:SecurityErrorEvent):void
{
dispatchEvent(event.clone());
}
private function onSocketDataEvent(event:ProgressEvent):void
{
_bytesLoaded += socket.bytesAvailable;
dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, _bytesLoaded, _bytesTotal))
var str:String = "";
try
{
str = socket.readUTFBytes(socket.bytesAvailable);
}
catch(e:Error)
{
}
if(!headerComplete)
{
var httpStatus:String;
var headerEndIndex:int = str.indexOf("\r\n\r\n");
if(headerEndIndex != -1)
{
headerTmp += str.substring(0, headerEndIndex);
headerComplete = true;
_data += str.substring(headerEndIndex + 4);
var headerArr:Array = headerTmp.split("\r\n");
var headerLine:String;
var headerParts:Array;
for each(headerLine in headerArr)
{
if(headerLine.indexOf("HTTP/1.") != -1)
{
headerParts = headerLine.split(" ");
if(headerParts.length > 0)
{
_httpVersion = parseFloat(StringUtil.trim(headerParts.shift().split("/")[1]));
}
if(headerParts.length > 0)
{
_httpStatusCode = parseInt(StringUtil.trim(headerParts.shift()));
}
if(headerParts.length > 0)
{
_httpStatusText = StringUtil.trim(headerParts.join(" "));
}
dispatchEvent(new HTTPStatusEvent(HTTPStatusEvent.HTTP_STATUS, false, false, _httpStatusCode));
}
else
{
var colonIndex:int = headerLine.indexOf(":");
if(colonIndex != -1) {
var key:String = StringUtil.trim(headerLine.substring(0, colonIndex));
var value:String = StringUtil.trim(headerLine.substring(colonIndex + 1));
if (!_header)
{
_header = new Object ();
}
_header[key] = value;
}
}
}
if(_header["Content-Length"])
{
// total bytes = content-length + header size (number of characters in header)
// not working, need to work on right logic..
_bytesTotal = int(_header["Content-Length"]) + headerTmp.length;
}
}
else
{
headerTmp += str;
}
}
else
{
_data += str;
}
}
private function sendHeaders():void
{
var requestHeaders:Array = _request.requestHeaders;
var h:String = "";
_header = null;
_bytesLoaded = 0;
_bytesTotal = 0;
_data = "";
headerComplete = false;
headerTmp = "";
//create an HTTP 1.0 Header Request
h+= "GET " + _httpRequest + " HTTP/1.0\r\n";
h+= "Host:" + _httpServer + "\r\n";
if(requestHeaders.length > 0)
{
for each(var rh:URLRequestHeader in requestHeaders)
{
h+= rh.name + ":" + rh.value + "\r\n";
}
}
//set HTTP headers to socket buffer
socket.writeUTFBytes(h + "\r\n\r\n")
//push the data to server
socket.flush()
}
private function parseURL():Boolean
{
//parse URL into sockServer and sockRequest
var d:Array = _request.url.split('http://')[1].split('/');
if(d.length > 0)
{
_httpServer = d.shift();
//load crossdomain, if its on server.
Security.loadPolicyFile("http://"+_httpServer+"/crossdomain.xml");
_httpRequest = '/' + d.join('/');
return true;
}
return false;
}
}
}
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="onAppInit()">
<mx:Script>
import flash.net.*;
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():void
{
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):void
{
//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):void
{
//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):void
{
//if httpStatus is 401, 403, 404, 500, 501, socket is closed.
console.text+= "Event: httpStatus (" + event.status + ")\n\n";
}
private function loadURL():void
{
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment