fix: 支持自定义s3协议region name和signature version,解决cloudflare r2文件取回问题

This commit is contained in:
lan
2024-04-29 22:11:56 +08:00
parent eca480bab6
commit 58f313af1b
95 changed files with 18 additions and 421 deletions
+2
View File
@@ -19,6 +19,8 @@ default_value = {
's3_secret_access_key': '',
's3_bucket_name': '',
's3_endpoint_url': '',
's3_region_name': 'auto',
's3_signature_version': 's3v2',
's3_hostname': '',
's3_proxy': 0,
'aws_session_token': '',
+8 -7
View File
@@ -10,7 +10,7 @@ import io
import re
import sys
import aioboto3
import botocore
from botocore.config import Config
from fastapi import HTTPException, Response, UploadFile
from core.response import APIResponse
from core.settings import data_root, settings
@@ -20,8 +20,6 @@ from fastapi.responses import FileResponse
class FileStorageInterface:
def __init__(self):
raise NotImplementedError
async def save_file(self, file: UploadFile, save_path: str):
"""
@@ -93,6 +91,8 @@ class S3FileStorage(FileStorageInterface):
self.secret_access_key = settings.s3_secret_access_key
self.bucket_name = settings.s3_bucket_name
self.s3_hostname = settings.s3_hostname
self.region_name = settings.s3_region_name
self.signature_version = settings.s3_signature_version
self.endpoint_url = settings.s3_endpoint_url or f'https://{self.s3_hostname}'
self.aws_session_token = settings.aws_session_token
self.proxy = settings.s3_proxy
@@ -104,17 +104,18 @@ class S3FileStorage(FileStorageInterface):
self.endpoint_url = settings.s3_endpoint_url
async def save_file(self, file: UploadFile, save_path: str):
async with self.session.client("s3", endpoint_url=self.endpoint_url, aws_session_token=self.aws_session_token) as s3:
async with self.session.client("s3", endpoint_url=self.endpoint_url, aws_session_token=self.aws_session_token, region_name=self.region_name,
config=Config(signature_version=self.signature_version)) as s3:
await s3.put_object(Bucket=self.bucket_name, Key=save_path, Body=await file.read(), ContentType=file.content_type)
async def delete_file(self, file_code: FileCodes):
async with self.session.client("s3", endpoint_url=self.endpoint_url) as s3:
async with self.session.client("s3", endpoint_url=self.endpoint_url, region_name=self.region_name, config=Config(signature_version=self.signature_version)) as s3:
await s3.delete_object(Bucket=self.bucket_name, Key=await file_code.get_file_path())
async def get_file_response(self, file_code: FileCodes):
try:
filename = file_code.prefix + file_code.suffix
async with self.session.client("s3", endpoint_url=self.endpoint_url) as s3:
async with self.session.client("s3", endpoint_url=self.endpoint_url, region_name=self.region_name, config=Config(signature_version=self.signature_version)) as s3:
link = await s3.generate_presigned_url('get_object', Params={'Bucket': self.bucket_name, 'Key': await file_code.get_file_path()}, ExpiresIn=3600)
tmp = io.BytesIO()
async with aiohttp.ClientSession() as session:
@@ -133,7 +134,7 @@ class S3FileStorage(FileStorageInterface):
if self.proxy:
return await get_file_url(file_code.code)
else:
async with self.session.client("s3", endpoint_url=self.endpoint_url) as s3:
async with self.session.client("s3", endpoint_url=self.endpoint_url, region_name=self.region_name, config=Config(signature_version=self.signature_version)) as s3:
result = await s3.generate_presigned_url('get_object', Params={'Bucket': self.bucket_name, 'Key': await file_code.get_file_path()}, ExpiresIn=3600)
return result