这是一个脑筋急转弯的问题,我实际上知道答案。我正在抛出一笔赏金,因为它代表了一个有价值的节点编程安全提示(这是第一个提示)。
我正在使用
var knox = require('knox');
var s3 = knox.createClient({
key: ...,
secret: ...,
bucket: ...
});
// The bug is below:
var stringVal = JSON.stringify(<2d javascript array from a large spreadsheet>)
var req = s3.put(path + filename, {
'Content-Length': stringVal.length,
'Content-Type': 'application/json'
});
req.end(stringVal);
结果上传被截断或以其他方式损坏。我们有stringVal.length === 322889
,生成的S3项目大小与之匹配。但是下载并重新加载文件会产生一个长度为322140
的字符串。在尝试使用JSON.parse字符串(可预测地)导致语法错误之前,没有错误出现。
怎么了?
答案 0 :(得分:5)
从knox
- 模块(https://github.com/LearnBoost/knox/blob/master/lib/client.js)的来源,您可以了解到它使用标准http
- 请求。
req.write
和req.end
默认情况下会从'utf8'转换字符串(http://nodejs.org/api/http.html#http_request_end_data_encoding)。
所以真正发生的是你不小心通过设置字符串长度而不是'Content-Length'字段中的字节数来切断字符串的结尾。服务器扔掉的东西比这更长;所以当你解析字符串时会出现错误。
最快的解决方法是:
'Content-Length': new Buffer(stringVal).length,
甚至更快:只需删除'Content-Length'行。