gpt4 book ai didi

python - 使用Python/Boto/Django直接上传到S3构建Policy

转载 作者:太空狗 更新时间:2023-10-30 00:46:35 25 4
gpt4 key购买 nike

到目前为止,我已经经历了这个问题的多次迭代,搜索了许多不同的例子,并且已经阅读了所有文档。

我正在尝试将 Plupload ( http://www.plupload.com/) 与 AWS S3 直接发布方法 (http://aws.amazon.com/articles/1434) 相结合。但是,我认为我构建传输策略和签名的方式有问题。当我提交表单时,我没有收到服务器的响应,而是重置了我与服务器的连接。

我尝试在示例中使用 python 代码:

import base64
import hmac, sha

policy = base64.b64encode(policy_document)

signature = base64.b64encode(
hmac.new(aws_secret_key, policy, sha).digest())

我还尝试在 python 中使用更新的 hashlib 库。无论我使用什么方法来构建我的策略和签名,我得到的值总是与此处生成的值不同:

http://s3.amazonaws.com/doc/s3-example-code/post/post_sample.html

我已经通读了这个问题:

How do I make Plupload upload directly to Amazon S3?

但我发现提供的示例过于复杂,无法准确实现。

我最近的尝试是使用部分 boto 库:

http://boto.cloudhackers.com/ref/s3.html#module-boto.s3.connection

但是使用 S3Commection.build_post_form_args 方法对我也不起作用。

如果有人能提供一个正确的例子来说明如何使用 python 创建帖子表单,我将不胜感激。即使是一些关于为什么总是重置连接的简单见解也会很好。

一些注意事项:

如果可能,我想使用 hashlib。我想从亚马逊获得 XML 响应(大概是“success_action_status = '201'”)我需要能够上传较大类型的文件,最大大小为 ~2GB。

最后一点,当我在 Chrome 中运行它时,它会提供上传进度,上传失败通常在 37% 左右。

最佳答案

Nathan 的回答帮助我开始了。我已经包含了两个目前为我工作的解决方案。

第一个解决方案使用纯 Python。第二个使用boto。

我试图让 boto 先工作,但一直出错。所以我回到 Amazon ruby​​ 文档并让 S3 接受使用 python 而不使用 boto 的文件。 (Browser Uploads to S3 using HTML POST)

在了解发生了什么之后,我能够修复我的错误并使用 boto,这是一个更简单的解决方案。

我包括解决方案 1,因为它明确显示了如何使用 python 设置策略文档和签名。

我的目标是将 html 上传页面创建为动态页面,以及用户在成功上传后看到的“成功”页面。方案一是动态创建表单上传页面,方案二是同时创建上传表单页面和成功页面。

解决方案一:

import base64
import hmac, hashlib

###### EDIT ONLY THE FOLLOWING ITEMS ######

DEBUG = 1
AWS_SECRET_KEY = "MySecretKey"
AWS_ACCESS_KEY = "MyAccessKey"
HTML_NAME = "S3PostForm.html"
EXPIRE_DATE = "2015-01-01T00:00:00Z" # Jan 1, 2015 gmt
FILE_TO_UPLOAD = "${filename}"
BUCKET = "media.mysite.com"
KEY = ""
ACL = "public-read" # or "private"
SUCCESS = "http://media.mysite.com/success.html"
CONTENT_TYPE = ""
CONTENT_LENGTH = 1024**3 # One gigabyte
HTTP_OR_HTTPS = "http" # Or "https" for better security
PAGE_TITLE = "My Html Upload to S3 Form"
ACTION = "%s://%s.s3.amazonaws.com/" % (HTTP_OR_HTTPS, BUCKET)

###### DON'T EDIT FROM HERE ON DOWN ######

policy_document_data = {
"expire": EXPIRE_DATE,
"bucket_name": BUCKET,
"key_name": KEY,
"acl_name": ACL,
"success_redirect": SUCCESS,
"content_name": CONTENT_TYPE,
"content_length": CONTENT_LENGTH,
}

policy_document = """
{"expiration": "%(expire)s",
"conditions": [
{"bucket": "%(bucket_name)s"},
["starts-with", "$key", "%(key_name)s"],
{"acl": "%(acl_name)s"},
{"success_action_redirect": "%(success_redirect)s"},
["starts-with", "$Content-Type", "%(content_name)s"],
["content-length-range", 0, %(content_length)d]
]
}
""" % policy_document_data

policy = base64.b64encode(policy_document)
signature = base64.b64encode(hmac.new(AWS_SECRET_KEY, policy, hashlib.sha1).digest())

html_page_data = {
"page_title": PAGE_TITLE,
"action_name": ACTION,
"filename": FILE_TO_UPLOAD,
"access_name": AWS_ACCESS_KEY,
"acl_name": ACL,
"redirect_name": SUCCESS,
"policy_name": policy,
"sig_name": signature,
"content_name": CONTENT_TYPE,
}

html_page = """
<html>
<head>
<title>%(page_title)s</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="%(action_name)s" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="%(filename)s">
<input type="hidden" name="AWSAccessKeyId" value="%(access_name)s">
<input type="hidden" name="acl" value="%(acl_name)s">
<input type="hidden" name="success_action_redirect" value="%(redirect_name)s">
<input type="hidden" name="policy" value="%(policy_name)s">
<input type="hidden" name="signature" value="%(sig_name)s">
<input type="hidden" name="Content-Type" value="%(content_name)s">

<!-- Include any additional input fields here -->

Browse to locate the file to upload:<br \> <br \>

<input name="file" type="file"><br> <br \>
<input type="submit" value="Upload File to S3">
</form>
</body>
</html>
""" % html_page_data

with open(HTML_NAME, "wb") as f:
f.write(html_page)

###### Dump output if testing ######
if DEBUG:

if 1: # Set true if not using the LEO editor
class G:
def es(self, data):print(data)
g = G()

items = [
"",
"",
"policy_document: %s" % policy_document,
"ploicy: %s" % policy,
"signature: %s" % signature,
"",
"",
]
for item in items:
g.es(item)

解决方案 2:

from boto.s3 import connection

###### EDIT ONLY THE FOLLOWING ITEMS ######

DEBUG = 1
AWS_SECRET_KEY = "MySecretKey"
AWS_ACCESS_KEY = "MyAccessKey"
HTML_NAME = "S3PostForm.html"
SUCCESS_NAME = "success.html"
EXPIRES = 60*60*24*356 # seconds = 1 year
BUCKET = "media.mysite.com"
KEY = "${filename}" # will match file entered by user
ACL = "public-read" # or "private"
SUCCESS = "http://media.mysite.com/success.html"
CONTENT_TYPE = "" # seems to work this way
CONTENT_LENGTH = 1024**3 # One gigabyte
HTTP_OR_HTTPS = "http" # Or https for better security
PAGE_TITLE = "My Html Upload to S3 Form"

###### DON'T EDIT FROM HERE ON DOWN ######

conn = connection.S3Connection(AWS_ACCESS_KEY,AWS_SECRET_KEY)
args = conn.build_post_form_args(
BUCKET,
KEY,
expires_in=EXPIRES,
acl=ACL,
success_action_redirect=SUCCESS,
max_content_length=CONTENT_LENGTH,
http_method=HTTP_OR_HTTPS,
fields=None,
conditions=None,
storage_class='STANDARD',
server_side_encryption=None,
)

form_fields = ""
line = ' <input type="hidden" name="%s" value="%s" >\n'
for item in args['fields']:
new_line = line % (item["name"], item["value"])
form_fields += new_line

html_page_data = {
"page_title": PAGE_TITLE,
"action": args["action"],
"input_fields": form_fields,
}

html_page = """
<html>
<head>
<title>%(page_title)s</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="%(action)s" method="post" enctype="multipart/form-data" >
%(input_fields)s
<!-- Include any additional input fields here -->

Browse to locate the file to upload:<br \> <br \>

<input name="file" type="file"><br> <br \>
<input type="submit" value="Upload File to S3">
</form>
</body>
</html>
""" % html_page_data

with open(HTML_NAME, "wb") as f:
f.write(html_page)

success_page = """
<html>
<head>
<title>S3 POST Success Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="jquery.js"></script>
<script src="purl.js"></script>
<!--

Amazon S3 passes three data items in the url of this page if
the upload was successful:
bucket = bucket name
key = file name upload to the bucket
etag = hash of file

The following script parses these values and puts them in
the page to be displayed.

-->

<script type="text/javascript">
var pname,url,val,params=["bucket","key","etag"];
$(document).ready(function()
{
url = $.url();
for (param in params)
{
pname = params[param];
val = url.param(pname);
if(typeof val != 'undefined')
document.getElementById(pname).value = val;
}
});
</script>

</head>
<body>
<div style="margin:0 auto;text-align:center;">
<p>Congratulations!</p>
<p>You have successfully uploaded the file.</p>
<form action="#" method="get"
>Location:
<br />
<input type="text" name="bucket" id="bucket" />
<br />File Name:
<br />
<input type="text" name="key" id="key" />
<br />Hash:
<br />
<input type="text" name="etag" id="etag" />
</form>
</div>
</body>
</html>
"""

with open(SUCCESS_NAME, "wb") as f:
f.write(success_page)

###### Dump output if testing ######
if DEBUG:

if 1: # Set true if not using the LEO editor
class G:
def es(self, data):print(data)
g = G()

g.es("conn = %s" % conn)
for key in args.keys():
if key is not "fields":
g.es("%s: %s" % (key, args[key]))
continue
for item in args['fields']:
g.es(item)

关于python - 使用Python/Boto/Django直接上传到S3构建Policy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7127215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com