我们生成预签名 URL,以便用户将文件直接上传到 S3 存储桶。运行集成测试时,我们发现了一个失败的测试,其中预签名 URL 上的 HTTP PUT 请求产生了SignatureDoesNotMatch错误响应。令人惊讶的是,相同的代码使用另一个存储桶可以正常工作。我们一直在导致测试失败的原始存储桶上进行尝试,当它突然开始工作而没有任何实际代码更改时,我们感到很惊讶。
我们注意到,测试成功通过时,大约是在我们创建存储桶后两个小时。由于我们位于 UTC+0200,我们怀疑该问题与该时差和/或某些时钟同步问题有关。我们开始证实我们的怀疑,即经过足够的时间后,相同的预签名 URL 会突然起作用。剧透:确实如此!
以下代码创建一个全新的存储桶,生成适合文件上传的预签名 URL ( ClientMethod='put_object'),并尝试使用该requests库通过 HTTP PUT 某些数据。我们每 60 秒重试一次 PUT 数据,直到创建存储桶后 5419 秒(或 90 分钟)最终成功。
注意:即使之后删除了存储桶,运行相同的脚本(使用相同的存储桶名称)现在也会立即成功。如果您想重新确认此行为,请确保第二次使用不同的存储桶名称。
import logging
import time
import boto3
import requests
from botocore.client import Config
logger = logging.getLogger(__name__)
# region = "eu-central-1"
# region = "eu-west-1"
# region = "us-west-1"
region = "us-east-1"
s3_client = boto3.client('s3', region_name=region, config=Config(signature_version='s3v4'))
if __name__ == "__main__":
bucket_name = "some-globally-unique-bucket-name"
key_for_file = "test-file.txt" …Run Code Online (Sandbox Code Playgroud) 编写具有一些网络活动的应用程序 我发现自己一遍又一遍地为多个视图控制器编写相同的代码只是为了显示活动指示器。
class SomeViewController: UIViewController {
let indicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
override func viewDidLoad() {
super.viewDidLoad()
// customize indicator
self.indicator.layer.cornerRadius = 10
self.indicator.center = self.view.center
self.indicator.hidesWhenStopped = true
self.indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
self.indicator.backgroundColor = UIColor(red: 1/255, green: 1/255, blue: 1/255, alpha: 0.5)
}
// MARK: - Acitivity Indicator
func startIndicatingActivity() {
DispatchQueue.main.async {
self.view.addSubview(self.indicator)
self.indicator.startAnimating()
}
}
func stopIndicatingActivity() {
DispatchQueue.main.async {
self.indicator.stopAnimating()
}
}
}
Run Code Online (Sandbox Code Playgroud)
在同一个SomeViewController类中,我可以按如下方式使用它:
@IBAction func startHeavyNetworkStuffButtonPressed(_ sender: …Run Code Online (Sandbox Code Playgroud)