public.py 6.23 KB
Newer Older
Antony Chazapis's avatar
Antony Chazapis committed
1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
Antony Chazapis's avatar
Antony Chazapis committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
# 
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
# 
#   1. Redistributions of source code must retain the above
#      copyright notice, this list of conditions and the following
#      disclaimer.
# 
#   2. Redistributions in binary form must reproduce the above
#      copyright notice, this list of conditions and the following
#      disclaimer in the documentation and/or other materials
#      provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# 
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.

import logging

from django.http import HttpResponse
37
from django.views.decorators.csrf import csrf_exempt
Antony Chazapis's avatar
Antony Chazapis committed
38

Antony Chazapis's avatar
Antony Chazapis committed
39
from synnefo.lib.astakos import get_user
40

41
from pithos.api.faults import (Fault, BadRequest, ItemNotFound)
Antony Chazapis's avatar
Antony Chazapis committed
42
from pithos.api.util import (put_object_headers, update_manifest_meta,
Antony Chazapis's avatar
Antony Chazapis committed
43 44
    validate_modification_preconditions, validate_matching_preconditions,
    object_data_response, api_method)
Antony Chazapis's avatar
Antony Chazapis committed
45
from pithos.api.short_url import decode_url
46
from pithos.api.settings import AUTHENTICATION_URL, AUTHENTICATION_USERS
Antony Chazapis's avatar
Antony Chazapis committed
47 48 49 50 51


logger = logging.getLogger(__name__)


52
@csrf_exempt
Antony Chazapis's avatar
Antony Chazapis committed
53
def public_demux(request, v_public):
54
    get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS)
Antony Chazapis's avatar
Antony Chazapis committed
55
    if request.method == 'HEAD':
Antony Chazapis's avatar
Antony Chazapis committed
56
        return public_meta(request, v_public)
Antony Chazapis's avatar
Antony Chazapis committed
57
    elif request.method == 'GET':
Antony Chazapis's avatar
Antony Chazapis committed
58
        return public_read(request, v_public)
Antony Chazapis's avatar
Antony Chazapis committed
59 60 61
    else:
        return method_not_allowed(request)

62
@api_method('HEAD', user_required=False)
Antony Chazapis's avatar
Antony Chazapis committed
63
def public_meta(request, v_public):
Antony Chazapis's avatar
Antony Chazapis committed
64
    # Normal Response Codes: 204
65
    # Error Response Codes: internalServerError (500),
Antony Chazapis's avatar
Antony Chazapis committed
66 67 68 69
    #                       itemNotFound (404),
    #                       badRequest (400)
    
    try:
Antony Chazapis's avatar
Antony Chazapis committed
70 71
        v_account, v_container, v_object = request.backend.get_public(request.user_uniq,
                                                    decode_url(v_public))
72
        meta = request.backend.get_object_meta(request.user_uniq, v_account,
73
                                                    v_container, v_object, 'pithos')
74
        public = request.backend.get_object_public(request.user_uniq, v_account,
75
                                                    v_container, v_object)
Antony Chazapis's avatar
Antony Chazapis committed
76
    except:
Antony Chazapis's avatar
Antony Chazapis committed
77 78
        raise ItemNotFound('Object does not exist')
    
79
    if not public:
Antony Chazapis's avatar
Antony Chazapis committed
80
        raise ItemNotFound('Object does not exist')
Antony Chazapis's avatar
Antony Chazapis committed
81
    update_manifest_meta(request, v_account, meta)
Antony Chazapis's avatar
Antony Chazapis committed
82
    
83 84
    response = HttpResponse(status=200)
    put_object_headers(response, meta, True)
Antony Chazapis's avatar
Antony Chazapis committed
85 86
    return response

87
@api_method('GET', user_required=False)
Antony Chazapis's avatar
Antony Chazapis committed
88
def public_read(request, v_public):
Antony Chazapis's avatar
Antony Chazapis committed
89
    # Normal Response Codes: 200, 206
90
    # Error Response Codes: internalServerError (500),
Antony Chazapis's avatar
Antony Chazapis committed
91 92 93 94 95 96 97
    #                       rangeNotSatisfiable (416),
    #                       preconditionFailed (412),
    #                       itemNotFound (404),
    #                       badRequest (400),
    #                       notModified (304)
    
    try:
Antony Chazapis's avatar
Antony Chazapis committed
98 99
        v_account, v_container, v_object = request.backend.get_public(request.user_uniq,
                                                    decode_url(v_public))
100
        meta = request.backend.get_object_meta(request.user_uniq, v_account,
101
                                                    v_container, v_object, 'pithos')
102
        public = request.backend.get_object_public(request.user_uniq, v_account,
103
                                                    v_container, v_object)
Antony Chazapis's avatar
Antony Chazapis committed
104
    except:
Antony Chazapis's avatar
Antony Chazapis committed
105 106
        raise ItemNotFound('Object does not exist')
    
107
    if not public:
Antony Chazapis's avatar
Antony Chazapis committed
108
        raise ItemNotFound('Object does not exist')
Antony Chazapis's avatar
Antony Chazapis committed
109
    update_manifest_meta(request, v_account, meta)
Antony Chazapis's avatar
Antony Chazapis committed
110 111 112 113 114 115 116
    
    # Evaluate conditions.
    validate_modification_preconditions(request, meta)
    try:
        validate_matching_preconditions(request, meta)
    except NotModified:
        response = HttpResponse(status=304)
117
        response['ETag'] = meta['ETag']
Antony Chazapis's avatar
Antony Chazapis committed
118 119
        return response
    
Antony Chazapis's avatar
Antony Chazapis committed
120 121 122 123
    sizes = []
    hashmaps = []
    if 'X-Object-Manifest' in meta:
        try:
124
            src_container, src_name = split_container_object_string('/' + meta['X-Object-Manifest'])
125
            objects = request.backend.list_objects(request.user_uniq, v_account,
126
                                src_container, prefix=src_name, virtual=False)
Antony Chazapis's avatar
Antony Chazapis committed
127
        except:
Antony Chazapis's avatar
Antony Chazapis committed
128 129 130 131
            raise ItemNotFound('Object does not exist')
        
        try:
            for x in objects:
132
                s, h = request.backend.get_object_hashmap(request.user_uniq,
133
                                        v_account, src_container, x[0], x[1])
Antony Chazapis's avatar
Antony Chazapis committed
134 135
                sizes.append(s)
                hashmaps.append(h)
Antony Chazapis's avatar
Antony Chazapis committed
136
        except:
Antony Chazapis's avatar
Antony Chazapis committed
137 138 139
            raise ItemNotFound('Object does not exist')
    else:
        try:
140
            s, h = request.backend.get_object_hashmap(request.user_uniq, v_account,
141
                                                        v_container, v_object)
Antony Chazapis's avatar
Antony Chazapis committed
142 143
            sizes.append(s)
            hashmaps.append(h)
Antony Chazapis's avatar
Antony Chazapis committed
144
        except:
Antony Chazapis's avatar
Antony Chazapis committed
145
            raise ItemNotFound('Object does not exist')
Antony Chazapis's avatar
Antony Chazapis committed
146
    
Antony Chazapis's avatar
Antony Chazapis committed
147 148 149 150 151 152
    if 'Content-Disposition' not in meta:
        name = v_object.rstrip('/').split('/')[-1]
        if not name:
            name = v_public
        meta['Content-Disposition'] = 'attachment; filename=%s' % (name,)
    
Antony Chazapis's avatar
Antony Chazapis committed
153
    return object_data_response(request, sizes, hashmaps, meta, True)
Antony Chazapis's avatar
Antony Chazapis committed
154

155
@api_method(user_required=False)
Antony Chazapis's avatar
Antony Chazapis committed
156
def method_not_allowed(request, **v_args):
Antony Chazapis's avatar
Antony Chazapis committed
157
    raise ItemNotFound('Object does not exist')