2014-04-16 14 views
5

Ho problemi nell'eliminare un file da S3 utilizzando Fineuploader e Django/boto. Sono in grado di caricare file su S3 con Fineuploader e recuperare e visualizzare l'URL dell'immagine, ma l'eliminazione non ha avuto esito positivo.Eliminazione di un file da S3 utilizzando Django + Fineuploader + boto

Dall'esame dei registri di debug di boto, sembra che boto non stia inviando il token come parte della richiesta di S3 e penso che possa essere il mio problema.

In primo luogo ho l'uscita boto di debug perché ho il sospetto che qualcuno più familiarità con esso può aiutare dopo solo a guardarla, ma io ho la mia piena messa a punto in seguito (che segue l'esempio a https://github.com/Widen/fine-uploader-server/blob/master/python/django-fine-uploader-s3/ il più vicino possibile)

uscita terminale di eliminazione

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 

Ovviamente ho il nome del mio bucket attuale, come ho detto che il caricamento funziona, quindi non penso che il problema sia nelle impostazioni.

Fineuploader grado

$("#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()) 
    } 
+0

Hmm ... Non riesco a riprodurre questo. Qual è l'output di 'pip freeze'? E ci sono tracce di stack o altri messaggi di log utili nel terminale? –

+0

L'errore 500 nell'ultima riga del log del terminale indica che qualcosa è andato storto con il server Django. È il tuo _entire_ 'views.py'? –

+0

Questo non è l'intero views.py, ma è l'unica parte che coinvolge fineuploader. Dopo aver menzionato che si tratta di qualcosa sul server Django, ho notato che raggiunge la vista 'handle_delete', soddisfa le condizioni di' if boto', e dovrebbe quindi chiamare 'make_response (200)'. Sembra che qualcosa stia andando male nella chiamata 'aws_key.delete()'. – berserkia

risposta

2

Si è scoperto che ho avuto non configurato correttamente il criterio del bucket S3 per consentire anche le richieste DELETE dal mio server, quindi i log del bucket mostravano un errore 204. Avevo permesso le richieste PUT e GET, quindi il caricamento e il recupero funzionavano, ma non DELETE. Ho cambiato la mia politica della benna per essere più simile a:

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Effect": "Allow", 
     "Action": ["s3:ListAllMyBuckets"], 
     "Resource": "arn:aws:s3:::*" 
    }, 
    { 
     "Effect": "Allow", 
     "Action": [ 
     "s3:ListBucket", 
     "s3:GetBucketLocation" 
     ], 
     "Resource": "arn:aws:s3:::xxxxx" 
    }, 
    { 
     "Effect": "Allow", 
     "Action": [ 
     "s3:PutObject", 
     "s3:GetObject", 
     "s3:DeleteObject" 
     ], 
     "Resource": "arn:aws:s3:::xxxxx/*" 
    } 
    ] 
} 
Problemi correlati