在发送POST之前,与远程服务器协商最大请求主体大小

时间:2018-05-31 18:00:30

标签: node.js rest http httprequest

我有一个Node JS服务器,它将不确定大小的JSON对象发送到远程服务器,该服务器可能无法提前知道对主体请求大小的限制。

如果我的JSON对象超过了最大请求大小,我想以块的形式发送数据。

我正在测试远程服务器的模拟实现,该实现使用npm库主体解析器来设置其最大请求主体大小。当我发送超过此限制的请求时,模拟远程服务器返回错误:PayloadTooLargeError: request entity too large

问题:有没有办法通过标准HTTP方法和标题确定服务器接受的最大请求体大小?

1 个答案:

答案 0 :(得分:2)

我认为您无法查询远程服务器以直接获取最大值。

可能你最好的选择是尝试“检查并查看”方法,从合理的价值开始,并在每次被413拒绝时通过减少一些比例来切换到分块。

我猜想8mb-10mb是一般互联网服务器的良好起始大小。但是在您的特定应用程序中,您可能知道它将连接到的服务器类型以及您尝试发送的数据的典型大小的一些额外限制,因此您可以使用更大的默认值。

我不确定我会推荐它但是这里是一个愚蠢的脚本,它向二进制搜索发送了一堆虚拟请求,google.com的最大大小为4096字节。

var http = require('http');
var querystring = require('querystring');

function compute_size(domain) {
  var max_size = 10240;
  var min_size = 0;

  function send_req(size) {
    var post_data = '*'.repeat(size)
    var post_options = {
      host: domain,
      port: '80',
      path: '/',
      method: 'POST',
      headers: {
        'Content-Length': size
      }
    };

    var req = http.request(post_options, function(res) {
      console.log('Try for size ' + size + ': ' + res.statusCode);
      var fn;

      if (res.statusCode == 413) {
        max_size = size;
        fn = Math.floor;
      } else {
        min_size = size;
        fn = Math.ceil;
      }

      var next_size = fn((max_size - min_size)/2+min_size);

      if (next_size == max_size || next_size == min_size) {
        console.log('Found max: ', min_size);
      } else {
        send_req(next_size);
      }
    });

    req.write(post_data);
    req.end();

  }

  send_req(max_size);
}

compute_size('google.com');

这是google.com的输出,推断最大值为4096 ... lol

$ node post.js
Try for size 10240: 413
Try for size 5120: 413
Try for size 2560: 405
Try for size 3840: 405
Try for size 4480: 413
Try for size 4160: 413
Try for size 4000: 405
Try for size 4080: 405
Try for size 4120: 413
Try for size 4100: 413
Try for size 4090: 405
Try for size 4095: 405
Try for size 4098: 413
Try for size 4096: 405
Try for size 4097: 413
Found max:  4096