training_data/packages/tus/src/handlers/HeadHandler.ts

91 lines
2.7 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 模块HeadHandler
* 功能处理TUS协议的HEAD请求用于获取上传文件的状态信息
* 使用场景:在文件分片上传过程中,客户端需要定期查询上传进度时使用
*/
import { CancellationContext, ERRORS, Upload, Metadata } from '../utils'
import { BaseHandler } from './BaseHandler'
import type http from 'node:http'
/**
* HeadHandler类
* 核心功能处理TUS协议的HEAD请求返回文件上传的元数据和进度信息
* 设计模式继承自BaseHandler采用模板方法模式
* 使用示例:
* const handler = new HeadHandler(store, options)
* await handler.send(req, res, context)
*/
export class HeadHandler extends BaseHandler {
/**
* 处理HEAD请求的核心方法
* @param req HTTP请求对象
* @param res HTTP响应对象
* @param context 取消操作的上下文
* @returns 返回HTTP响应
* @throws ERRORS.FILE_NOT_FOUND 文件ID不存在时抛出
* @throws ERRORS.FILE_NO_LONGER_EXISTS 文件已过期时抛出
*/
async send(
req: http.IncomingMessage,
res: http.ServerResponse,
context: CancellationContext
) {
// 从请求中提取文件ID
const id = this.getFileIdFromRequest(req)
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)
let file: Upload
try {
// 从存储中获取文件上传信息
file = await this.store.getUpload(id)
} finally {
// 无论成功与否,都释放锁
await lock.unlock()
}
// 检查文件是否已过期
const now = new Date()
if (
this.store.hasExtension('expiration') &&
this.store.getExpiration() > 0 &&
file.creation_date &&
now > new Date(new Date(file.creation_date).getTime() + this.store.getExpiration())
) {
throw ERRORS.FILE_NO_LONGER_EXISTS
}
// 设置响应头,防止缓存
res.setHeader('Cache-Control', 'no-store')
// 返回当前上传偏移量
res.setHeader('Upload-Offset', file.offset)
// 处理文件大小信息
if (file.sizeIsDeferred) {
// 如果文件大小未知,设置延迟长度标志
res.setHeader('Upload-Defer-Length', '1')
} else {
// 如果文件大小已知,返回实际大小
res.setHeader('Upload-Length', file.size as number)
}
// 处理文件元数据
if (file.metadata !== undefined) {
// 将元数据转换为字符串格式返回
res.setHeader('Upload-Metadata', Metadata.stringify(file.metadata) as string)
}
// 结束响应
return res.end()
}
}