Add AWS S3 integration with presigned URL generation and compatibility flags

This commit is contained in:
HoshinoKoji 2025-03-11 17:55:25 +08:00
parent 157c494035
commit 3f6f7ea629
4 changed files with 1716 additions and 5 deletions

1662
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,5 +12,9 @@
"@cloudflare/vitest-pool-workers": "^0.7.5",
"vitest": "~3.0.7",
"wrangler": "^3.112.0"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.758.0",
"@aws-sdk/s3-request-presigner": "^3.758.0"
}
}

View File

@ -7,9 +7,57 @@
*
* 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) {
return new Response('Hello World!');
const url = new URL(request.url);
const key = url.pathname;
if (url.hostname !== '127.0.0.1' && url.protocol === 'http:') {
return new Response(null, { status: 301, headers: {
Location: url.toString().replace(/^(http:)/, 'https:')
}});
}
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 = 'accelerate';
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 client = new S3Client({
endpoint,
credentials: { accessKeyId, secretAccessKey },
region,
maxRetries: 3,
signatureVersion: 'v4',
});
const command = new PutObjectCommand({ Bucket: bucket, Key: key });
const signedUrl = await getSignedUrl(client, command, { expiresIn: 24*60*60 });
return new Response(signedUrl);
},
};
};

View File

@ -6,6 +6,9 @@
"$schema": "node_modules/wrangler/config-schema.json",
"name": "s3-presigned",
"main": "src/index.js",
"compatibility_flags": [
"nodejs_compat"
],
"compatibility_date": "2025-03-10",
"observability": {
"enabled": true