nodejs-std icon indicating copy to clipboard operation
nodejs-std copied to clipboard

Haxe and Node.js http mismatch

Open indolering opened this issue 11 years ago • 0 comments

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) {
    }
};

indolering avatar May 10 '14 04:05 indolering