Add URLLoader for HTML5, other platforms TBD
This commit is contained in:
0
lime/net/NetConnection.hx
Normal file
0
lime/net/NetConnection.hx
Normal file
0
lime/net/NetConnectionManager.hx
Normal file
0
lime/net/NetConnectionManager.hx
Normal file
303
lime/net/URLLoader.hx
Normal file
303
lime/net/URLLoader.hx
Normal file
@@ -0,0 +1,303 @@
|
||||
package lime.net;
|
||||
|
||||
|
||||
import lime.app.Event;
|
||||
import lime.utils.ByteArray;
|
||||
|
||||
#if js
|
||||
import js.html.EventTarget;
|
||||
import js.html.XMLHttpRequest;
|
||||
import js.Browser;
|
||||
import js.Lib;
|
||||
#end
|
||||
|
||||
|
||||
class URLLoader {
|
||||
|
||||
|
||||
public var bytesLoaded:Int;
|
||||
public var bytesTotal:Int;
|
||||
public var data:Dynamic;
|
||||
public var dataFormat (default, set):URLLoaderDataFormat;
|
||||
public var onComplete = new Event<URLLoader->Void> ();
|
||||
public var onHTTPStatus = new Event<URLLoader->Int->Void> ();
|
||||
public var onIOError = new Event<URLLoader->String->Void> ();
|
||||
public var onOpen = new Event<URLLoader->Void> ();
|
||||
public var onProgress = new Event<URLLoader->Int->Int->Void> ();
|
||||
public var onSecurityError = new Event<URLLoader->String->Void> ();
|
||||
|
||||
|
||||
public function new (request:URLRequest = null) {
|
||||
|
||||
bytesLoaded = 0;
|
||||
bytesTotal = 0;
|
||||
dataFormat = URLLoaderDataFormat.TEXT;
|
||||
|
||||
if (request != null) {
|
||||
|
||||
load (request);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function close ():Void {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private dynamic function getData ():Dynamic {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function load (request:URLRequest):Void {
|
||||
|
||||
#if js
|
||||
requestUrl (request.url, request.method, request.data, request.formatRequestHeaders ());
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if js
|
||||
private function registerEvents (subject:EventTarget):Void {
|
||||
|
||||
var self = this;
|
||||
if (untyped __js__("typeof XMLHttpRequestProgressEvent") != __js__('"undefined"')) {
|
||||
|
||||
subject.addEventListener ("progress", __onProgress, false);
|
||||
|
||||
}
|
||||
|
||||
untyped subject.onreadystatechange = function () {
|
||||
|
||||
if (subject.readyState != 4) return;
|
||||
|
||||
var s = try subject.status catch (e:Dynamic) null;
|
||||
|
||||
if (s == untyped __js__("undefined")) {
|
||||
|
||||
s = null;
|
||||
|
||||
}
|
||||
|
||||
if (s != null) {
|
||||
|
||||
self.onHTTPStatus.dispatch (this, s);
|
||||
|
||||
}
|
||||
|
||||
//js.Lib.alert (s);
|
||||
|
||||
if (s != null && s >= 200 && s < 400) {
|
||||
|
||||
self.__onData (subject.response);
|
||||
|
||||
} else {
|
||||
|
||||
if (s == null) {
|
||||
|
||||
self.onIOError.dispatch (this, "Failed to connect or resolve host");
|
||||
|
||||
} else if (s == 12029) {
|
||||
|
||||
self.onIOError.dispatch (this, "Failed to connect to host");
|
||||
|
||||
} else if (s == 12007) {
|
||||
|
||||
self.onIOError.dispatch (this, "Unknown host");
|
||||
|
||||
} else if (s == 0) {
|
||||
|
||||
self.onIOError.dispatch (this, "Unable to make request (may be blocked due to cross-domain permissions)");
|
||||
self.onSecurityError.dispatch (this, "Unable to make request (may be blocked due to cross-domain permissions)");
|
||||
|
||||
} else {
|
||||
|
||||
self.onIOError.dispatch (this, "Http Error #" + subject.status);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function requestUrl (url:String, method:String, data:Dynamic, requestHeaders:Array<URLRequestHeader>):Void {
|
||||
|
||||
var xmlHttpRequest:XMLHttpRequest = untyped __new__("XMLHttpRequest");
|
||||
registerEvents (cast xmlHttpRequest);
|
||||
var uri:Dynamic = "";
|
||||
|
||||
if (Std.is (data, ByteArray)) {
|
||||
|
||||
var data:ByteArray = cast data;
|
||||
|
||||
switch (dataFormat) {
|
||||
|
||||
//case BINARY: uri = data.__getBuffer ();
|
||||
default: uri = data.readUTFBytes (data.length);
|
||||
|
||||
}
|
||||
|
||||
} else if (Std.is (data, URLVariables)) {
|
||||
|
||||
var data:URLVariables = cast data;
|
||||
|
||||
for (p in Reflect.fields (data)) {
|
||||
|
||||
if (uri.length != 0) uri += "&";
|
||||
uri += StringTools.urlEncode (p) + "=" + StringTools.urlEncode (Reflect.field (data, p));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (data != null) {
|
||||
|
||||
uri = data.toString ();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if (method == "GET" && uri != null && uri != "") {
|
||||
|
||||
var question = url.split ("?").length <= 1;
|
||||
xmlHttpRequest.open (method, url + (if (question) "?" else "&") + uri, true);
|
||||
uri = "";
|
||||
|
||||
} else {
|
||||
|
||||
//js.Lib.alert ("open: " + method + ", " + url + ", true");
|
||||
xmlHttpRequest.open (method, url, true);
|
||||
|
||||
}
|
||||
|
||||
} catch (e:Dynamic) {
|
||||
|
||||
onIOError.dispatch (this, e.toString ());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//js.Lib.alert ("dataFormat: " + dataFormat);
|
||||
|
||||
switch (dataFormat) {
|
||||
|
||||
case BINARY: untyped xmlHttpRequest.responseType = 'arraybuffer';
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
for (header in requestHeaders) {
|
||||
|
||||
//js.Lib.alert ("setRequestHeader: " + header.name + ", " + header.value);
|
||||
xmlHttpRequest.setRequestHeader (header.name, header.value);
|
||||
|
||||
}
|
||||
|
||||
//js.Lib.alert ("uri: " + uri);
|
||||
|
||||
xmlHttpRequest.send (uri);
|
||||
onOpen.dispatch (this);
|
||||
|
||||
getData = function () {
|
||||
|
||||
if (xmlHttpRequest.response != null) {
|
||||
|
||||
return xmlHttpRequest.response;
|
||||
|
||||
} else {
|
||||
|
||||
return xmlHttpRequest.responseText;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#end
|
||||
|
||||
|
||||
|
||||
|
||||
// Event Handlers
|
||||
|
||||
|
||||
|
||||
|
||||
private function __onData (_):Void {
|
||||
|
||||
#if js
|
||||
var content:Dynamic = getData ();
|
||||
|
||||
switch (dataFormat) {
|
||||
|
||||
//case BINARY: this.data = ByteArray.__ofBuffer (content);
|
||||
default: this.data = Std.string (content);
|
||||
|
||||
}
|
||||
#end
|
||||
|
||||
onComplete.dispatch (this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function __onProgress (event:XMLHttpRequestProgressEvent):Void {
|
||||
|
||||
bytesLoaded = event.loaded;
|
||||
bytesTotal = event.total;
|
||||
|
||||
onProgress.dispatch (this, bytesLoaded, bytesTotal);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Get & Set Methods
|
||||
|
||||
|
||||
|
||||
|
||||
private function set_dataFormat (inputVal:URLLoaderDataFormat):URLLoaderDataFormat {
|
||||
|
||||
#if js
|
||||
// prevent inadvertently using typed arrays when they are unsupported
|
||||
// @todo move these sorts of tests somewhere common in the vein of Modernizr
|
||||
|
||||
if (inputVal == URLLoaderDataFormat.BINARY && !Reflect.hasField (Browser.window, "ArrayBuffer")) {
|
||||
|
||||
dataFormat = URLLoaderDataFormat.TEXT;
|
||||
|
||||
} else {
|
||||
|
||||
dataFormat = inputVal;
|
||||
|
||||
}
|
||||
|
||||
return dataFormat;
|
||||
#else
|
||||
return inputVal;
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
typedef XMLHttpRequestProgressEvent = Dynamic;
|
||||
15
lime/net/URLLoaderDataFormat.hx
Normal file
15
lime/net/URLLoaderDataFormat.hx
Normal file
@@ -0,0 +1,15 @@
|
||||
package lime.net; #if !flash
|
||||
|
||||
|
||||
enum URLLoaderDataFormat {
|
||||
|
||||
BINARY;
|
||||
TEXT;
|
||||
VARIABLES;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
typedef URLLoaderDataFormat = flash.net.URLLoaderDataFormat;
|
||||
#end
|
||||
57
lime/net/URLRequest.hx
Normal file
57
lime/net/URLRequest.hx
Normal file
@@ -0,0 +1,57 @@
|
||||
package lime.net; #if !flash
|
||||
|
||||
|
||||
import lime.utils.ByteArray;
|
||||
|
||||
|
||||
class URLRequest {
|
||||
|
||||
|
||||
public var contentType:String;
|
||||
public var data:Dynamic;
|
||||
public var method:String;
|
||||
public var requestHeaders:Array<URLRequestHeader>;
|
||||
public var url:String;
|
||||
public var userAgent:String;
|
||||
|
||||
|
||||
public function new (inURL:String = null) {
|
||||
|
||||
if (inURL != null) {
|
||||
|
||||
url = inURL;
|
||||
|
||||
}
|
||||
|
||||
requestHeaders = [];
|
||||
method = URLRequestMethod.GET;
|
||||
contentType = null; // "application/x-www-form-urlencoded";
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function formatRequestHeaders ():Array<URLRequestHeader> {
|
||||
|
||||
var res = requestHeaders;
|
||||
if (res == null) res = [];
|
||||
|
||||
if (method == URLRequestMethod.GET || data == null) return res;
|
||||
|
||||
if (Std.is (data, String) || Std.is (data, ByteArray)) {
|
||||
|
||||
res = res.copy ();
|
||||
res.push (new URLRequestHeader ("Content-Type", contentType != null ? contentType : "application/x-www-form-urlencoded"));
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
typedef URLRequest = flash.net.URLRequest;
|
||||
#end
|
||||
24
lime/net/URLRequestHeader.hx
Normal file
24
lime/net/URLRequestHeader.hx
Normal file
@@ -0,0 +1,24 @@
|
||||
package lime.net; #if !flash
|
||||
|
||||
|
||||
class URLRequestHeader {
|
||||
|
||||
|
||||
public var name : String;
|
||||
public var value : String;
|
||||
|
||||
|
||||
public function new (name:String = "", value:String = "") {
|
||||
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
typedef URLRequestHeader = flash.net.URLRequestHeader;
|
||||
#end
|
||||
18
lime/net/URLRequestMethod.hx
Normal file
18
lime/net/URLRequestMethod.hx
Normal file
@@ -0,0 +1,18 @@
|
||||
package lime.net; #if !flash
|
||||
|
||||
|
||||
class URLRequestMethod {
|
||||
|
||||
public static var DELETE:String = "DELETE";
|
||||
public static var GET:String = "GET";
|
||||
public static var HEAD:String = "HEAD";
|
||||
public static var OPTIONS:String = "OPTIONS";
|
||||
public static var POST:String = "POST";
|
||||
public static var PUT:String = "PUT";
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
typedef URLRequestMethod = flash.net.URLRequestMethod;
|
||||
#end
|
||||
70
lime/net/URLVariables.hx
Normal file
70
lime/net/URLVariables.hx
Normal file
@@ -0,0 +1,70 @@
|
||||
package lime.net; #if !flash
|
||||
|
||||
|
||||
class URLVariables implements Dynamic {
|
||||
|
||||
|
||||
public function new (inEncoded:String = null) {
|
||||
|
||||
if (inEncoded != null) {
|
||||
|
||||
decode (inEncoded);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function decode (inVars:String):Void {
|
||||
|
||||
var fields = Reflect.fields (this);
|
||||
|
||||
for (f in fields) {
|
||||
|
||||
Reflect.deleteField (this, f);
|
||||
|
||||
}
|
||||
|
||||
var fields = inVars.split (";").join ("&").split ("&");
|
||||
|
||||
for (f in fields) {
|
||||
|
||||
var eq = f.indexOf ("=");
|
||||
|
||||
if (eq > 0) {
|
||||
|
||||
Reflect.setField (this, StringTools.urlDecode (f.substr(0, eq)), StringTools.urlDecode (f.substr(eq + 1)));
|
||||
|
||||
} else if (eq != 0) {
|
||||
|
||||
Reflect.setField (this, StringTools.urlDecode (f), "");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function toString ():String {
|
||||
|
||||
var result = new Array<String> ();
|
||||
var fields = Reflect.fields (this);
|
||||
|
||||
for (f in fields) {
|
||||
|
||||
result.push (StringTools.urlEncode (f) + "=" + StringTools.urlEncode (Reflect.field (this, f)));
|
||||
|
||||
}
|
||||
|
||||
return result.join ("&");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
typedef URLVariables = flash.net.URLVariables;
|
||||
#end
|
||||
@@ -38,8 +38,10 @@ class ApplicationMain {
|
||||
|
||||
}
|
||||
|
||||
#if (js && munit)
|
||||
#if js
|
||||
#if munit
|
||||
embed (null, ::WIN_WIDTH::, ::WIN_HEIGHT::, "::WIN_FLASHBACKGROUND::");
|
||||
#end
|
||||
#else
|
||||
create ();
|
||||
#end
|
||||
|
||||
Reference in New Issue
Block a user