mirror of
https://github.com/ZSCGR/CloudFlare-ImgBed.git
synced 2026-08-13 04:03:42 +08:00
Cloudflare Workers and Pages already provide the Fetch/Web APIs needed for WebDAV verbs, so the storage integration uses a small local helper instead of adding a Node-oriented WebDAV client. The channel now participates in upload, read, delete, move, rename, channel listing, and runtime config, with chunked uploads explicitly guarded because WebDAV has no portable server-side compose primitive. Constraint: Preserve Pages Functions and generated Worker deployment paths Constraint: No new npm dependency for WebDAV client behavior Rejected: Add a WebDAV npm client | likely Node API/compatibility and package-lock churn Rejected: Treat WebDAV as External URL only | not a complete storage channel lifecycle Confidence: high Scope-risk: moderate Directive: WebDAV here is third-party storage; keep it distinct from the built-in /dav server settings Tested: npm test; node worker/generate-routes.js; npx wrangler deploy --dry-run --config worker/wrangler.toml; git diff --cached --check Not-tested: Live third-party WebDAV provider credentials; Digest-only WebDAV authentication
336 lines
11 KiB
JavaScript
336 lines
11 KiB
JavaScript
import { getDatabase } from '../../../utils/databaseAdapter.js';
|
|
import { normalizeWebDAVHeaders } from '../../../utils/webdavAPI.js';
|
|
|
|
export async function onRequest(context) {
|
|
// 上传设置相关,GET方法读取设置,POST方法保存设置
|
|
const {
|
|
request, // same as existing Worker API
|
|
env, // same as existing Worker API
|
|
params, // if filename includes [id] or [[path]]
|
|
waitUntil, // same as ctx.waitUntil in existing Worker API
|
|
next, // used for middleware or to fetch assets
|
|
data, // arbitrary space for passing data between middlewares
|
|
} = context;
|
|
|
|
const db = getDatabase(env);
|
|
|
|
// GET读取设置
|
|
if (request.method === 'GET') {
|
|
const settings = await getUploadConfig(db, env)
|
|
|
|
return new Response(JSON.stringify(settings), {
|
|
headers: {
|
|
'content-type': 'application/json',
|
|
},
|
|
})
|
|
}
|
|
|
|
// POST保存设置
|
|
if (request.method === 'POST') {
|
|
const body = await request.json()
|
|
const settings = body
|
|
// 兼容旧前端包:如果旧包尚未提交 webdav 配置,保留已有 WebDAV 渠道,避免保存其他上传设置时被清空。
|
|
if (settings.webdav === undefined) {
|
|
const existingSettingsStr = await db.get('manage@sysConfig@upload')
|
|
const existingSettings = existingSettingsStr ? JSON.parse(existingSettingsStr) : {}
|
|
if (existingSettings.webdav !== undefined) {
|
|
settings.webdav = existingSettings.webdav
|
|
}
|
|
}
|
|
|
|
// 写入数据库
|
|
await db.put('manage@sysConfig@upload', JSON.stringify(settings))
|
|
|
|
return new Response(JSON.stringify(settings), {
|
|
headers: {
|
|
'content-type': 'application/json',
|
|
},
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
export async function getUploadConfig(db, env) {
|
|
const settings = {}
|
|
// 读取数据库中的设置
|
|
const settingsStr = await db.get('manage@sysConfig@upload')
|
|
const settingsKV = settingsStr ? JSON.parse(settingsStr) : {}
|
|
|
|
// =====================读取tg渠道配置=====================
|
|
const telegram = {}
|
|
|
|
const telegramChannels = []
|
|
telegram.channels = telegramChannels
|
|
if (env.TG_BOT_TOKEN) {
|
|
telegramChannels.push({
|
|
id: 1,
|
|
name: 'Telegram_env',
|
|
type: 'telegram',
|
|
savePath: 'environment variable',
|
|
botToken: env.TG_BOT_TOKEN,
|
|
chatId: env.TG_CHAT_ID,
|
|
proxyUrl: env.TG_PROXY_URL || '', // 可选的代理 URL
|
|
enabled: true,
|
|
fixed: true,
|
|
})
|
|
}
|
|
for (const tg of settingsKV.telegram?.channels || []) {
|
|
// 如果savePath是environment variable,修改可变参数
|
|
if (tg.savePath === 'environment variable') {
|
|
// 如果环境变量未删除,进行覆盖操作
|
|
if (telegramChannels[0]) {
|
|
telegramChannels[0].enabled = tg.enabled
|
|
telegramChannels[0].proxyUrl = tg.proxyUrl
|
|
}
|
|
|
|
continue
|
|
}
|
|
// id自增
|
|
tg.id = telegramChannels.length + 1
|
|
telegramChannels.push(tg)
|
|
}
|
|
|
|
// 负载均衡
|
|
const tgLoadBalance = settingsKV.telegram?.loadBalance || {
|
|
enabled: false,
|
|
channels: [],
|
|
}
|
|
telegram.loadBalance = tgLoadBalance
|
|
|
|
|
|
|
|
// =====================读取r2渠道配置=====================
|
|
const cfr2 = {}
|
|
const cfr2Channels = []
|
|
cfr2.channels = cfr2Channels
|
|
if (env.img_r2) {
|
|
cfr2Channels.push({
|
|
id: 1,
|
|
name: 'R2_env',
|
|
type: 'cfr2',
|
|
savePath: 'environment variable',
|
|
publicUrl: env.R2PublicUrl,
|
|
enabled: true,
|
|
fixed: true,
|
|
})
|
|
}
|
|
for (const r2 of settingsKV.cfr2?.channels || []) {
|
|
// 如果savePath是environment variable,修改可变参数
|
|
if (r2.savePath === 'environment variable') {
|
|
// 如果环境变量未删除,进行覆盖操作
|
|
if (cfr2Channels[0]) {
|
|
cfr2Channels[0].publicUrl = r2.publicUrl
|
|
cfr2Channels[0].enabled = r2.enabled
|
|
cfr2Channels[0].quota = r2.quota // 保留容量限制配置
|
|
}
|
|
|
|
continue
|
|
}
|
|
// id自增
|
|
r2.id = cfr2Channels.length + 1
|
|
cfr2Channels.push(r2)
|
|
}
|
|
|
|
// 负载均衡
|
|
const r2LoadBalance = settingsKV.cfr2?.loadBalance || {
|
|
enabled: false,
|
|
channels: [],
|
|
}
|
|
cfr2.loadBalance = r2LoadBalance
|
|
|
|
|
|
// =====================读取s3渠道配置=====================
|
|
const s3 = {}
|
|
const s3Channels = []
|
|
s3.channels = s3Channels
|
|
if (env.S3_ACCESS_KEY_ID) {
|
|
s3Channels.push({
|
|
id: 1,
|
|
name: 'S3_env',
|
|
type: 's3',
|
|
savePath: 'environment variable',
|
|
accessKeyId: env.S3_ACCESS_KEY_ID,
|
|
secretAccessKey: env.S3_SECRET_ACCESS_KEY,
|
|
region: env.S3_REGION || 'auto',
|
|
bucketName: env.S3_BUCKET_NAME,
|
|
endpoint: env.S3_ENDPOINT,
|
|
pathStyle: env.S3_PATH_STYLE === 'true',
|
|
cdnDomain: env.S3_CDN_DOMAIN || '', // 可选的 CDN 域名
|
|
enabled: true,
|
|
fixed: true,
|
|
})
|
|
}
|
|
for (const s of settingsKV.s3?.channels || []) {
|
|
// 如果savePath是environment variable,修改可变参数
|
|
if (s.savePath === 'environment variable') {
|
|
// 如果环境变量未删除,进行覆盖操作
|
|
if (s3Channels[0]) {
|
|
s3Channels[0].enabled = s.enabled
|
|
s3Channels[0].quota = s.quota // 保留容量限制配置
|
|
s3Channels[0].cdnDomain = s.cdnDomain // 保留 CDN 域名配置
|
|
}
|
|
|
|
continue
|
|
}
|
|
// id自增
|
|
s.id = s3Channels.length + 1
|
|
s3Channels.push(s)
|
|
}
|
|
|
|
// 负载均衡
|
|
const s3LoadBalance = settingsKV.s3?.loadBalance || {
|
|
enabled: false,
|
|
channels: [],
|
|
}
|
|
s3.loadBalance = s3LoadBalance
|
|
|
|
|
|
// =====================读取 Discord 渠道配置=====================
|
|
const discord = {}
|
|
const discordChannels = []
|
|
discord.channels = discordChannels
|
|
|
|
// 从环境变量读取 Discord 配置
|
|
if (env.DISCORD_BOT_TOKEN) {
|
|
discordChannels.push({
|
|
id: 1,
|
|
name: 'Discord_env',
|
|
type: 'discord',
|
|
savePath: 'environment variable',
|
|
botToken: env.DISCORD_BOT_TOKEN,
|
|
channelId: env.DISCORD_CHANNEL_ID,
|
|
proxyUrl: env.DISCORD_PROXY_URL || '', // 可选的代理 URL
|
|
isNitro: env.DISCORD_IS_NITRO === 'true', // Nitro 会员,支持 25MB
|
|
enabled: true,
|
|
fixed: true,
|
|
})
|
|
}
|
|
|
|
for (const dc of settingsKV.discord?.channels || []) {
|
|
// 如果 savePath 是 environment variable,修改可变参数
|
|
if (dc.savePath === 'environment variable') {
|
|
// 如果环境变量未删除,进行覆盖操作
|
|
if (discordChannels[0]) {
|
|
discordChannels[0].enabled = dc.enabled
|
|
discordChannels[0].proxyUrl = dc.proxyUrl
|
|
discordChannels[0].isNitro = dc.isNitro
|
|
}
|
|
continue
|
|
}
|
|
// id 自增
|
|
dc.id = discordChannels.length + 1
|
|
discordChannels.push(dc)
|
|
}
|
|
|
|
// 负载均衡
|
|
const discordLoadBalance = settingsKV.discord?.loadBalance || {
|
|
enabled: false,
|
|
channels: [],
|
|
}
|
|
discord.loadBalance = discordLoadBalance
|
|
|
|
|
|
// =====================读取 HuggingFace 渠道配置=====================
|
|
const huggingface = {}
|
|
const huggingfaceChannels = []
|
|
huggingface.channels = huggingfaceChannels
|
|
|
|
// 从环境变量读取 HuggingFace 配置
|
|
if (env.HF_TOKEN) {
|
|
huggingfaceChannels.push({
|
|
id: 1,
|
|
name: 'HuggingFace_env',
|
|
type: 'huggingface',
|
|
savePath: 'environment variable',
|
|
token: env.HF_TOKEN,
|
|
repo: env.HF_REPO,
|
|
isPrivate: env.HF_PRIVATE === 'true',
|
|
enabled: true,
|
|
fixed: true,
|
|
})
|
|
}
|
|
|
|
for (const hf of settingsKV.huggingface?.channels || []) {
|
|
// 如果 savePath 是 environment variable,修改可变参数
|
|
if (hf.savePath === 'environment variable') {
|
|
// 如果环境变量未删除,进行覆盖操作
|
|
if (huggingfaceChannels[0]) {
|
|
huggingfaceChannels[0].enabled = hf.enabled
|
|
huggingfaceChannels[0].isPrivate = hf.isPrivate
|
|
}
|
|
continue
|
|
}
|
|
// id 自增
|
|
hf.id = huggingfaceChannels.length + 1
|
|
huggingfaceChannels.push(hf)
|
|
}
|
|
|
|
// 负载均衡
|
|
const huggingfaceLoadBalance = settingsKV.huggingface?.loadBalance || {
|
|
enabled: false,
|
|
channels: [],
|
|
}
|
|
huggingface.loadBalance = huggingfaceLoadBalance
|
|
|
|
|
|
// =====================读取 WebDAV 渠道配置=====================
|
|
const webdav = {}
|
|
const webdavChannels = []
|
|
webdav.channels = webdavChannels
|
|
|
|
// 从环境变量读取 WebDAV 配置
|
|
if (env.WEBDAV_BASE_URL) {
|
|
webdavChannels.push({
|
|
id: 1,
|
|
name: 'WebDAV_env',
|
|
type: 'webdav',
|
|
savePath: 'environment variable',
|
|
baseUrl: env.WEBDAV_BASE_URL,
|
|
username: env.WEBDAV_USERNAME || '',
|
|
password: env.WEBDAV_PASSWORD || '',
|
|
publicUrl: env.WEBDAV_PUBLIC_URL || '',
|
|
headers: normalizeWebDAVHeaders(env.WEBDAV_HEADERS || {}),
|
|
createDirectory: env.WEBDAV_CREATE_DIRECTORY !== 'false',
|
|
enabled: true,
|
|
fixed: true,
|
|
})
|
|
}
|
|
|
|
for (const wd of settingsKV.webdav?.channels || []) {
|
|
// 如果 savePath 是 environment variable,修改可变参数
|
|
if (wd.savePath === 'environment variable') {
|
|
// 如果环境变量未删除,进行覆盖操作
|
|
if (webdavChannels[0]) {
|
|
webdavChannels[0].enabled = wd.enabled
|
|
webdavChannels[0].publicUrl = wd.publicUrl || webdavChannels[0].publicUrl
|
|
webdavChannels[0].headers = normalizeWebDAVHeaders(wd.headers || wd.customHeaders || webdavChannels[0].headers)
|
|
webdavChannels[0].createDirectory = wd.createDirectory !== false
|
|
webdavChannels[0].quota = wd.quota
|
|
}
|
|
continue
|
|
}
|
|
// id 自增
|
|
wd.id = webdavChannels.length + 1
|
|
wd.headers = normalizeWebDAVHeaders(wd.headers || wd.customHeaders || {})
|
|
wd.createDirectory = wd.createDirectory !== false
|
|
webdavChannels.push(wd)
|
|
}
|
|
|
|
// 负载均衡
|
|
const webdavLoadBalance = settingsKV.webdav?.loadBalance || {
|
|
enabled: false,
|
|
channels: [],
|
|
}
|
|
webdav.loadBalance = webdavLoadBalance
|
|
|
|
|
|
settings.telegram = telegram
|
|
settings.cfr2 = cfr2
|
|
settings.s3 = s3
|
|
settings.discord = discord
|
|
settings.huggingface = huggingface
|
|
settings.webdav = webdav
|
|
|
|
return settings;
|
|
}
|