调整语法, 兼容bun

v2
yutent 2023-10-25 18:45:16 +08:00
parent 148684bf35
commit 6b3a44d387
8 changed files with 913 additions and 912 deletions

View File

@ -14,11 +14,11 @@ import PATH from 'path'
const DEFAULT_FORM_TYPE = 'application/x-www-form-urlencoded'
var __dirname = PATH.dirname(URL.fileURLToPath(import.meta.url))
const __dirname = PATH.dirname(URL.fileURLToPath(import.meta.url))
var tmpdir = PATH.resolve(__dirname, '.tmp/')
var encode = encodeURIComponent
var decode = decodeURIComponent
const tmpdir = PATH.resolve(__dirname, '.tmp/')
const encode = encodeURIComponent
const decode = decodeURIComponent
if (fs.isdir(tmpdir)) {
fs.rm(tmpdir, true)
@ -44,7 +44,6 @@ export default class Request {
hideProperty(this, '__GET__', null)
hideProperty(this, '__POST__', null)
hideProperty(this, '__COOKIE__', parseCookie(this.header('cookie') || ''))
this.__fixUrl()
}

View File

@ -4,16 +4,16 @@
*/
// var KEY_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/
var SPLIT_REGEXP = /; */
const SPLIT_REGEXP = /; */
// var encode = encodeURIComponent
var decode = decodeURIComponent
const decode = decodeURIComponent
/**
* [parse 格式化字符串]
*/
export function parseCookie(str) {
var obj = {}
var pairs
let obj = {}
let pairs
if (typeof str !== 'string') {
return {}
@ -27,8 +27,8 @@ export function parseCookie(str) {
continue
}
var key = item[0].trim()
var val = item[1].trim()
let key = item[0].trim()
let val = item[1].trim()
obj[key] = decode(val)
}

View File

@ -1,38 +1,30 @@
import util from 'util'
import { WriteStream } from 'fs'
import { EventEmitter } from 'events'
import crypto from 'crypto'
import { WriteStream } from 'node:fs'
import { EventEmitter } from 'node:events'
export default function File(properties) {
EventEmitter.call(this)
this.size = 0
this.path = null
this.name = null
this.type = null
this.hash = null
this.lastModifiedDate = null
export default class File extends EventEmitter {
this._writeStream = null
#stream = null
for (var key in properties) {
this[key] = properties[key]
size = 0
path = null
name = null
type = null
lastModifiedDate = null
constructor(props = {}){
super()
for (var key in props) {
this[key] = props[key]
}
}
if (typeof this.hash === 'string') {
this.hash = crypto.createHash(properties.hash)
} else {
this.hash = null
open() {
this.#stream = new WriteStream(this.path)
}
}
util.inherits(File, EventEmitter)
File.prototype.open = function() {
this._writeStream = new WriteStream(this.path)
}
File.prototype.toJSON = function() {
toJSON() {
return {
size: this.size,
path: this.path,
@ -43,28 +35,27 @@ File.prototype.toJSON = function() {
filename: this.filename,
mime: this.mime
}
}
File.prototype.write = function(buffer, cb) {
var self = this
if (self.hash) {
self.hash.update(buffer)
}
this._writeStream.write(buffer, function() {
self.lastModifiedDate = new Date()
self.size += buffer.length
self.emit('progress', self.size)
write(buffer, cb) {
this.#stream.write(buffer, _ =>{
this.lastModifiedDate = new Date()
this.size += buffer.length
this.emit('progress', this.size)
cb()
})
}
File.prototype.end = function(cb) {
var self = this
if (self.hash) {
self.hash = self.hash.digest('hex')
}
this._writeStream.end(function() {
self.emit('end')
end(cb) {
this.#stream.end(() => {
this.emit('end')
cb()
})
}
}

View File

@ -1,21 +1,31 @@
import crypto from 'crypto'
import fs from 'fs'
import util from 'util'
import path from 'path'
import crypto from 'node:crypto'
import fs from 'node:fs'
import util from 'node:util'
import path from 'node:path'
import File from './file.js'
import { EventEmitter } from 'events'
import { Stream } from 'stream'
import { StringDecoder } from 'string_decoder'
import { EventEmitter } from 'node:events'
import { Stream } from 'node:stream'
import { StringDecoder } from 'node:string_decoder'
import { MultipartParser } from './multipart_parser.js'
import { QuerystringParser } from './querystring_parser.js'
import { OctetParser } from './octet_parser.js'
import { JSONParser } from './json_parser.js'
export default function IncomingForm(opts) {
EventEmitter.call(this)
opts = opts || {}
function dummyParser(self) {
return {
end: function() {
self.ended = true
self._maybeEnd()
return null
}
}
}
export default class IncomingForm{
constructor(opts = {}) {
this.error = null
this.ended = false
@ -37,11 +47,13 @@ export default function IncomingForm(opts) {
this._flushing = 0
this._fieldsSize = 0
this.openedFiles = []
}
util.inherits(IncomingForm, EventEmitter)
}
IncomingForm.prototype.parse = function(req, cb) {
parse(req, cb) {
this.pause = function() {
try {
req.pause()
@ -129,15 +141,15 @@ IncomingForm.prototype.parse = function(req, cb) {
})
return this
}
}
IncomingForm.prototype.writeHeaders = function(headers) {
writeHeaders(headers) {
this.headers = headers
this._parseContentLength()
this._parseContentType()
}
}
IncomingForm.prototype.write = function(buffer) {
write(buffer) {
if (this.error) {
return
}
@ -163,24 +175,24 @@ IncomingForm.prototype.write = function(buffer) {
}
return bytesParsed
}
}
IncomingForm.prototype.pause = function() {
pause() {
// this does nothing, unless overwritten in IncomingForm.parse
return false
}
}
IncomingForm.prototype.resume = function() {
resume() {
// this does nothing, unless overwritten in IncomingForm.parse
return false
}
}
IncomingForm.prototype.onPart = function(part) {
onPart(part) {
// this method can be overwritten by the user
this.handlePart(part)
}
}
IncomingForm.prototype.handlePart = function(part) {
handlePart(part) {
var self = this
if (part.filename === undefined) {
@ -239,19 +251,10 @@ IncomingForm.prototype.handlePart = function(part) {
self._maybeEnd()
})
})
}
function dummyParser(self) {
return {
end: function() {
self.ended = true
self._maybeEnd()
return null
}
}
}
IncomingForm.prototype._parseContentType = function() {
_parseContentType() {
if (this.bytesExpected === 0) {
this._parser = dummyParser(this)
return
@ -295,9 +298,9 @@ IncomingForm.prototype._parseContentType = function() {
this.headers['content-type']
)
)
}
}
IncomingForm.prototype._error = function(err) {
_error(err) {
if (this.error || this.ended) {
return
}
@ -311,9 +314,9 @@ IncomingForm.prototype._error = function(err) {
setTimeout(fs.unlink, 0, file.path, function(error) {})
})
}
}
}
IncomingForm.prototype._parseContentLength = function() {
_parseContentLength() {
this.bytesReceived = 0
if (this.headers['content-length']) {
this.bytesExpected = parseInt(this.headers['content-length'], 10)
@ -324,13 +327,13 @@ IncomingForm.prototype._parseContentLength = function() {
if (this.bytesExpected !== null) {
this.emit('progress', this.bytesReceived, this.bytesExpected)
}
}
}
IncomingForm.prototype._newParser = function() {
_newParser() {
return new MultipartParser()
}
}
IncomingForm.prototype._initMultipart = function(boundary) {
_initMultipart(boundary) {
this.type = 'multipart'
var parser = new MultipartParser(),
@ -436,9 +439,9 @@ IncomingForm.prototype._initMultipart = function(boundary) {
}
this._parser = parser
}
}
IncomingForm.prototype._fileName = function(headerValue) {
_fileName(headerValue) {
var m = headerValue.match(/\bfilename="(.*?)"($|; )/i)
if (!m) return
@ -448,9 +451,9 @@ IncomingForm.prototype._fileName = function(headerValue) {
return String.fromCharCode(code)
})
return filename
}
}
IncomingForm.prototype._initUrlencoded = function() {
_initUrlencoded() {
this.type = 'urlencoded'
var parser = new QuerystringParser(this.maxFields)
@ -465,9 +468,9 @@ IncomingForm.prototype._initUrlencoded = function() {
}
this._parser = parser
}
}
IncomingForm.prototype._initOctetStream = function() {
_initOctetStream() {
this.type = 'octet-stream'
var filename = this.headers['x-file-name']
var mime = this.headers['content-type']
@ -521,9 +524,9 @@ IncomingForm.prototype._initOctetStream = function() {
self._parser.once('doneWritingFile', done)
}
})
}
}
IncomingForm.prototype._initJSONencoded = function() {
_initJSONencoded() {
this.type = 'json'
var parser = new JSONParser(),
@ -543,9 +546,9 @@ IncomingForm.prototype._initJSONencoded = function() {
}
this._parser = parser
}
}
IncomingForm.prototype._uploadPath = function(filename) {
_uploadPath(filename) {
var name = 'upload_'
var buf = crypto.randomBytes(16)
for (var i = 0; i < buf.length; ++i) {
@ -560,12 +563,15 @@ IncomingForm.prototype._uploadPath = function(filename) {
}
return path.join(this.uploadDir, name)
}
}
IncomingForm.prototype._maybeEnd = function() {
_maybeEnd() {
if (!this.ended || this._flushing || this.error) {
return
}
this.emit('end')
}
}

View File

@ -1,13 +1,13 @@
export function JSONParser() {
this.data = Buffer.from('')
this.bytesWritten = 0
}
export class JSONParser {
JSONParser.prototype.initWithLength = function(length) {
data = Buffer.from('')
bytesWritten = 0
initWithLength(length) {
this.data = Buffer.alloc(length)
}
}
JSONParser.prototype.write = function(buffer) {
write(buffer) {
if (this.data.length >= this.bytesWritten + buffer.length) {
buffer.copy(this.data, this.bytesWritten)
} else {
@ -15,9 +15,9 @@ JSONParser.prototype.write = function(buffer) {
}
this.bytesWritten += buffer.length
return buffer.length
}
}
JSONParser.prototype.end = function() {
end() {
var data = this.data.toString('utf8')
var fields
try {
@ -30,4 +30,7 @@ JSONParser.prototype.end = function() {
this.data = null
this.onEnd()
}
}

View File

@ -30,24 +30,25 @@ var s = 0,
return c | 0x20
}
export function MultipartParser() {
this.boundary = null
this.boundaryChars = null
this.lookbehind = null
this.state = S.PARSER_UNINITIALIZED
export class MultipartParser {
boundary = null
boundaryChars = null
lookbehind = null
state = S.PARSER_UNINITIALIZED
this.index = null
this.flags = 0
}
index = null
flags = 0
MultipartParser.stateToString = function(stateNumber) {
static stateToString(stateNumber) {
for (var state in S) {
var number = S[state]
if (number === stateNumber) return state
}
}
}
MultipartParser.prototype.initWithBoundary = function(str) {
initWithBoundary(str) {
this.boundary = Buffer.alloc(str.length + 4)
this.boundary.write('\r\n--', 0)
this.boundary.write(str, 4)
@ -58,9 +59,9 @@ MultipartParser.prototype.initWithBoundary = function(str) {
for (var i = 0; i < this.boundary.length; i++) {
this.boundaryChars[this.boundary[i]] = true
}
}
}
MultipartParser.prototype.write = function(buffer) {
write(buffer) {
var self = this,
i = 0,
len = buffer.length,
@ -300,9 +301,9 @@ MultipartParser.prototype.write = function(buffer) {
this.flags = flags
return len
}
}
MultipartParser.prototype.end = function() {
end() {
var callback = function(self, name) {
var callbackSymbol = 'on' + name.substr(0, 1).toUpperCase() + name.substr(1)
if (callbackSymbol in self) {
@ -320,8 +321,11 @@ MultipartParser.prototype.end = function() {
'MultipartParser.end(): stream ended unexpectedly: ' + this.explain()
)
}
}
explain() {
return 'state = ' + MultipartParser.stateToString(this.state)
}
}
MultipartParser.prototype.explain = function() {
return 'state = ' + MultipartParser.stateToString(this.state)
}

View File

@ -1,17 +1,15 @@
import { EventEmitter } from 'events'
import util from 'util'
export function OctetParser() {
EventEmitter.call(this)
}
util.inherits(OctetParser, EventEmitter)
OctetParser.prototype.write = function(buffer) {
export class OctetParser extends EventEmitter {
write(buffer) {
this.emit('data', buffer)
return buffer.length
}
OctetParser.prototype.end = function() {
end () {
this.emit('end')
}
}

View File

@ -1,6 +1,6 @@
// This is a buffering parser, not quite as nice as the multipart one.
// If I find time I'll rewrite this to be fully streaming as well
import querystring from 'querystring'
import {parse} from 'node:querystring'
export class QuerystringParser {
constructor(maxKeys) {
@ -14,7 +14,7 @@ export class QuerystringParser {
}
end() {
var fields = querystring.parse(this.buffer, '&', '=', {
var fields = parse(this.buffer, '&', '=', {
maxKeys: this.maxKeys
})
for (var field in fields) {