Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-app / pithos / api / public.py @ 1e47e49d

History | View | Annotate | Download (6.3 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.settings import UNSAFE_DOMAIN
41
from pithos.api.util import (put_object_headers, update_manifest_meta,
42
                             validate_modification_preconditions,
43
                             validate_matching_preconditions,
44
                             object_data_response, api_method,
45
                             split_container_object_string, restrict_to_host)
46

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

    
50

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

    
61

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

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

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

    
87
    response = HttpResponse(status=200)
88
    put_object_headers(response, meta, True)
89
    return response
90

    
91

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

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

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

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

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

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

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

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