| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 | 
							- 'use strict'
 
- const EventEmitter = require('node:events').EventEmitter
 
- const inherits = require('node:util').inherits
 
- const getLimit = require('../../../lib/utils/getLimit')
 
- const StreamSearch = require('../../streamsearch/sbmh')
 
- const B_DCRLF = Buffer.from('\r\n\r\n')
 
- const RE_CRLF = /\r\n/g
 
- const RE_HDR = /^([^:]+):[ \t]?([\x00-\xFF]+)?$/ // eslint-disable-line no-control-regex
 
- function HeaderParser (cfg) {
 
-   EventEmitter.call(this)
 
-   cfg = cfg || {}
 
-   const self = this
 
-   this.nread = 0
 
-   this.maxed = false
 
-   this.npairs = 0
 
-   this.maxHeaderPairs = getLimit(cfg, 'maxHeaderPairs', 2000)
 
-   this.maxHeaderSize = getLimit(cfg, 'maxHeaderSize', 80 * 1024)
 
-   this.buffer = ''
 
-   this.header = {}
 
-   this.finished = false
 
-   this.ss = new StreamSearch(B_DCRLF)
 
-   this.ss.on('info', function (isMatch, data, start, end) {
 
-     if (data && !self.maxed) {
 
-       if (self.nread + end - start >= self.maxHeaderSize) {
 
-         end = self.maxHeaderSize - self.nread + start
 
-         self.nread = self.maxHeaderSize
 
-         self.maxed = true
 
-       } else { self.nread += (end - start) }
 
-       self.buffer += data.toString('binary', start, end)
 
-     }
 
-     if (isMatch) { self._finish() }
 
-   })
 
- }
 
- inherits(HeaderParser, EventEmitter)
 
- HeaderParser.prototype.push = function (data) {
 
-   const r = this.ss.push(data)
 
-   if (this.finished) { return r }
 
- }
 
- HeaderParser.prototype.reset = function () {
 
-   this.finished = false
 
-   this.buffer = ''
 
-   this.header = {}
 
-   this.ss.reset()
 
- }
 
- HeaderParser.prototype._finish = function () {
 
-   if (this.buffer) { this._parseHeader() }
 
-   this.ss.matches = this.ss.maxMatches
 
-   const header = this.header
 
-   this.header = {}
 
-   this.buffer = ''
 
-   this.finished = true
 
-   this.nread = this.npairs = 0
 
-   this.maxed = false
 
-   this.emit('header', header)
 
- }
 
- HeaderParser.prototype._parseHeader = function () {
 
-   if (this.npairs === this.maxHeaderPairs) { return }
 
-   const lines = this.buffer.split(RE_CRLF)
 
-   const len = lines.length
 
-   let m, h
 
-   for (var i = 0; i < len; ++i) { // eslint-disable-line no-var
 
-     if (lines[i].length === 0) { continue }
 
-     if (lines[i][0] === '\t' || lines[i][0] === ' ') {
 
-       // folded header content
 
-       // RFC2822 says to just remove the CRLF and not the whitespace following
 
-       // it, so we follow the RFC and include the leading whitespace ...
 
-       if (h) {
 
-         this.header[h][this.header[h].length - 1] += lines[i]
 
-         continue
 
-       }
 
-     }
 
-     const posColon = lines[i].indexOf(':')
 
-     if (
 
-       posColon === -1 ||
 
-       posColon === 0
 
-     ) {
 
-       return
 
-     }
 
-     m = RE_HDR.exec(lines[i])
 
-     h = m[1].toLowerCase()
 
-     this.header[h] = this.header[h] || []
 
-     this.header[h].push((m[2] || ''))
 
-     if (++this.npairs === this.maxHeaderPairs) { break }
 
-   }
 
- }
 
- module.exports = HeaderParser
 
 
  |