如何限制从 nodejs http 模块上的 rest 服务器传入的块的大小?
How to limit size of chunk incoming from rest server on nodejs http module?
我正在使用 nodejs 请求模块从 nodejs 请求一个休息服务器。
如果传入数据大小超出允许范围,我想取消流 limit.the 这里的目的是确保我的网络未被锁定。
我的代码示例如下;
var http = require("http");
async function httpRequest({
host,
method,
port,
path
} = params, data) {
if (method.toUpperCase() === "GET") {
let query = "";
data = JSON.parse(data);
for (var key in data) {
if (data.hasOwnProperty(key)) {
let value = data[key];
console.log(key + " -> " + value);
query = query
.concat("&")
.concat(key)
.concat("=")
.concat(value);
}
}
if (query) {
query = "?".concat(query.substring(1));
}
path = encodeURI(path.concat(query));
console.log("path : " + path);
}
var opts = {
hostname: host,
port: port,
path: path,
method: method,
timeout: 30 * 1000,
headers: {
"Content-Type": "application/json"
}
};
return new Promise(function (resolve, reject) {
const req = http.request(opts, function (response) {
console.log("Status Code : " + response.statusCode);
if (response.statusCode < 200 || response.statusCode >= 300) {
req.end();
return reject("Fetch data failed = " + response.statusCode);
}
var str = "";
response.on("data", function (chunk) {
console.log("chunk : " + chunk);
str += chunk;
if (str.length > 256) {
req.abort();
reject(
new Error(
"The size of the incoming data is larger than the allowable limit."
)
);
}
});
response.on("end", function () {
console.log("\n Result from web service : ", str);
try {
let jsonData = JSON.parse(str);
if (jsonData.status) {
if (jsonData.status.toLowerCase === "success") {
if (!("result" in jsonData)) {
reject("Json Structure Error");
}
} else if (jsonData.status.toLowerCase === "error") {
if (!jsonData.error) {
reject("Json Structure Error");
}
}
resolve(jsonData);
} else {
reject("Json Structure Error");
}
} catch (error) {
reject("Response json error : " + error);
}
});
});
if (method.toUpperCase() !== "GET" && data) {
req.write(data);
}
//req bitti
req.on("timeout", function () {
console.log("timeout! " + opts.timeout / 1000 + " seconds expired");
req.abort();
});
req.on("error", function (err) {
console.log("Error : " + err);
if (err.code === "ECONNRESET") {
req.abort();
console.log("Timeout occurs : " + err);
reject(new Error("Timeout occurs : " + err));
} else if (err.code === "ENOTFOUND") {
req.abort();
console.log("Address cannot be reachable : " + err);
reject(new Error("Address cannot be reachable : " + err));
} else {
req.abort();
reject(new Error(err));
}
});
req.end();
});
}
let data = JSON.stringify({
username: "monetrum",
password: "123456",
name: "Loremipsumdolorsitamet,consecteturadipiscingelit" +
".Aeneaninaliquamodio,egetfac"
});
let params = {
host: "127.0.0.1",
method: "GET",
port: 3010,
path: "/login"
};
httpRequest(params, data);
到目前为止 good.But 有一个 problem.I 正在控制传入的 data.Size 我允许的数据不能大于 256 Bytes.But 块的第一次提取大于允许 size.So 我的大小控制是 nonsense.Is 有一种方法可以处理 it.Is 可以限制块的大小。提前致谢。
'readable'事件
您想使用 readable
事件而不是 data
事件:
var byteCount = 0;
var chunkSize = 32;
var maxBytes = 256;
req.on('readable', function () {
var chunks = [];
var data;
while(true) {
data = this.read(chunkSize);
if (!data) { break; }
byteCount += data.byteLength;
if (byteCount > maxBytes) {
req.abort();
break;
}
chunks.push(data);
}
// do something with chunks
});
req.on('abort', function () {
// do something to handle the error
});
由于您的问题非常具体,我使示例更通用一些,希望其他人也能从中有所了解。
见https://nodejs.org/api/stream.html#stream_event_readable
然而...
网络不关心
但是,您将获得比这更多的数据。 TCP数据包大小为64k。通过非千兆以太网,将 MTU 截断为 1500 字节 (1.5k)。
除了关闭连接之外,您无法采取任何措施来防止网络 activity 发生,并且每个数据事件获得的数据不能少于 1.5k,除非少于 1.5k正在发送的数据(或发生疯狂的网络问题,您无法控制)。t
P.S.
我建议您使用代码编辑器,例如 VSCode。很难阅读混合有制表符和空格以及不同级别的不同块的代码。它将建议可以帮助您及早发现错误并重新格式化代码的插件,以便其他人(和您自己)更容易阅读它。
我正在使用 nodejs 请求模块从 nodejs 请求一个休息服务器。 如果传入数据大小超出允许范围,我想取消流 limit.the 这里的目的是确保我的网络未被锁定。
我的代码示例如下;
var http = require("http");
async function httpRequest({
host,
method,
port,
path
} = params, data) {
if (method.toUpperCase() === "GET") {
let query = "";
data = JSON.parse(data);
for (var key in data) {
if (data.hasOwnProperty(key)) {
let value = data[key];
console.log(key + " -> " + value);
query = query
.concat("&")
.concat(key)
.concat("=")
.concat(value);
}
}
if (query) {
query = "?".concat(query.substring(1));
}
path = encodeURI(path.concat(query));
console.log("path : " + path);
}
var opts = {
hostname: host,
port: port,
path: path,
method: method,
timeout: 30 * 1000,
headers: {
"Content-Type": "application/json"
}
};
return new Promise(function (resolve, reject) {
const req = http.request(opts, function (response) {
console.log("Status Code : " + response.statusCode);
if (response.statusCode < 200 || response.statusCode >= 300) {
req.end();
return reject("Fetch data failed = " + response.statusCode);
}
var str = "";
response.on("data", function (chunk) {
console.log("chunk : " + chunk);
str += chunk;
if (str.length > 256) {
req.abort();
reject(
new Error(
"The size of the incoming data is larger than the allowable limit."
)
);
}
});
response.on("end", function () {
console.log("\n Result from web service : ", str);
try {
let jsonData = JSON.parse(str);
if (jsonData.status) {
if (jsonData.status.toLowerCase === "success") {
if (!("result" in jsonData)) {
reject("Json Structure Error");
}
} else if (jsonData.status.toLowerCase === "error") {
if (!jsonData.error) {
reject("Json Structure Error");
}
}
resolve(jsonData);
} else {
reject("Json Structure Error");
}
} catch (error) {
reject("Response json error : " + error);
}
});
});
if (method.toUpperCase() !== "GET" && data) {
req.write(data);
}
//req bitti
req.on("timeout", function () {
console.log("timeout! " + opts.timeout / 1000 + " seconds expired");
req.abort();
});
req.on("error", function (err) {
console.log("Error : " + err);
if (err.code === "ECONNRESET") {
req.abort();
console.log("Timeout occurs : " + err);
reject(new Error("Timeout occurs : " + err));
} else if (err.code === "ENOTFOUND") {
req.abort();
console.log("Address cannot be reachable : " + err);
reject(new Error("Address cannot be reachable : " + err));
} else {
req.abort();
reject(new Error(err));
}
});
req.end();
});
}
let data = JSON.stringify({
username: "monetrum",
password: "123456",
name: "Loremipsumdolorsitamet,consecteturadipiscingelit" +
".Aeneaninaliquamodio,egetfac"
});
let params = {
host: "127.0.0.1",
method: "GET",
port: 3010,
path: "/login"
};
httpRequest(params, data);
到目前为止 good.But 有一个 problem.I 正在控制传入的 data.Size 我允许的数据不能大于 256 Bytes.But 块的第一次提取大于允许 size.So 我的大小控制是 nonsense.Is 有一种方法可以处理 it.Is 可以限制块的大小。提前致谢。
'readable'事件
您想使用 readable
事件而不是 data
事件:
var byteCount = 0;
var chunkSize = 32;
var maxBytes = 256;
req.on('readable', function () {
var chunks = [];
var data;
while(true) {
data = this.read(chunkSize);
if (!data) { break; }
byteCount += data.byteLength;
if (byteCount > maxBytes) {
req.abort();
break;
}
chunks.push(data);
}
// do something with chunks
});
req.on('abort', function () {
// do something to handle the error
});
由于您的问题非常具体,我使示例更通用一些,希望其他人也能从中有所了解。
见https://nodejs.org/api/stream.html#stream_event_readable
然而...
网络不关心
但是,您将获得比这更多的数据。 TCP数据包大小为64k。通过非千兆以太网,将 MTU 截断为 1500 字节 (1.5k)。
除了关闭连接之外,您无法采取任何措施来防止网络 activity 发生,并且每个数据事件获得的数据不能少于 1.5k,除非少于 1.5k正在发送的数据(或发生疯狂的网络问题,您无法控制)。t
P.S.
我建议您使用代码编辑器,例如 VSCode。很难阅读混合有制表符和空格以及不同级别的不同块的代码。它将建议可以帮助您及早发现错误并重新格式化代码的插件,以便其他人(和您自己)更容易阅读它。