优化body解析

master
yutent 2024-07-10 16:44:17 +08:00
parent 9d66a77b4d
commit 8afca9afaa
7 changed files with 66 additions and 18 deletions

View File

@ -197,6 +197,9 @@ export default class Request {
} }
} }
}) })
.on('buffer', buf => {
this.#body = buf
})
.on('error', out.reject) .on('error', out.reject)
.on('end', _ => { .on('end', _ => {
if (contentType.includes('urlencoded')) { if (contentType.includes('urlencoded')) {

View File

@ -6,7 +6,7 @@ import { EventEmitter } from 'node:events'
import File from './file.js' import File from './file.js'
import { MultipartParser } from './multipart_parser.js' import { MultipartParser } from './multipart_parser.js'
import { UrlencodedParser } from './urlencoded_parser.js' import { UrlencodedParser } from './urlencoded_parser.js'
import { OctetParser, EmptyParser } from './octet_parser.js' import { OctetParser, BufferParser, EmptyParser } from './octet_parser.js'
import { JSONParser } from './json_parser.js' import { JSONParser } from './json_parser.js'
function randomPath(uploadDir) { function randomPath(uploadDir) {
@ -98,8 +98,8 @@ export default class IncomingForm extends EventEmitter {
let value = Buffer.from('') let value = Buffer.from('')
part part
.on('data', buff => { .on('data', buf => {
value = Buffer.concat([value, buff]) value = Buffer.concat([value, buf])
}) })
.on('end', () => { .on('end', () => {
this.emit('field', part.name, value.toString(this.encoding)) this.emit('field', part.name, value.toString(this.encoding))
@ -167,7 +167,7 @@ export default class IncomingForm extends EventEmitter {
return this.#createJsonParser() return this.#createJsonParser()
} }
this.#handleError(new TypeError('unknown content-type: ' + contentType)) this.#createBufferParser()
} }
#parseContentLength() { #parseContentLength() {
@ -316,6 +316,21 @@ export default class IncomingForm extends EventEmitter {
.on('error', err => this.#handleError(err)) .on('error', err => this.#handleError(err))
} }
#createBufferParser() {
this.#parser = new BufferParser()
if (this.bytesExpected) {
this.#parser.initLength(this.bytesExpected)
}
this.#parser
.on('buffer', buf => {
this.emit('buffer', buf)
})
.on('end', () => this.#handleEnd())
.on('error', err => this.#handleError(err))
}
#clearUploads() { #clearUploads() {
while (this.#openedFiles.length) { while (this.#openedFiles.length) {
let file = this.#openedFiles.pop() let file = this.#openedFiles.pop()

View File

@ -1,7 +1,7 @@
import { EventEmitter } from 'node:events' import { EventEmitter } from 'node:events'
export class JSONParser extends EventEmitter { export class JSONParser extends EventEmitter {
#buff = Buffer.from('') #buf = Buffer.from('')
#byteLen = 0 #byteLen = 0
initLength(length) { initLength(length) {
@ -9,12 +9,12 @@ export class JSONParser extends EventEmitter {
} }
write(buffer) { write(buffer) {
this.#buff = Buffer.concat([this.#buff, buffer]) this.#buf = Buffer.concat([this.#buf, buffer])
} }
end() { end() {
if (this.#buff.length === this.#byteLen) { if (this.#buf.length === this.#byteLen) {
let data = this.#buff.toString() let data = this.#buf.toString()
let fields = data let fields = data
try { try {
fields = JSON.parse(data) fields = JSON.parse(data)
@ -28,14 +28,14 @@ export class JSONParser extends EventEmitter {
this.emit('field', false, fields) this.emit('field', false, fields)
this.emit('end') this.emit('end')
this.#buff = null this.#buf = null
} else { } else {
this.emit( this.emit(
'error', 'error',
new Error( new Error(
`The uploaded data is incomplete. Expected ${ `The uploaded data is incomplete. Expected ${
this.#byteLen this.#byteLen
}, Received ${this.#buff.length} .` }, Received ${this.#buf.length} .`
) )
) )
} }

View File

@ -73,11 +73,11 @@ export class MultipartParser {
this[k + 'Mark'] = v this[k + 'Mark'] = v
} }
#emit(name, buff, idx, cleanup) { #emit(name, buf, idx, cleanup) {
let mark = name + 'Mark' let mark = name + 'Mark'
if (this[mark] !== void 0) { if (this[mark] !== void 0) {
let start = this[mark] let start = this[mark]
let end = buff.length let end = buf.length
if (cleanup) { if (cleanup) {
end = idx end = idx
@ -89,7 +89,7 @@ export class MultipartParser {
if (start === end) { if (start === end) {
return return
} }
this['$' + name](buff.slice(start, end)) this['$' + name](buf.slice(start, end))
} }
} }

View File

@ -47,6 +47,36 @@ export class OctetParser extends EventEmitter {
} }
} }
export class BufferParser extends EventEmitter {
#buf = Buffer.from('')
#byteLen = 0
initLength(length) {
this.#byteLen = length
}
write(buffer) {
this.#buf = Buffer.concat([this.#buf, buffer])
}
end() {
if (this.#buf.length === this.#byteLen) {
this.emit('buffer', this.#buf)
this.emit('end')
this.#buf = null
} else {
this.emit(
'error',
new Error(
`The uploaded data is incomplete. Expected ${
this.#byteLen
}, Received ${this.#buf.length} .`
)
)
}
}
}
export class EmptyParser extends EventEmitter { export class EmptyParser extends EventEmitter {
write() {} write() {}

View File

@ -8,17 +8,17 @@ import { parse } from 'node:querystring'
import { EventEmitter } from 'node:events' import { EventEmitter } from 'node:events'
export class UrlencodedParser extends EventEmitter { export class UrlencodedParser extends EventEmitter {
#buff = Buffer.from('') #buf = Buffer.from('')
write(buffer) { write(buffer) {
this.#buff = Buffer.concat([this.#buff, buffer]) this.#buf = Buffer.concat([this.#buf, buffer])
} }
end() { end() {
let data = this.#buff.toString() let data = this.#buf.toString()
let fields = parse(data) let fields = parse(data)
this.#buff = null this.#buf = null
this.emit('field', fields) this.emit('field', fields)
this.emit('end') this.emit('end')

View File

@ -1,6 +1,6 @@
{ {
"name": "@gm5/request", "name": "@gm5/request",
"version": "2.0.4", "version": "2.0.5",
"description": "对Http的Request进一步封装, 提供常用的API", "description": "对Http的Request进一步封装, 提供常用的API",
"main": "index.js", "main": "index.js",
"author": "yutent", "author": "yutent",