origin/packages/tus/src/validators/HeaderValidator.ts

138 lines
3.5 KiB
TypeScript
Raw Normal View History

2025-01-06 08:45:23 +08:00
/**
* TUS协议头部验证器
*
* TUS协议中各种HTTP头部的验证逻辑
* TUS是一个用于可恢复文件上传的开放协议
*
* @version 1.0.0
* @see https://tus.io/protocols/resumable-upload.html
*/
import { Metadata, TUS_VERSION, TUS_RESUMABLE } from "../utils"
/** 验证器函数类型定义,接收可选的字符串值,返回布尔值表示验证结果 */
type validator = (value?: string) => boolean
/**
* TUS协议头部验证器映射表
* TUS协议规定的HTTP头部的验证规则
*/
export const validators = new Map<string, validator>([
[
'upload-offset',
/**
* Upload-Offset头部验证
*
*
*/
(value) => {
const n = Number(value)
return Number.isInteger(n) && String(n) === value && n >= 0
},
],
[
'upload-length',
/**
* Upload-Length头部验证
*
*
*/
(value) => {
const n = Number(value)
return Number.isInteger(n) && String(n) === value && n >= 0
},
],
[
'upload-defer-length',
/**
* Upload-Defer-Length头部验证
* ,
* 1,
*/
(value) => value === '1',
],
[
'upload-metadata',
/**
* Upload-Metadata头部验证
*
*
*
* ASCII编码,Base64编码
*
*/
(value) => {
try {
Metadata.parse(value)
return true
} catch {
return false
}
},
],
[
'x-forwarded-proto',
/**
* X-Forwarded-Proto头部验证
*
* http或https
*/
(value) => {
if (value === 'http' || value === 'https') {
return true
}
return false
},
],
[
'tus-version',
/**
* Tus-Version头部验证
*
* ,
*/
(value) => {
return TUS_VERSION.includes(value as any)
},
],
[
'tus-resumable',
/**
* Tus-Resumable头部验证
* OPTIONS请求外的每个请求和响应都必须包含
* 使
*/
(value) => value === TUS_RESUMABLE,
],
['content-type', (value) => value === 'application/offset+octet-stream'],
[
'upload-concat',
/**
* Upload-Concat头部验证
*
* partial
* final开头,URL列表
*/
(value) => {
if (!value) return false
const valid_partial = value === 'partial'
const valid_final = value.startsWith('final;')
return valid_partial || valid_final
},
],
])
/**
* HTTP头部值是否符合TUS协议规范
* @param name
* @param value
* @returns
*/
export function validateHeader(name: string, value?: string): boolean {
const lowercaseName = name.toLowerCase()
if (!validators.has(lowercaseName)) {
return true
}
return validators.get(lowercaseName)!(value)
}