87 lines
2.8 KiB
JavaScript
87 lines
2.8 KiB
JavaScript
/**
|
|
* Welcome to Cloudflare Workers! This is your first worker.
|
|
*
|
|
* - Run `npm run dev` in your terminal to start a development server
|
|
* - Open a browser tab at http://localhost:8787/ to see your worker in action
|
|
* - Run `npm run deploy` to publish your worker
|
|
*
|
|
* Learn more at https://developers.cloudflare.com/workers/
|
|
*/
|
|
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
|
|
export default {
|
|
async fetch(request, env, ctx) {
|
|
const url = new URL(request.url);
|
|
const rawKey = url.pathname.slice(1); // remove leading slash
|
|
const corsHeaders = {
|
|
'Access-Control-Allow-Origin': request.headers.get('Origin'),
|
|
'Access-Control-Allow-Methods': '*',
|
|
'Access-Control-Allow-Headers': '*',
|
|
};
|
|
|
|
if (url.hostname !== '127.0.0.1' && url.protocol === 'http:') {
|
|
return new Response(null, { status: 301, headers: {
|
|
Location: url.toString().replace(/^(http:)/, 'https:')
|
|
}});
|
|
}
|
|
|
|
if (request.method === 'OPTIONS') {
|
|
return new Response(null, { status: 200, headers: corsHeaders });
|
|
}
|
|
|
|
if (!rawKey) {
|
|
return new Response('Invalid key', { status: 400, headers: corsHeaders });
|
|
}
|
|
|
|
let endpoint, accessKeyId, secretAccessKey, region, bucket;
|
|
switch (url.searchParams.get('backend')) {
|
|
case 'r2':
|
|
endpoint = env.R2_ENDPOINT;
|
|
accessKeyId = env.R2_ACCESS_KEY_ID;
|
|
secretAccessKey = env.R2_SECRET_ACCESS_KEY;
|
|
region = 'auto';
|
|
bucket = env.R2_BUCKET;
|
|
break;
|
|
case 'cos-global':
|
|
endpoint = env.COS_GLOBAL_ENDPOINT;
|
|
accessKeyId = env.COS_GLOBAL_ACCESS_KEY_ID;
|
|
secretAccessKey = env.COS_GLOBAL_SECRET_ACCESS_KEY;
|
|
region = env.COS_GLOBAL_REGION;
|
|
bucket = env.COS_GLOBAL_BUCKET;
|
|
break;
|
|
case 'cos-cn':
|
|
endpoint = env.COS_CN_ENDPOINT;
|
|
accessKeyId = env.COS_CN_ACCESS_KEY_ID;
|
|
secretAccessKey = env.COS_CN_SECRET_ACCESS_KEY;
|
|
region = env.COS_CN_REGION;
|
|
bucket = env.COS_CN_BUCKET;
|
|
break;
|
|
default:
|
|
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 parameters', { status: 400, headers: corsHeaders });
|
|
}
|
|
|
|
const client = new S3Client({
|
|
endpoint,
|
|
credentials: { accessKeyId, secretAccessKey },
|
|
region,
|
|
maxRetries: 3,
|
|
signatureVersion: 'v4',
|
|
});
|
|
|
|
const command = new PutObjectCommand({
|
|
Bucket: bucket,
|
|
Key: `${expId}/${participantId}/${rawKey}`
|
|
});
|
|
const signedUrl = await getSignedUrl(client, command, { expiresIn: 12*60*60 });
|
|
return new Response(signedUrl, { headers: corsHeaders });
|
|
},
|
|
}; |