Как ограничить размер чанка, поступающего с остального сервера на http-модуль nodejs? - PullRequest
0 голосов
/ 06 марта 2019

Я запрашиваю сервер отдыха у nodejs с помощью модуля запроса nodejs.Я хочу отменить поток, если размер входящих данных выходит за допустимые пределы. Цель состоит в том, чтобы убедиться, что моя сеть не заблокирована.

Мой пример кода следующий;

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

Пока все хорошо. Но есть проблема. Я управляю входящими данными. Размер разрешенных данных должен быть не более 256 байт. Но первая выборка фрагмента больше, чем допустимый размер.Мой контроль размера - нонсенс. Есть способ справиться с этим. Можно ли ограничить размер чанка.Заранее спасибо.

1 Ответ

1 голос
/ 07 марта 2019

Событие для чтения

Вы хотите использовать событие 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 составляет 64 КБ. По негигабитному Ethernet, который сокращает MTU до 1500 байт (1,5 КБ).

Вы ничего не можете сделать, чтобы предотвратить сетевую активность, кроме закрытия соединения, и вы не можете получить менее 1,5 тыс. Данных на событие данных, если не отправлено менее 1,5 тыс. Данных (или происходят сумасшедшие проблемы с сетью, которые вы не можете контролировать) .t

приписка

Я бы порекомендовал вам использовать редактор кода, такой как VSCode. Очень трудно читать код, в котором смешаны табуляции и пробелы, а также разные блоки на разных уровнях. В нем будут предложены плагины, которые помогут вам раньше обнаруживать ошибки и переформатировать код, чтобы другим (и вам) было легче его читать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...