Ich habe Probleme beim Löschen einer Datei aus S3 mit Fineuploader und Django/boto. Ich bin in der Lage, Dateien erfolgreich mit Fineuploader zu S3 zu laden, und die Bildurl abzurufen und anzuzeigen, aber das Löschen war nicht erfolgreich.Löschen einer Datei aus S3 mit Django + Fineuploader + boto
Aus dem Blick auf die Boto-Debug-Protokolle sieht es so aus, als ob Boto das Token nicht als Teil der Anfrage an S3 sendet und ich denke, das könnte mein Problem sein.
Zuerst habe ich die boto Debug-Ausgabe, weil ich jemand mehr mit ihm vertraut vermuten, nach einem Blick auf sie helfen kann, aber ich habe meine volle Setup danach (was das Beispiel bei https://github.com/Widen/fine-uploader-server/blob/master/python/django-fine-uploader-s3/ so eng wie möglich folgt)
Terminal-Ausgabe auf Lösch
bucket_name: XXXXXXXX
key_name: b45069b8-dc44-45fe-8b67-b25fc088bdea.jpg
aws_bucket: <Bucket: XXXXXXXXX>
aws_key: <Key: XXXXXXXX,b45069b8-dc44-45fe-8b67-b25fc088bdea.jpg>
2014-04-17 15:01:56,576 boto [DEBUG]:path=/b45069b8-dc44-45fe-8b67-b25fc088bdea.jpg
2014-04-17 15:01:56,577 boto [DEBUG]:auth_path=/thisorthis/b45069b8-dc44-45fe-8b67-b25fc088bdea.jpg
2014-04-17 15:01:56,577 boto [DEBUG]:Method: DELETE
2014-04-17 15:01:56,577 boto [DEBUG]:Path: /b45069b8-dc44-45fe-8b67-b25fc088bdea.jpg
2014-04-17 15:01:56,577 boto [DEBUG]:Data:
2014-04-17 15:01:56,577 boto [DEBUG]:Headers: {}
2014-04-17 15:01:56,577 boto [DEBUG]:Host: XXXXXXX.s3.amazonaws.com
2014-04-17 15:01:56,578 boto [DEBUG]:Port: 443
2014-04-17 15:01:56,578 boto [DEBUG]:Params: {}
2014-04-17 15:01:56,578 boto [DEBUG]:establishing HTTPS connection: host=thisorthis.s3.amazonaws.com, kwargs={'port': 443, 'timeout': 70}
2014-04-17 15:01:56,578 boto [DEBUG]:Token: None
2014-04-17 15:01:56,578 boto [DEBUG]:StringToSign:
DELETE
Thu, 17 Apr 2014 15:01:56 GMT
/XXXXXXXX/b45069b8-dc44-45fe-8b67-b25fc088bdea.jpg
2014-04-17 15:01:56,579 boto [DEBUG]:Signature:
AWS AKIAJYS27FQSNHPH3CXQ:dVKlBpulsY9LrOtHOa+xQmurIEM=
[17/Apr/2014 15:01:57] "DELETE /s3/delete/b45069b8-dc44-45fe-8b67-b25fc088bdea?key=b45069b8-dc44-45fe-8b67-b25fc088bdea.jpg&bucket=XXXXXXXX HTTP/1.1" 500 15975
settings.py:
AWS_CLIENT_SECRET_KEY = os.getenv("AWS_CLIENT_SECRET_KEY")
AWS_SERVER_PUBLIC_KEY = os.getenv("AWS_SERVER_PUBLIC_KEY")
AWS_SERVER_SECRET_KEY = os.getenv("AWS_SERVER_SECRET_KEY")
AWS_EXPECTED_BUCKET = 'mybucketname'
AWS_MAX_SIZE = 15000000
Offensichtlich habe ich meinen tatsächlichen Bucket-Namen dort, wie gesagt Uploading funktioniert, so glaube ich nicht, dass das Problem in den Einstellungen ist.
Fineuploader Instanz
$("#fine-uploader).fineUploaderS3({
debug: true,
request: {
endpoint: 'XXXXX',
accessKey: 'XXXXXXXX'
},
template: "simple-previews-template",
signature: {
endpoint: '/s3/signature/'
},
uploadSuccess: {
endpoint: '/s3/success/'
},
iframeSupport: {
localBlankPagePath: '/success.html'
},
deleteFile: {
enabled: true,
endpoint: '/s3/delete/'
},
classes: {
dropActive: "cssClassToAddToDropZoneOnEnter"
},
})
urls.py
url(r'^s3/signature/', views.handle_s3, name="s3_signee"),
url(r'^s3/delete/', views.handle_s3, name='s3_delete'),
url(r'^s3/success/', views.success_redirect_endpoint, name="s3_succes_endpoint")
views.py
try:
import boto
from boto.s3.connection import Key, S3Connection
boto.set_stream_logger('boto')
S3 = S3Connection(development.AWS_SERVER_PUBLIC_KEY, development.AWS_SERVER_SECRET_KEY)
except ImportError, e:
print("Could not import boto, the Amazon SDK for Python.")
print("Deleting files will not work.")
print("Install boto with")
print("$ pip install boto")
@csrf_exempt
def success_redirect_endpoint(request):
""" This is where the upload will snd a POST request after the
file has been stored in S3.
"""
key = request.POST.get('key')
response = {}
response['url'] = key
return HttpResponse(json.dumps(response), content_type="application/json")
@csrf_exempt
def handle_s3(request):
""" View which handles all POST and DELETE requests sent by Fine Uploader
S3. You will need to adjust these paths/conditions based on your setup.
"""
if request.method == "POST":
return handle_POST(request)
elif request.method == "DELETE":
return handle_DELETE(request)
else:
return HttpResponse(status=405)
def handle_POST(request):
""" Handle S3 uploader POST requests here. For files <=5MiB this is a simple
request to sign the policy document. For files >5MiB this is a request
to sign the headers to start a multipart encoded request.
"""
if request.POST.get('success', None):
return make_response(200)
else:
request_payload = json.loads(request.body)
headers = request_payload.get('headers', None)
if headers:
print "headers"
# The presence of the 'headers' property in the request payload
# means this is a request to sign a REST/multipart request
# and NOT a policy document
response_data = sign_headers(headers)
else:
print "no headers"
if not is_valid_policy(request_payload):
print "is not valid"
return make_response(400, {'invalid': True})
response_data = sign_policy_document(request_payload)
response_payload = json.dumps(response_data)
return make_response(200, response_payload)
def handle_DELETE(request):
""" Handle file deletion requests. For this, we use the Amazon Python SDK,
boto.
"""
print "handle delete"
if boto:
bucket_name = request.REQUEST.get('bucket')
print "bucket_name: ", bucket_name
key_name = request.REQUEST.get('key')
print "key_name:", key_name
aws_bucket = S3.get_bucket(bucket_name, validate=False)
print "aws_bucket: ", aws_bucket
aws_key = Key(aws_bucket, key_name)
print "aws_key: ", aws_key
aws_key.delete()
print "after aws_key.delete()"
return make_response(200)
else:
return make_response(500)
def make_response(status=200, content=None):
""" Construct an HTTP response. Fine Uploader expects 'application/json'.
"""
response = HttpResponse()
response.status_code = status
response['Content-Type'] = "application/json"
response.content = content
return response
def is_valid_policy(policy_document):
""" Verify the policy document has not been tampered with client-side
before sending it off.
"""
bucket = development.AWS_EXPECTED_BUCKET
parsed_max_size = development.AWS_MAX_SIZE
print "check validity"
# bucket = ''
# parsed_max_size = 0
for condition in policy_document['conditions']:
if isinstance(condition, list) and condition[0] == 'content-length-range':
parsed_max_size = condition[2]
else:
if condition.get('bucket', None):
bucket = condition['bucket']
return bucket == development.AWS_EXPECTED_BUCKET and parsed_max_size == development.AWS_MAX_SIZE
def sign_policy_document(policy_document):
""" Sign and return the policy doucument for a simple upload.
http://aws.amazon.com/articles/1434/#signyours3postform
"""
policy = base64.b64encode(json.dumps(policy_document))
signature = base64.b64encode(hmac.new(development.AWS_CLIENT_SECRET_KEY, policy, hashlib.sha1).digest())
return {
'policy': policy,
'signature': signature
}
def sign_headers(headers):
""" Sign and return the headers for a chunked upload. """
print "sign headers"
return {
'signature': base64.b64encode(hmac.new(development.AWS_CLIENT_SECRET_KEY, headers, hashlib.sha1).digest())
}
Hmm ... Ich bin nicht in der Lage, dies zu reproduzieren. Was ist die Ausgabe von 'pip freeze'? Und gibt es Stack-Traces oder andere nützliche Log-Nachrichten im Terminal? –
Der 500-Fehler in der letzten Zeile Ihres Terminalprotokolls weist darauf hin, dass beim Django-Server ein Fehler aufgetreten ist. Ist das dein _entire_ 'views.py'? –
Das ist nicht die gesamte views.py, aber es ist der einzige Teil, der fineuploader beinhaltet. Nachdem Sie erwähnt haben, dass es etwas auf dem Django-Server ist, bemerkte ich, dass es die 'handle_delete'-Ansicht erreicht, die 'if boto'-Bedingungen erfüllt und dann' make_response (200) 'aufrufen sollte. Beim Aufruf 'aws_key.delete()' scheint etwas schiefzugehen. – berserkia