使用boto3的S3预签名帖子网址问题

我有一个Webapp,在apache2中运行了python-flask。该应用程序托管在Linode上,在很大程度上依赖于它们的S3对象存储。我正在使用boto3与S3存储进行交互。我的问题是在生产中使用generate_presigned_url方法时。它返回以下结构:

{
 'url': 'https://eu-central-1.linodeobjects.com/my-s3-bucket','fields': {
   'ACL': 'private','key': 'foo.bar','AWSaccessKeyId': 'FOOBAR','policy': 'base64longhash...','signature': 'foobar'
  }
} 

每次我在同一个python会话上使用此方法时,policy键都会返回一个较长的值(每个后续请求的长度增加约1.5倍)。几次请求后,policy的大小变得非常大(数十MB),应用中断了。如果我重新启动python服务,则policy的大小将被重置。

在深入研究boto3文档和GitHub中的一些线程之后,在这里无需重新启动整个python会话就可以找到任何有关重置S3连接的信息。要保持定期定期重新启动apache2服务不是一个好方法,因此我的解决方案是使用generate_presigned_url从独立脚本中调用subprocess并在使用之前将字符串输出解析回json,这不是理想,因为我希望我不必一直从apache内部调用bash脚本。我使用的主要功能如下:

AWS_BUCKET_PARAMS = {'ACL': 'private'}

# connect to my linode's s3 bucket
def awsSign():
    return boto3.client('s3',aws_access_key_id=AWS_accESS_KEY_ID,aws_secret_access_key=AWS_SECRET_accESS_KEY,endpoint_url=AWS_ENDPOINT_URL)

# generate presigned post object for uploading files
def awsPostForm(file_path):
    s3 = awsSign()
    return s3.generate_presigned_post(AWS_BUCKET,file_path,AWS_BUCKET_PARAMS,[AWS_BUCKET_PARAMS],1800)

# generate post object from external script
def awsPostFormTerminal(file_path):
    from subprocess import Popen,PIPE
    cmd = [ 'python3','-c',f'from utils import awsPostForm; print(awsPostForm("{file_path}"))' ]
    output = Popen( cmd,stdout=PIPE ).communicate()[0]
    return json.loads(output.decode('utf-8').replace('\n','').replace("'",'"'))

无论一次或多次调用awsSign()以获得文件列表,都会发生此问题。

简而言之,我希望有一个更好的方法,可以在同一python会话中从post检索后续的generate_presigned_url表单,而不必在每个新请求上都增加policy。如果有重新启动boto3连接的正确方法,请提供一些我在设置API调用时丢失的参数,或者这可能是Linode的S3对象存储服务所特有的。

如果有人可以指出正确的方向,我将不胜感激!

iCMS 回答:使用boto3的S3预签名帖子网址问题

好吧,事实证明这是一个菜鸟错误-从linode's Q&A得到了提示。因此,回答我自己的问题:

证明AWS_BUCKET_PARAMS变量在通过generate_presigned_post之后正在通过引用进行更新。在发送请求之前将全局变量复制到函数的作用域内即可解决此问题。

本文链接:https://www.f2er.com/1855443.html

大家都在问