65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
![]() |
import { CancellationContext, ERRORS, EVENTS } from '../utils'
|
|||
|
import { BaseHandler } from './BaseHandler'
|
|||
|
|
|||
|
import type http from 'node:http'
|
|||
|
|
|||
|
export class DeleteHandler extends BaseHandler {
|
|||
|
/**
|
|||
|
* 处理DELETE请求的核心方法
|
|||
|
* @param req HTTP请求对象,包含请求头、请求体等信息
|
|||
|
* @param res HTTP响应对象,用于返回响应状态和数据
|
|||
|
* @param context 取消上下文,用于处理请求取消逻辑
|
|||
|
* @returns 返回处理后的HTTP响应对象
|
|||
|
*
|
|||
|
* 技术原理:
|
|||
|
* - 通过HTTP DELETE方法删除指定资源
|
|||
|
* - 使用锁机制保证并发安全
|
|||
|
* - 支持自定义请求处理钩子
|
|||
|
*
|
|||
|
* 优化建议:
|
|||
|
* - 可考虑添加批量删除支持
|
|||
|
* - 可优化锁机制,使用更细粒度的锁
|
|||
|
*/
|
|||
|
async send(
|
|||
|
req: http.IncomingMessage,
|
|||
|
res: http.ServerResponse,
|
|||
|
context: CancellationContext
|
|||
|
) {
|
|||
|
// 从请求中提取文件ID
|
|||
|
const id = this.getFileIdFromRequest(req)
|
|||
|
// 文件ID不存在时抛出异常
|
|||
|
if (!id) {
|
|||
|
throw ERRORS.FILE_NOT_FOUND
|
|||
|
}
|
|||
|
|
|||
|
// 执行自定义的请求处理钩子
|
|||
|
if (this.options.onIncomingRequest) {
|
|||
|
await this.options.onIncomingRequest(req, res, id)
|
|||
|
}
|
|||
|
|
|||
|
// 获取文件操作锁,保证并发安全
|
|||
|
const lock = await this.acquireLock(req, id, context)
|
|||
|
try {
|
|||
|
// 检查是否禁止删除已完成的上传
|
|||
|
if (this.options.disableTerminationForFinishedUploads) {
|
|||
|
const upload = await this.store.getUpload(id)
|
|||
|
// 上传已完成时抛出异常
|
|||
|
if (upload.offset === upload.size) {
|
|||
|
throw ERRORS.INVALID_TERMINATION
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 从存储中删除指定文件
|
|||
|
await this.store.remove(id)
|
|||
|
} finally {
|
|||
|
// 无论成功与否,最终都要释放锁
|
|||
|
await lock.unlock()
|
|||
|
}
|
|||
|
// 返回204 No Content响应
|
|||
|
const writtenRes = this.write(res, 204, {})
|
|||
|
// 触发删除完成事件
|
|||
|
this.emit(EVENTS.POST_TERMINATE, req, writtenRes, id)
|
|||
|
return writtenRes
|
|||
|
}
|
|||
|
}
|