Haxe and Node.js http mismatch
Bear with me here, I'm not sure if I totally understand all of the layers of abstraction going on in the code : )
So, I've been trying to send off some authenticated HTTP requests using the Jsonhx JSON-RPC library. I keep getting error: Http Request Error: Error: getaddrinfo ENOTFOUND
Some googling shows this to be an issue with how Node.js does it's DNS lookups:
I've seen this happen when your host (which you pass in as httpaction) has the scheme (so "http://") in front of it. Your host should strictly be the domain like "www.google.com" not "http://www.google.com" or "www.google.com/hello-world" or "http://www.google.com/hello-world".
Keep it just the domain.
Sure enough, when I pop into the debugger and climb up the call chain to haxe.Http.prototype it displays the host variable as user:pass@localhost:8336.
I switched to a hand-rolled my own authentication header mechanism, that specific error went away, and WireShark picked up on actual HTTP requests being sent (before it saw nothing). I fairly certain that this fixed the problem.
But now I am running into weird error 500 parse errors from my server where the path variable has POST data in it. I dove into the produced code and found weird logic (see inline comments in code below) which I tried tweaking, but I couldn't coax a proper method call out of it. However, appears to be standard code produced by the Haxe JS converter, so I don't know if it is in any way related and now I'm unsure if my fix from above is specific to nodejs-std or not. : (
haxe.Http.prototype = {
...
,request: function(post) {
var _g = this;
var me = this;
var options = { };
var uri = this.postData; //WTF?
var is_secure = this.url.substring(0,8) == "https://";
if(this.url.substring(0,7) == "http://") this.url = HxOverrides.substr(this.url,7,null); else if(is_secure) this.url = HxOverrides.substr(this.url,8,null);
var urlTokens = this.url.split("/");
var host = urlTokens.shift();
if(urlTokens.length > 0) options.path = "/" + urlTokens.join("/"); else options.path = "/";
var hostTokens = host.split(":");
if(hostTokens != null && hostTokens.length > 1) {
options.host = hostTokens[0];
options.port = Std.parseInt(hostTokens[1]);
} else options.host = host;
if(uri != null) post = true; else { // ?
var $it0 = this.params.keys();
while( $it0.hasNext() ) {
var p = $it0.next();
if(uri == null) uri = ""; else uri += "&";
uri += encodeURIComponent(p) + "=" + StringTools.urlEncode(this.params.get(p));
}
}
if(uri != null) {
var question = this.url.split("?").length <= 1;
options.path += (question?"?":"&") + uri;
uri = null; // Stopping the debugger here reveals options.path = "/?{ DATA FROM POST}"
}
if(post) options.method = "POST"; else options.method = "GET";
if(this.headers.get("Content-Type") == null && post && this.postData == null) this.headers.set("Content-Type","application/x-www-form-urlencoded");
if(this.headers.iterator().hasNext()) {
if(options.headers == null) options.headers = { };
var $it1 = this.headers.keys();
while( $it1.hasNext() ) {
var h = $it1.next();
Reflect.setField(options.headers,h,this.headers.get(h));
}
}
var service = null;
if(is_secure) service = js.Node.require("https"); else service = js.Node.require("http");
var request = service.request(options,function(response) {
var responseData = "";
response.setEncoding("utf8");
var s;
try {
s = response.statusCode;
} catch( e ) {
s = 0;
}
if(response.statusCode != null) me.onStatus(response.statusCode);
if(response.statusCode != null && response.statusCode >= 200 && response.statusCode < 400) {
} else switch(s) {
case 0:
me.onError("Failed to connect or resolve host");
break;
case 12029:
me.onError("Failed to connect to host");
break;
case 12007:
me.onError("Unknown host");
break;
default:
me.onError("Http Error #" + response.statusCode);
}
response.on("data",function(chunk) {
responseData += chunk;
});
response.once("end",function() {
response.removeAllListeners("data");
response.removeAllListeners("end");
if(responseData != null) _g.onData(responseData);
responseData = null;
});
response.once("close",function() {
if(responseData != null) _g.onData(responseData);
responseData = null;
});
response.once("error",function(error) {
me.onError("Http Response Error: " + Std.string(error));
});
});
request.on("error",function(error1) {
me.onError("Http Request Error: " + Std.string(error1));
});
request.end();
}
,onData: function(data) {
}
,onError: function(msg) {
}
,onStatus: function(status) {
}
};