Implement parameter processing

This commit is contained in:
HoshinoKoji 2025-03-11 19:31:12 +08:00
parent 3f6f7ea629
commit 37a4f83701
2 changed files with 29 additions and 6 deletions

View File

@ -13,7 +13,7 @@ import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
export default { export default {
async fetch(request, env, ctx) { async fetch(request, env, ctx) {
const url = new URL(request.url); const url = new URL(request.url);
const key = url.pathname; const rawKey = url.pathname.slice(1); // remove leading slash
if (url.hostname !== '127.0.0.1' && url.protocol === 'http:') { if (url.hostname !== '127.0.0.1' && url.protocol === 'http:') {
return new Response(null, { status: 301, headers: { return new Response(null, { status: 301, headers: {
@ -21,6 +21,10 @@ export default {
}}); }});
} }
if (!rawKey) {
return new Response('Invalid key', { status: 400 });
}
let endpoint, accessKeyId, secretAccessKey, region, bucket; let endpoint, accessKeyId, secretAccessKey, region, bucket;
switch (url.searchParams.get('backend')) { switch (url.searchParams.get('backend')) {
case 'r2': case 'r2':
@ -34,7 +38,7 @@ export default {
endpoint = env.COS_GLOBAL_ENDPOINT; endpoint = env.COS_GLOBAL_ENDPOINT;
accessKeyId = env.COS_GLOBAL_ACCESS_KEY_ID; accessKeyId = env.COS_GLOBAL_ACCESS_KEY_ID;
secretAccessKey = env.COS_GLOBAL_SECRET_ACCESS_KEY; secretAccessKey = env.COS_GLOBAL_SECRET_ACCESS_KEY;
region = 'accelerate'; region = env.COS_GLOBAL_REGION;
bucket = env.COS_GLOBAL_BUCKET; bucket = env.COS_GLOBAL_BUCKET;
break; break;
case 'cos-cn': case 'cos-cn':
@ -48,6 +52,14 @@ export default {
return new Response('Invalid backend', { status: 400 }); return new Response('Invalid backend', { status: 400 });
} }
const expId = url.searchParams.get('expId');
const participantId = url.searchParams.get('participantId');
const pat = /^[a-zA-Z0-9]{1,64}$/;
if (!expId || !participantId || expId.includes('/') || !participantId.match(pat)) {
// prevent path traversal
return new Response('Invalid expId or participantId', { status: 400 });
}
const client = new S3Client({ const client = new S3Client({
endpoint, endpoint,
credentials: { accessKeyId, secretAccessKey }, credentials: { accessKeyId, secretAccessKey },
@ -56,8 +68,11 @@ export default {
signatureVersion: 'v4', signatureVersion: 'v4',
}); });
const command = new PutObjectCommand({ Bucket: bucket, Key: key }); const command = new PutObjectCommand({
const signedUrl = await getSignedUrl(client, command, { expiresIn: 24*60*60 }); Bucket: bucket,
Key: `${expId}/${participantId}/${rawKey}`
});
const signedUrl = await getSignedUrl(client, command, { expiresIn: 12*60*60 });
return new Response(signedUrl); return new Response(signedUrl);
}, },
}; };

View File

@ -12,7 +12,7 @@
"compatibility_date": "2025-03-10", "compatibility_date": "2025-03-10",
"observability": { "observability": {
"enabled": true "enabled": true
} },
/** /**
* Smart Placement * Smart Placement
* Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement * Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
@ -30,7 +30,15 @@
* Environment Variables * Environment Variables
* https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables * https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
*/ */
// "vars": { "MY_VARIABLE": "production_value" }, "vars": {
"R2_BUCKET": "experiment",
"COS_GLOBAL_ENDPOINT": "https://cos.accelerate.myqcloud.com",
"COS_GLOBAL_REGION": "accelerate",
"COS_GLOBAL_BUCKET": "hoshino-exp-1304089692",
"COS_CN_ENDPOINT": "https://cos.ap-beijing.myqcloud.com",
"COS_CN_REGION": "ap-beijing",
"COS_CN_BUCKET": "hoshino-exp-cn-1304089692",
}
/** /**
* Note: Use secrets to store sensitive data. * Note: Use secrets to store sensitive data.
* https://developers.cloudflare.com/workers/configuration/secrets/ * https://developers.cloudflare.com/workers/configuration/secrets/