'foo.bar.com.s3.amazonaws.com' 与“*.s3.amazonaws.com”、's3.amazonaws.com' 中的任何一个都不匹配

'foo.bar.com.s3.amazonaws.com' doesn't match either of '*.s3.amazonaws.com', 's3.amazonaws.com'

我使用的是 django,我在 s3 中存储了诸如 imgs 之类的东西(为此我使用的是 boto),但最近我遇到了这个错误:

'foo.bar.com.s3.amazonaws.com' doesn't match either of '*.s3.amazonaws.com', 's3.amazonaws.com'

我花了大约两天时间寻找可能的解决方案,但建议的独特之处在于更改 boto 的源代码,但我无法在生产环境中执行此操作。

编辑:使用 Django 1.58、Boto 2.38.0

如有任何帮助,我们将不胜感激。 提前致谢。

这是一个已知问题:#2836。这是由于您的存储桶名称中的点。 几天前我遇到了这个问题。用户似乎已通过设置成功解决此问题:

AWS_S3_HOST = 's3-eu-central-1.amazonaws.com'
AWS_S3_CALLING_FORMAT = 'boto.s3.connection.OrdinaryCallingFormat

但它对我不起作用。

否则,您可以创建一个没有点数的桶(例如 : foo-bar-com)。它会起作用。这是我临时解决这个问题的方法。

您可以在 connection.py 文件 (boto/connection.py) 中使用这个猴子补丁:

import ssl

_old_match_hostname = ssl.match_hostname

def _new_match_hostname(cert, hostname):
   if hostname.endswith('.s3.amazonaws.com'):
      pos = hostname.find('.s3.amazonaws.com')
      hostname = hostname[:pos].replace('.', '') + hostname[pos:]
   return _old_match_hostname(cert, hostname)

ssl.match_hostname = _new_match_hostname

(source)

另一个解决方案在:

如前所述,问题出现在名称上包含点的存储桶中。下面只是一个防止这种情况的例子。

import boto
from boto.s3.connection import VHostCallingFormat

c = boto.connect_s3(aws_access_key_id='your-access-key',
                    is_secure=False,
                    aws_secret_access_key='your-secret-access',
                    calling_format=VHostCallingFormat())
b = c.get_bucket(bucket_name='your.bucket.with.dots', validate=True)
print(b)

我从 python3.4 移动到 python3.5 时遇到了同样的错误(boto 版本保持不变)。

问题已通过从 boto 移动到 boto3 包解决。

示例:

import boto3
s3_client = boto3.client("s3", aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key)
body = open(local_filename, 'rb').read()
resp = s3_client.put_object(ACL="private", Body=body, Bucket=your_bucket_name, Key=path_to_the_file_inside_the_bucket)
if resp["ResponseMetadata"]["HTTPStatusCode"] != 200:
        raise Exception("Something went wrong...")