Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-app / pithos / api / public.py @ d630c78b

History | View | Annotate | Download (6.2 kB)

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

    
34
from django.http import HttpResponse
35
from django.views.decorators.csrf import csrf_exempt
36

    
37
from snf_django.lib import api
38
from snf_django.lib.api import faults
39

    
40
from pithos.api.util import (put_object_headers, update_manifest_meta,
41
                             validate_modification_preconditions,
42
                             validate_matching_preconditions,
43
                             object_data_response, api_method,
44
                             split_container_object_string)
45

    
46
import logging
47
logger = logging.getLogger(__name__)
48

    
49

    
50
@csrf_exempt
51
def public_demux(request, v_public):
52
    if request.method == 'HEAD':
53
        return public_meta(request, v_public)
54
    elif request.method == 'GET':
55
        return public_read(request, v_public)
56
    else:
57
        return api.method_not_allowed(request)
58

    
59

    
60
@api_method(http_method="HEAD", token_required=False, user_required=False,
61
            logger=logger)
62
def public_meta(request, v_public):
63
    # Normal Response Codes: 204
64
    # Error Response Codes: internalServerError (500),
65
    #                       itemNotFound (404),
66
    #                       badRequest (400)
67

    
68
    request.user_uniq = None
69
    try:
70
        v_account, v_container, v_object = request.backend.get_public(
71
            request.user_uniq,
72
            v_public)
73
        meta = request.backend.get_object_meta(request.user_uniq, v_account,
74
                                               v_container, v_object, 'pithos')
75
        public = request.backend.get_object_public(
76
            request.user_uniq, v_account,
77
            v_container, v_object)
78
    except:
79
        raise faults.ItemNotFound('Object does not exist')
80

    
81
    if not public:
82
        raise faults.ItemNotFound('Object does not exist')
83
    update_manifest_meta(request, v_account, meta)
84

    
85
    response = HttpResponse(status=200)
86
    put_object_headers(response, meta, True)
87
    return response
88

    
89

    
90
@api_method(http_method="GET", token_required=False, user_required=False,
91
            logger=logger)
92
def public_read(request, v_public):
93
    # Normal Response Codes: 200, 206
94
    # Error Response Codes: internalServerError (500),
95
    #                       rangeNotSatisfiable (416),
96
    #                       preconditionFailed (412),
97
    #                       itemNotFound (404),
98
    #                       badRequest (400),
99
    #                       notModified (304)
100

    
101
    request.user_uniq = None
102
    try:
103
        v_account, v_container, v_object = request.backend.get_public(
104
            request.user_uniq,
105
            v_public)
106
        meta = request.backend.get_object_meta(request.user_uniq, v_account,
107
                                               v_container, v_object, 'pithos')
108
        public = request.backend.get_object_public(
109
            request.user_uniq, v_account,
110
            v_container, v_object)
111
    except:
112
        raise faults.ItemNotFound('Object does not exist')
113

    
114
    if not public:
115
        raise faults.ItemNotFound('Object does not exist')
116
    update_manifest_meta(request, v_account, meta)
117

    
118
    # Evaluate conditions.
119
    validate_modification_preconditions(request, meta)
120
    try:
121
        validate_matching_preconditions(request, meta)
122
    except faults.NotModified:
123
        response = HttpResponse(status=304)
124
        response['ETag'] = meta['ETag']
125
        return response
126

    
127
    sizes = []
128
    hashmaps = []
129
    if 'X-Object-Manifest' in meta:
130
        try:
131
            src_container, src_name = split_container_object_string(
132
                '/' + meta['X-Object-Manifest'])
133
            objects = request.backend.list_objects(
134
                request.user_uniq, v_account,
135
                src_container, prefix=src_name, virtual=False)
136
        except:
137
            raise faults.ItemNotFound('Object does not exist')
138

    
139
        try:
140
            for x in objects:
141
                s, h = request.backend.get_object_hashmap(request.user_uniq,
142
                                                          v_account,
143
                                                          src_container,
144
                                                          x[0], x[1])
145
                sizes.append(s)
146
                hashmaps.append(h)
147
        except:
148
            raise faults.ItemNotFound('Object does not exist')
149
    else:
150
        try:
151
            s, h = request.backend.get_object_hashmap(
152
                request.user_uniq, v_account,
153
                v_container, v_object)
154
            sizes.append(s)
155
            hashmaps.append(h)
156
        except:
157
            raise faults.ItemNotFound('Object does not exist')
158

    
159
    if 'Content-Disposition' not in meta:
160
        name = v_object.rstrip('/').split('/')[-1]
161
        if not name:
162
            name = v_public
163
        meta['Content-Disposition'] = 'attachment; filename=%s' % (name,)
164

    
165
    return object_data_response(request, sizes, hashmaps, meta, True)