如何使用regex和nodejs验证传入的http body是multipart/form-data?

gywdnpxw  于 2023-05-22  发布在  Node.js
关注(0)|答案(1)|浏览(70)

在我的nodejs项目中,我想验证传入的http请求是否只是一个有效的multipart/form-data请求。
到目前为止,我尝试了以下示例:

const http = require('http');

const validateMultipartFormData = (body) => {
   // Somehow use a logic to verify whether body is a multipart one.
   // For now I return a dummy logic
   return true;
};
  
const server = http.createServer((req, res) => {

  var body = [];

    req.on('data', (data) => body.push(data));

    req.on('end', () => {
      body = body.toString();

      const validMultipart =  validateMultipartFormData(body);

      if (req.headers['content-type'].includes('multipart/form-data')) {

        const statuscode = validMultipart?200:400;
        const validStatusMsg = validMultipart?"Valid Body":"Invalid Multipart";
        
        res.statusCode=statuscode;
        res.end(validStatusMsg);

      } else {
        res.end("No Multipart Body")
      }
    });
});

server.listen(8080, () => {
  console.log('Server listening on http://localhost:8080/ ...');
});
qlzsbp2j

qlzsbp2j1#

在你的例子中,所需的正则表达式是:

/[\-\w]+\r\nContent-Disposition:\sform-data;\sname=.*\r\n/

因此,函数validateMultipartFormData将是:

const validateMultipartFormData = (body) => {
    const pattern = /[\-\w]+\r\nContent-Disposition:\sform-data;\sname=.*\r\n/;
    return pattern.test(body);
};

一个工作示例是:

const http = require('http');

const validateMultipartFormData = (body) => {
    const pattern = /[\-\w]+\r\nContent-Disposition:\sform-data;\sname=.*\r\n/;
    return pattern.test(body);
};
  

const server = http.createServer((req, res) => {

  var body = [];

    req.on('data', (data) => body.push(data));

    req.on('end', () => {
      body = body.toString();

      const validMultipart =  validateMultipartFormData(body);

      if (req.headers['content-type'].includes('multipart/form-data')) {

        const statuscode = validMultipart?200:400;
        const validStatusMsg = validMultipart?"Valid Body":"Invalid Multipart";
        
        res.statusCode=statuscode;
        res.end(validStatusMsg);

      } else {
        res.end("No Multipart Body")
      }
    });
});

server.listen(8080, () => {
  console.log('Server listening on http://localhost:8080/ ...');
});

正则表达式背后的哲学

多部分http主体是用以\r\n结尾的分隔符字符串分隔的字段。通常在大多数情况下,分隔符看起来像这样:

--------------------------e2953aef605ceeb2

\r\n是不可打印的字符,因此没有显示在上面的字符串中。如果我们转义它们,分隔符字符串将是:

--------------------------e2953aef605ceeb2\r\n

每个分隔符字符串都在http头Content-Type上定义。对于上面的分隔符,header的值为:

Content-Type: multipart/form-data; boundary=--------------------------e2953aef605ceeb2

分隔符字符串定义在标题的; boundary部分。通过测试,边界将以一些破折号(-)开始,并以一些随机字符和\r\n结束(\r表示字符回车,而\n表示字符换行符)。
此外,主体也将始终包含:

Content-Disposition: form-data; name=

然后会有一些其他字符跟随,并且总是以\r\n结尾。
因此,如果我尝试检查这2行是否存在,我可以肯定大多数情况下内容将匹配miltipart/form-data头。

相关问题