代码400错误的请求,因为标题中的Content-Length

时间:2014-07-06 14:01:27

标签: node.js http

我正在编写用于测试RESTful api的规范。我在nodejs中用来发出http请求的模块是standard http module

如果我没有指定内容长度'在标题中,然后请求成功,但我通过

指定长度
  

options.headers [' Content-Length'] = post_data.length;

,然后这是一个400错误代码的错误请求。我搜索了stackoverflow的内容长度相关问题,但到目前为止没有得到任何灵感。我尝试了长度+1,只有100,都以相同的错误请求结束。

以下是我的代码。你能告诉我这是什么问题吗?

var options = {
  hostname: hostname,
  port: port,
  headers: {
        'Content-Type': 'application/json',
        'Cache-Control': 'no-cache'
        // 'Content-Length': post_data.length
    }
};

describe('API Testing Function', function () {

    db.bind('user');

    describe('POST /api/user', function () {
        it('should return 400 when password is not present', function (done) {

            options.method = 'POST';
            options.path = '/api/user';
            var post_data = JSON.stringify({email:'111@email.com'});
            options.headers['Content-Length'] = post_data.length; // error here
            // if I delete above line, then it is totally good request. 

            var req = http.request(options, function(res){

                res.on('data', function(chunk){
                    // console.log('BODY:' + chunk);
                    var result = JSON.parse(chunk);
                    assert.equal(400, result.code);
                    done();
                });
            });
            req.write(post_data, 'utf8');
            req.end();
        });
    });
});

1 个答案:

答案 0 :(得分:0)

在研究同样的问题时遇到了你的帖子,并认为我可能会发布我的调查结果的答案,即使你发布这个已经大约2。5年了。不妨为将来的参考做出贡献。 :)

以下是一些要点:

首先,建议使用Buffer.byteLength(post_data)而不是变量的字符串长度来考虑不同的编码类型。

我已经在我的本地机器上简化了你的代码,并尝试在我计划采矿的当地工作场所拍摄它。删除内容长度给了我411(需要长度)。但是,保留大部分代码完好无损,我设法使用Content-Length按原样提取一些结果。我的问题恰恰相反,我尝试使用GET方法和Content-Length。这在目标服务器上不起作用。我的猜测是它是服务器或RFC的东西。这是可以的,因为我见过的大多数实现只在POST时使用它而不是GET。

最后,我建议您阅读RFC for Content-Length以及GET method以获得基本了解。它的规格有一些细微差别,但有些值得记住。

当我明白我的问题是什么时,值得注意的项目会这样说:

对于GET方法:

  

GET请求消息中的有效负载没有定义的语义;   在GET请求上发送有效负载主体可能会导致一些存在   拒绝请求的实现。

根据Content-Length文档,我发现了这个:

  

.. Content-Length头字段通常在POST请求中发送   当值为0时(表示空的有效负载体)。用户代理   在请求消息时,不应发送Content-Length头字段   不包含有效负载主体,方法语义不包含   期待这样一个机构。   ...   发件人不得在任何邮件中发送Content-Length头字段   包含Transfer-Encoding标头字段。

此外,这个site帮助我从浏览器中获取了一些信息,从服务器的角度看它可能是什么样子。如果目标服务器在互联网上可见,您也可以使用它来调试目标服务器。

如果服务器在GET方法中接受Content-Length,那么简单检查是将其值设置为零。测试POST时也是如此。

值得注意的是HTTP / 1.1使用Transfer-Encoding来消除Content-Length中的猜测,并且它们也不应该同时使用。 Node.js HTTP文档在底部提到了这一点:

  

发送'Content-Length'标头将禁用默认的chunked   编码

我建议您不使用Content-Length而保持原样。它应该在那里,所以你不必担心它。