NodeJS,如何在GET请求的TLSSocket.socketOnData上调试解析错误?

时间:2017-01-20 22:15:05

标签: json node.js debugging https get

我对NodeJS很陌生,并且已经在AWS Lambda上试用了一个简单的Alexa服务来告诉我家里的温度。我遇到了一个让我陷入困境的问题 - 当我尝试与https端点通信以查询家庭自动化恒温器的某些数据时 - 我的Node应用程序终止时出现错误:

Error: Parse Error
    at TLSSocket.socketOnData (_http_client.js:362:20)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at TLSSocket.Readable.push (_stream_readable.js:134:10)
    at TLSWrap.onread (net.js:551:20)

这是一个相当简单的GET请求,通过https,端点的提供者使用Python没有问题。我尝试将我的代码移动到笔记本电脑上的本地节点设置中,但仍然存在问题(因此它不是AWS)。由于它的https和我的控制之外的服务,如果响应以某种微妙的方式损坏,我无法轻易地将流量发送到线路 - 但是我尝试使用Browsify将代码转换为在网络中运行浏览器(我可以使用wireshark),当然它可以工作,我可以看到json响应然后我得到的一切都不奇怪。

我尝试在节点中使用响应模块而不是核心https库,但我仍然遇到相同的底层错误。

我对我能做的事情感到困惑 - 并且不知道如何调试它。它让我感到质疑问题或时间问题 - 但我不知道如何处理这个问题。任何想法?

我的代码如下所示:

var https = require('https');
var crypto = require('crypto');

function executeHttpRequest(path, data, method, username, password) {

    var encodedLogin = getLoginString(username,password);
    var stringData = JSON.stringify(data);

    var requestOptions = {
        host: 'hub-server.domain.co.uk',
        port: 443,
        path: path,
        method: 'GET',
        headers: {
            'Cache-Control': 'no-cache',
            'Accept': 'application/json, text/plain, */*',
            'Authorization': 'Basic ' + encodedLogin
        }};

    var request = https.request(requestOptions, function(response) {

        var body='';
        response.setEncoding('utf8');

        response.on('error', function(err){
            console.log(method + " error: \n", err.stack);
        }); 

        response.on('data', function (chunk) {
            console.log("read data: " + chunk);
            body += chunk 
        });

        response.on('end', function () {
            console.log("end data");
        });

    });

    request.on('error', function(err) {
        console.log('request error: \n' + err.stack);
    });

    console.log("sending request:" + JSON.stringify(requestOptions));
    console.log("with data: " + stringData)

    request.write(stringData);  
    request.end();
    console.log("closed request")
}

在节点I中运行时,获得以下输出

sending request:{"host":"hub-server.domain.co.uk","port":443,"path":"/zone/1","method":"GET","headers":{"Cache-Control":"no-cache","Accept":"application/json, text/plain, */*","Authorization":"Basic bWFjdGEyOmY0OWZiODJlYTcyNWYzNDgwMTViODVjZTNlZmIyYmY1MWE4ZmI3YWUxMzJmZTRkNDk4OGEc"}}
closed request
request error: 
Error: Parse Error
    at TLSSocket.socketOnData (_http_client.js:362:20)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at TLSSocket.Readable.push (_stream_readable.js:134:10)
    at TLSWrap.onread (net.js:551:20)

我用类似的PUT命令得到了同样的错误。有趣的是,如果我在使用PUT时错过了一个参数,并且服务器回复了JSON错误,则上面的代码可以正常工作,并向我展示记录错误的JSON。同样,如果我使用无效的URL或错误的AUTH,我会正确获取适当的状态代码。

如果我尝试点击https://www.google.com并进行搜索,我的代码似乎也有效。

显然有些事情发生了 - 但我怎样才能纠正我的节点代码,或者建议端点的作者呢?

1 个答案:

答案 0 :(得分:2)

回答我自己的问题 - 使用Node插件支持在IntelliJ中运行此代码,我能够进入问题发生的位置。使用调试器可以更容易地发现出现问题。

我发现http解析器实际上显示的是错误代码:HPE_UNEXPECTED_CONTENT_LENGTH - 在google上搜索更多内容,我看到其他几个人经历过这个(有趣的,与家庭自动化有关) - 这些主题中的结论是由于安全问题,更高版本的Node对HTTP规范变得更加严格。有了这个错误代码,搜索显示了两个类似的情况(例如http.get Parse Error, code: 'HPE_UNEXPECTED_CONTENT_LENGTH'),结论是有一个Content-Length和Transfer-encoding的响应:chunked头存在于一起(这是一个错误)。我的回答没有这个错误,但是我想知道声明的内容长度是错误的还是某个地方的响应中是否存在虚假的cr / lf。我希望我能够在IntelliJ

中调试这个假设

IntelliJ debugging a node application