2014-04-16 17 views
5

Mam problem z usunięciem pliku z S3 przy użyciu programu Fineuploader i Django/boto. Jestem w stanie pomyślnie przesłać pliki do S3 za pomocą programu Fineuploader, a także pobrać i wyświetlić adres URL obrazu, ale usunięcie nie powiodło się.Usuwanie pliku z S3 przy użyciu narzędzia Django + Fineuploader + boto

Patrząc na logi debugowania boto, wygląda na to, że boto nie wysyła tokenu jako części żądania do S3 i myślę, że to może być mój problem.

Najpierw muszę wyjście boto debugowania bo podejrzewam ktoś bardziej obeznany z tym może pomóc po prostu patrząc na niego, ale mam pełną konfigurację potem (co wynika przykład w https://github.com/Widen/fine-uploader-server/blob/master/python/django-fine-uploader-s3/ jak najdokładniej)

wyjście na terminalu usuwania

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 

Oczywiście mam tam swoje prawdziwe nazwisko, ponieważ powiedziałem, że przesyłanie działa, więc nie sądzę, żeby problem był w ustawieniach.

Fineuploader Instance

$("#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 ... Nie mogę tego odtworzyć. Co to jest wyjście 'pip freeze'? Czy są jakieś ślady stosu lub inne przydatne komunikaty dziennika w terminalu? –

+0

Błąd 500 w ostatnim wierszu logu terminala wskazuje, że coś poszło nie tak z serwerem Django. Czy to twój _entire_ 'views.py'? –

+0

To nie jest cały views.py, ale jest to jedyna część, która obejmuje narzędzie fineuploader. Po tym, jak wspomniałeś, że jest to coś na serwerze Django, zauważyłem, że na nim osiąga widok 'handle_delete', spełnia warunki' if boto', a następnie powinno wywoływać 'make_response (200)'. Wydaje się, że coś dzieje się nie tak podczas wywołania 'aws_key.delete()'. – berserkia

Odpowiedz

2

Okazało się, miałem nie poprawnie skonfigurowałem moich zasad dla zasobników S3, aby umożliwić również wysyłanie żądań z mojego serwera, dlatego dzienniki segmentów były wyświetlane z błędem 204. Miałem dozwolone żądania PUT i GET, więc przesyłanie i pobieranie działało, ale nie DELETE. Zmieniłem zasady dotyczące łyżki, aby były bardziej podobne:

{ 
    "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/*" 
    } 
    ] 
} 
Powiązane problemy