body-parser 源码分析 (2)

现在我们来看下 lib/read.js 源码:

'use strict' var createError = require('http-errors') var getBody = require('raw-body') var iconv = require('iconv-lite') var onFinished = require('on-finished') var zlib = require('zlib') module.exports = read function read (req, res, next, parse, debug, options) { var length var opts = options var stream // parsed flag, 上游服务有做判断 req._body = true // read options var encoding = opts.encoding !== null ? opts.encoding : null var verify = opts.verify try { // get the content stream stream = contentstream(req, debug, opts.inflate) length = stream.length stream.length = undefined } catch (err) { return next(err) } // set raw-body options opts.length = length opts.encoding = verify ? null : encoding // assert charset is supported if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { charset: encoding.toLowerCase(), type: 'charset.unsupported' })) } // read body debug('read body') // getBody 函数用于从 stream 中读取内容 getBody(stream, opts, function (error, body) { if (error) { // 异常处理 var _error if (error.type === 'encoding.unsupported') { // echo back charset _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { charset: encoding.toLowerCase(), type: 'charset.unsupported' }) } else { // set status code on error _error = createError(400, error) } // read off entire request stream.resume() onFinished(req, function onfinished () { next(createError(400, _error)) }) return } // 用户自定义校验函数 verify if (verify) { try { debug('verify body') verify(req, res, body, encoding) } catch (err) { next(createError(403, err, { body: body, type: err.type || 'entity.verify.failed' })) return } } var str = body try { debug('parse body') // 如果body不是字符类型而且设置了encoding,那么需要重新解码 str = typeof body !== 'string' && encoding !== null ? iconv.decode(body, encoding) : body // 这里不同解析器,会传入不同 parse req.body = parse(str) } catch (err) { next(createError(400, err, { body: str, type: err.type || 'entity.parse.failed' })) return } next() }) } // 获取请求体 stream // 1. 获取压缩编码格式,如果有压缩需要先解压 // 2. 返回 stream function contentstream (req, debug, inflate) { var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() var length = req.headers['content-length'] var stream debug('content-encoding "%s"', encoding) if (inflate === false && encoding !== 'identity') { throw createError(415, 'content encoding unsupported', { encoding: encoding, type: 'encoding.unsupported' }) } switch (encoding) { case 'deflate': stream = zlib.createInflate() debug('inflate body') req.pipe(stream) break case 'gzip': stream = zlib.createGunzip() debug('gunzip body') req.pipe(stream) break case 'identity': stream = req stream.length = length break default: throw createError(415, 'unsupported content encoding "' + encoding + '"', { encoding: encoding, type: 'encoding.unsupported' }) } return stream } 5. 一些疑问 1. 为什么要对 charset 进行处理

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjwyf.html