Browse Source

Added haxe.Http support for nodejs (#4713)

* added haxe.Http support for nodejs

* removed sync options for nodejs; added onStatus callback

* call onStatus before end of response

* allow multiple headers of same name; switch regex parsing of url to nodejs Url.parse()
Sam 9 years ago
parent
commit
c98742c7ea
1 changed files with 66 additions and 5 deletions
  1. 66 5
      std/haxe/Http.hx

+ 66 - 5
std/haxe/Http.hx

@@ -53,7 +53,7 @@ class Http {
 	var chunk_size : Null<Int>;
 	var chunk_buf : haxe.io.Bytes;
 	var file : { param : String, filename : String, io : haxe.io.Input, size : Int, mimeType : String };
-#elseif js
+#elseif (js && !nodejs)
 	public var async : Bool;
 	public var withCredentials : Bool;
 #end
@@ -81,7 +81,7 @@ class Http {
 		headers = new List<{ header:String, value:String }>();
 		params = new List<{ param:String, value:String }>();
 
-		#if js
+		#if (js && !nodejs)
 		async = true;
 		withCredentials = false;
 		#elseif sys
@@ -145,7 +145,9 @@ class Http {
 
 	#if (js || flash)
 
-	#if js
+	#if nodejs
+	var req:js.node.http.ClientRequest;
+	#elseif js
 	var req:js.html.XMLHttpRequest;
 	#elseif flash
 	var req:flash.net.URLLoader;
@@ -186,7 +188,66 @@ class Http {
 	**/
 	public function request( ?post : Bool ) : Void {
 		var me = this;
-	#if js
+	#if nodejs
+		me.responseData = null;
+		var parsedUrl = js.node.Url.parse(url);
+		var secure = (parsedUrl.protocol == "https:");
+		var host = parsedUrl.hostname;
+		var path = parsedUrl.path;
+		var port = if (parsedUrl.port != null) Std.parseInt(parsedUrl.port) else (secure ? 443 : 80);
+		var h:Dynamic = {};
+		for (i in headers) {
+			var arr = Reflect.field(h, i.header);
+			if (arr == null) {
+				arr = new Array<String>();
+				Reflect.setField(h, i.header, arr);
+			}
+			
+			arr.push(i.value);
+		}
+		var uri = postData;
+		if( uri != null )
+			post = true;
+		else for( p in params ) {
+			if( uri == null )
+				uri = "";
+			else
+				uri += "&";
+			uri += StringTools.urlEncode(p.param)+"="+StringTools.urlEncode(p.value);
+		}
+		var question = path.split("?").length <= 1;
+		if (!post && uri != null) path += (if( question ) "?" else "&") + uri;
+		
+		var opts = {
+			protocol: parsedUrl.protocol,
+			hostname: host,
+			port: port,
+			method: post ? 'POST' : 'GET',
+			path: path,
+			headers: h
+		};
+		function httpResponse (res) {
+			var s = res.statusCode;
+			if (s != null)
+				me.onStatus(s);
+			var body = '';
+			res.on('data', function (d) {
+				body += d;
+			});
+			res.on('end', function (_) {
+				me.responseData = body;
+				me.req = null;
+				if (s != null && s >= 200 && s < 400) {
+					me.onData(body);
+				} else {
+					me.onError("Http Error #"+s);
+				}
+			});
+		}
+		req = secure ? js.node.Https.request(untyped opts, httpResponse) : js.node.Http.request(untyped opts, httpResponse);
+		if (post) req.write(uri);
+		req.end();
+	#elseif js
 		me.responseData = null;
 		var r = req = js.Browser.createXMLHttpRequest();
 		var onreadystatechange = function(_) {
@@ -752,7 +813,7 @@ class Http {
 	public dynamic function onStatus( status : Int ) {
 	}
 
-#if !flash
+#if (!flash && !nodejs)
 	/**
 		Makes a synchronous request to `url`.