root / snf-pithos-app / pithos / api / functions.py @ 2560c061
History | View | Annotate | Download (59.9 kB)
1 | c598a8a7 | Sofia Papagiannaki | # Copyright 2011-2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 2715ade4 | Sofia Papagiannaki | #
|
3 | 5635f9ef | Antony Chazapis | # Redistribution and use in source and binary forms, with or
|
4 | 5635f9ef | Antony Chazapis | # without modification, are permitted provided that the following
|
5 | 5635f9ef | Antony Chazapis | # conditions are met:
|
6 | 2715ade4 | Sofia Papagiannaki | #
|
7 | 5635f9ef | Antony Chazapis | # 1. Redistributions of source code must retain the above
|
8 | 5635f9ef | Antony Chazapis | # copyright notice, this list of conditions and the following
|
9 | 5635f9ef | Antony Chazapis | # disclaimer.
|
10 | 2715ade4 | Sofia Papagiannaki | #
|
11 | 5635f9ef | Antony Chazapis | # 2. Redistributions in binary form must reproduce the above
|
12 | 5635f9ef | Antony Chazapis | # copyright notice, this list of conditions and the following
|
13 | 5635f9ef | Antony Chazapis | # disclaimer in the documentation and/or other materials
|
14 | 5635f9ef | Antony Chazapis | # provided with the distribution.
|
15 | 2715ade4 | Sofia Papagiannaki | #
|
16 | 5635f9ef | Antony Chazapis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 5635f9ef | Antony Chazapis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 5635f9ef | Antony Chazapis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 5635f9ef | Antony Chazapis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 5635f9ef | Antony Chazapis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 5635f9ef | Antony Chazapis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 5635f9ef | Antony Chazapis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 5635f9ef | Antony Chazapis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 5635f9ef | Antony Chazapis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 5635f9ef | Antony Chazapis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 5635f9ef | Antony Chazapis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 5635f9ef | Antony Chazapis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 2715ade4 | Sofia Papagiannaki | #
|
29 | 5635f9ef | Antony Chazapis | # The views and conclusions contained in the software and
|
30 | 5635f9ef | Antony Chazapis | # documentation are those of the authors and should not be
|
31 | 5635f9ef | Antony Chazapis | # interpreted as representing official policies, either expressed
|
32 | 5635f9ef | Antony Chazapis | # or implied, of GRNET S.A.
|
33 | 5635f9ef | Antony Chazapis | |
34 | a7dff008 | Antony Chazapis | from xml.dom import minidom |
35 | b956618e | Antony Chazapis | |
36 | b956618e | Antony Chazapis | from django.http import HttpResponse |
37 | b956618e | Antony Chazapis | from django.template.loader import render_to_string |
38 | b956618e | Antony Chazapis | from django.utils import simplejson as json |
39 | b956618e | Antony Chazapis | from django.utils.http import parse_etags |
40 | 88283e9e | Antony Chazapis | from django.utils.encoding import smart_str |
41 | 8fbfd37b | Antony Chazapis | from django.views.decorators.csrf import csrf_exempt |
42 | b956618e | Antony Chazapis | |
43 | e6fb591c | Ilias Tsitsimpis | from astakosclient import AstakosClient |
44 | 1713c946 | Antony Chazapis | |
45 | 65bbcd43 | Christos Stavrakakis | from snf_django.lib import api |
46 | bd40abfa | Christos Stavrakakis | from snf_django.lib.api import faults |
47 | bd40abfa | Christos Stavrakakis | |
48 | 2715ade4 | Sofia Papagiannaki | from pithos.api.util import ( |
49 | 6255b97d | Sofia Papagiannaki | json_encode_decimal, rename_meta_key, format_header_key, |
50 | 6255b97d | Sofia Papagiannaki | printable_header_dict, get_account_headers, put_account_headers, |
51 | 6255b97d | Sofia Papagiannaki | get_container_headers, put_container_headers, get_object_headers, |
52 | 6255b97d | Sofia Papagiannaki | put_object_headers, update_manifest_meta, update_sharing_meta, |
53 | 6255b97d | Sofia Papagiannaki | update_public_meta, validate_modification_preconditions, |
54 | 6255b97d | Sofia Papagiannaki | validate_matching_preconditions, split_container_object_string, |
55 | 6255b97d | Sofia Papagiannaki | copy_or_move_object, get_int_parameter, get_content_length, |
56 | 6255b97d | Sofia Papagiannaki | get_content_range, socket_read_iterator, SaveToBackendHandler, |
57 | 6255b97d | Sofia Papagiannaki | object_data_response, put_object_block, hashmap_md5, simple_list_response, |
58 | 133e3fcf | Sofia Papagiannaki | api_method, is_uuid, retrieve_uuid, retrieve_uuids, |
59 | 3b8f938b | Sofia Papagiannaki | retrieve_displaynames, Checksum, NoChecksum |
60 | 27932481 | Sofia Papagiannaki | ) |
61 | 890c2065 | Sofia Papagiannaki | |
62 | 469d0997 | Georgios D. Tsoukalas | from pithos.api.settings import (UPDATE_MD5, TRANSLATE_UUIDS, |
63 | f759041f | Ilias Tsitsimpis | SERVICE_TOKEN, ASTAKOS_AUTH_URL) |
64 | b956618e | Antony Chazapis | |
65 | 3bdb9222 | Sofia Papagiannaki | from pithos.api import settings |
66 | 3bdb9222 | Sofia Papagiannaki | |
67 | 6255b97d | Sofia Papagiannaki | from pithos.backends.base import ( |
68 | 6255b97d | Sofia Papagiannaki | NotAllowedError, QuotaError, ContainerNotEmpty, ItemNotExists, |
69 | 3a5994a8 | Sofia Papagiannaki | VersionNotExists, ContainerExists, InvalidHash) |
70 | 7efc9f86 | Sofia Papagiannaki | |
71 | 6e147ecc | Antony Chazapis | from pithos.backends.filter import parse_filters |
72 | 6e147ecc | Antony Chazapis | |
73 | 65bbcd43 | Christos Stavrakakis | import logging |
74 | b956618e | Antony Chazapis | logger = logging.getLogger(__name__) |
75 | b956618e | Antony Chazapis | |
76 | bd40abfa | Christos Stavrakakis | |
77 | 469d0997 | Georgios D. Tsoukalas | def get_uuids(names): |
78 | 469d0997 | Georgios D. Tsoukalas | try:
|
79 | f759041f | Ilias Tsitsimpis | astakos = AstakosClient(SERVICE_TOKEN, ASTAKOS_AUTH_URL, |
80 | f759041f | Ilias Tsitsimpis | retry=2, use_pool=True, logger=logger) |
81 | f759041f | Ilias Tsitsimpis | uuids = astakos.service_get_uuids(names) |
82 | 469d0997 | Georgios D. Tsoukalas | except Exception, e: |
83 | 469d0997 | Georgios D. Tsoukalas | logger.exception(e) |
84 | 469d0997 | Georgios D. Tsoukalas | return {}
|
85 | 469d0997 | Georgios D. Tsoukalas | |
86 | 469d0997 | Georgios D. Tsoukalas | return uuids
|
87 | 469d0997 | Georgios D. Tsoukalas | |
88 | b956618e | Antony Chazapis | |
89 | 8fbfd37b | Antony Chazapis | @csrf_exempt
|
90 | b956618e | Antony Chazapis | def top_demux(request): |
91 | b956618e | Antony Chazapis | if request.method == 'GET': |
92 | 2715ade4 | Sofia Papagiannaki | try:
|
93 | 2715ade4 | Sofia Papagiannaki | request.GET['X-Auth-Token']
|
94 | 2715ade4 | Sofia Papagiannaki | except KeyError: |
95 | 2715ade4 | Sofia Papagiannaki | try:
|
96 | 2715ade4 | Sofia Papagiannaki | request.META['HTTP_X_AUTH_TOKEN']
|
97 | 2715ade4 | Sofia Papagiannaki | except KeyError: |
98 | 2715ade4 | Sofia Papagiannaki | return authenticate(request)
|
99 | 2715ade4 | Sofia Papagiannaki | return account_list(request)
|
100 | b956618e | Antony Chazapis | else:
|
101 | 2aba7764 | Sofia Papagiannaki | return api.api_method_not_allowed(request, allowed_methods=['GET']) |
102 | b956618e | Antony Chazapis | |
103 | 2715ade4 | Sofia Papagiannaki | |
104 | 8fbfd37b | Antony Chazapis | @csrf_exempt
|
105 | b956618e | Antony Chazapis | def account_demux(request, v_account): |
106 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
107 | 469d0997 | Georgios D. Tsoukalas | if not is_uuid(v_account): |
108 | 469d0997 | Georgios D. Tsoukalas | uuids = get_uuids([v_account]) |
109 | 469d0997 | Georgios D. Tsoukalas | if not uuids or not v_account in uuids: |
110 | 469d0997 | Georgios D. Tsoukalas | return HttpResponse(status=404) |
111 | 469d0997 | Georgios D. Tsoukalas | v_account = uuids[v_account] |
112 | 469d0997 | Georgios D. Tsoukalas | |
113 | b956618e | Antony Chazapis | if request.method == 'HEAD': |
114 | b956618e | Antony Chazapis | return account_meta(request, v_account)
|
115 | b956618e | Antony Chazapis | elif request.method == 'POST': |
116 | b956618e | Antony Chazapis | return account_update(request, v_account)
|
117 | 83dd59c5 | Antony Chazapis | elif request.method == 'GET': |
118 | 83dd59c5 | Antony Chazapis | return container_list(request, v_account)
|
119 | b956618e | Antony Chazapis | else:
|
120 | 2aba7764 | Sofia Papagiannaki | return api.api_method_not_allowed(request,
|
121 | 2aba7764 | Sofia Papagiannaki | allowed_methods=['HEAD',
|
122 | 2aba7764 | Sofia Papagiannaki | 'POST',
|
123 | 2aba7764 | Sofia Papagiannaki | 'GET'])
|
124 | b956618e | Antony Chazapis | |
125 | 2715ade4 | Sofia Papagiannaki | |
126 | 8fbfd37b | Antony Chazapis | @csrf_exempt
|
127 | b956618e | Antony Chazapis | def container_demux(request, v_account, v_container): |
128 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
129 | 469d0997 | Georgios D. Tsoukalas | if not is_uuid(v_account): |
130 | 469d0997 | Georgios D. Tsoukalas | uuids = get_uuids([v_account]) |
131 | 469d0997 | Georgios D. Tsoukalas | if not uuids or not v_account in uuids: |
132 | 469d0997 | Georgios D. Tsoukalas | return HttpResponse(status=404) |
133 | 469d0997 | Georgios D. Tsoukalas | v_account = uuids[v_account] |
134 | 469d0997 | Georgios D. Tsoukalas | |
135 | b956618e | Antony Chazapis | if request.method == 'HEAD': |
136 | b956618e | Antony Chazapis | return container_meta(request, v_account, v_container)
|
137 | b956618e | Antony Chazapis | elif request.method == 'PUT': |
138 | b956618e | Antony Chazapis | return container_create(request, v_account, v_container)
|
139 | b956618e | Antony Chazapis | elif request.method == 'POST': |
140 | b956618e | Antony Chazapis | return container_update(request, v_account, v_container)
|
141 | b956618e | Antony Chazapis | elif request.method == 'DELETE': |
142 | b956618e | Antony Chazapis | return container_delete(request, v_account, v_container)
|
143 | 83dd59c5 | Antony Chazapis | elif request.method == 'GET': |
144 | 83dd59c5 | Antony Chazapis | return object_list(request, v_account, v_container)
|
145 | b956618e | Antony Chazapis | else:
|
146 | 2aba7764 | Sofia Papagiannaki | return api.api_method_not_allowed(request,
|
147 | 2aba7764 | Sofia Papagiannaki | allowed_methods=['HEAD',
|
148 | 2aba7764 | Sofia Papagiannaki | 'PUT',
|
149 | 2aba7764 | Sofia Papagiannaki | 'POST',
|
150 | 2aba7764 | Sofia Papagiannaki | 'DELETE',
|
151 | 2aba7764 | Sofia Papagiannaki | 'GET'])
|
152 | b956618e | Antony Chazapis | |
153 | 2715ade4 | Sofia Papagiannaki | |
154 | 8fbfd37b | Antony Chazapis | @csrf_exempt
|
155 | b956618e | Antony Chazapis | def object_demux(request, v_account, v_container, v_object): |
156 | 67100dd2 | Ilias Tsitsimpis | # Helper to avoid placing the token in the URL
|
157 | 67100dd2 | Ilias Tsitsimpis | # when loading objects from a browser.
|
158 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
159 | 469d0997 | Georgios D. Tsoukalas | if not is_uuid(v_account): |
160 | 469d0997 | Georgios D. Tsoukalas | uuids = get_uuids([v_account]) |
161 | 469d0997 | Georgios D. Tsoukalas | if not uuids or not v_account in uuids: |
162 | 469d0997 | Georgios D. Tsoukalas | return HttpResponse(status=404) |
163 | 469d0997 | Georgios D. Tsoukalas | v_account = uuids[v_account] |
164 | 469d0997 | Georgios D. Tsoukalas | |
165 | b956618e | Antony Chazapis | if request.method == 'HEAD': |
166 | b956618e | Antony Chazapis | return object_meta(request, v_account, v_container, v_object)
|
167 | b956618e | Antony Chazapis | elif request.method == 'GET': |
168 | b956618e | Antony Chazapis | return object_read(request, v_account, v_container, v_object)
|
169 | b956618e | Antony Chazapis | elif request.method == 'PUT': |
170 | b956618e | Antony Chazapis | return object_write(request, v_account, v_container, v_object)
|
171 | b956618e | Antony Chazapis | elif request.method == 'COPY': |
172 | b956618e | Antony Chazapis | return object_copy(request, v_account, v_container, v_object)
|
173 | b956618e | Antony Chazapis | elif request.method == 'MOVE': |
174 | b956618e | Antony Chazapis | return object_move(request, v_account, v_container, v_object)
|
175 | b956618e | Antony Chazapis | elif request.method == 'POST': |
176 | 67100dd2 | Ilias Tsitsimpis | if request.META.get(
|
177 | 67100dd2 | Ilias Tsitsimpis | 'CONTENT_TYPE', '').startswith('multipart/form-data'): |
178 | 1d5c57d3 | Antony Chazapis | return object_write_form(request, v_account, v_container, v_object)
|
179 | b956618e | Antony Chazapis | return object_update(request, v_account, v_container, v_object)
|
180 | b956618e | Antony Chazapis | elif request.method == 'DELETE': |
181 | b956618e | Antony Chazapis | return object_delete(request, v_account, v_container, v_object)
|
182 | b956618e | Antony Chazapis | else:
|
183 | 2aba7764 | Sofia Papagiannaki | return api.api_method_not_allowed(request, allowed_methods=['HEAD', |
184 | 2aba7764 | Sofia Papagiannaki | 'GET',
|
185 | 2aba7764 | Sofia Papagiannaki | 'PUT',
|
186 | 2aba7764 | Sofia Papagiannaki | 'COPY',
|
187 | 2aba7764 | Sofia Papagiannaki | 'MOVE',
|
188 | 2aba7764 | Sofia Papagiannaki | 'POST',
|
189 | 2aba7764 | Sofia Papagiannaki | 'DELETE'])
|
190 | b956618e | Antony Chazapis | |
191 | 2715ade4 | Sofia Papagiannaki | |
192 | e805709b | Sofia Papagiannaki | @api_method('GET', token_required=False, user_required=False, logger=logger) |
193 | b956618e | Antony Chazapis | def authenticate(request): |
194 | b956618e | Antony Chazapis | # Normal Response Codes: 204
|
195 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
196 | 297513ba | Antony Chazapis | # forbidden (403),
|
197 | b956618e | Antony Chazapis | # badRequest (400)
|
198 | 2715ade4 | Sofia Papagiannaki | |
199 | b956618e | Antony Chazapis | x_auth_user = request.META.get('HTTP_X_AUTH_USER')
|
200 | b956618e | Antony Chazapis | x_auth_key = request.META.get('HTTP_X_AUTH_KEY')
|
201 | b956618e | Antony Chazapis | if not x_auth_user or not x_auth_key: |
202 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Missing X-Auth-User or X-Auth-Key header') |
203 | b956618e | Antony Chazapis | response = HttpResponse(status=204)
|
204 | 2715ade4 | Sofia Papagiannaki | |
205 | f7667baf | Antony Chazapis | uri = request.build_absolute_uri() |
206 | f7667baf | Antony Chazapis | if '?' in uri: |
207 | f7667baf | Antony Chazapis | uri = uri[:uri.find('?')]
|
208 | 2715ade4 | Sofia Papagiannaki | |
209 | 36d368f7 | Antony Chazapis | response['X-Auth-Token'] = x_auth_key
|
210 | 2715ade4 | Sofia Papagiannaki | response['X-Storage-Url'] = uri + ('' if uri.endswith('/') |
211 | 2715ade4 | Sofia Papagiannaki | else '/') + x_auth_user |
212 | b956618e | Antony Chazapis | return response
|
213 | b956618e | Antony Chazapis | |
214 | 2715ade4 | Sofia Papagiannaki | |
215 | 6e0f3e65 | Sofia Papagiannaki | @api_method('GET', format_allowed=True, user_required=True, logger=logger, |
216 | 6e0f3e65 | Sofia Papagiannaki | serializations=["text", "xml", "json"]) |
217 | f6c97079 | Antony Chazapis | def account_list(request): |
218 | f6c97079 | Antony Chazapis | # Normal Response Codes: 200, 204
|
219 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
220 | f6c97079 | Antony Chazapis | # badRequest (400)
|
221 | f6c97079 | Antony Chazapis | response = HttpResponse() |
222 | 2715ade4 | Sofia Papagiannaki | |
223 | f6c97079 | Antony Chazapis | marker = request.GET.get('marker')
|
224 | f6c97079 | Antony Chazapis | limit = get_int_parameter(request.GET.get('limit'))
|
225 | f6c97079 | Antony Chazapis | if not limit: |
226 | 3bdb9222 | Sofia Papagiannaki | limit = settings.API_LIST_LIMIT |
227 | 2715ade4 | Sofia Papagiannaki | |
228 | 61efb530 | Antony Chazapis | accounts = request.backend.list_accounts(request.user_uniq, marker, limit) |
229 | 2715ade4 | Sofia Papagiannaki | |
230 | f6c97079 | Antony Chazapis | if request.serialization == 'text': |
231 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
232 | 469d0997 | Georgios D. Tsoukalas | accounts = retrieve_displaynames( |
233 | 67100dd2 | Ilias Tsitsimpis | getattr(request, 'token', None), accounts) |
234 | f6c97079 | Antony Chazapis | if len(accounts) == 0: |
235 | f6c97079 | Antony Chazapis | # The cloudfiles python bindings expect 200 if json/xml.
|
236 | f6c97079 | Antony Chazapis | response.status_code = 204
|
237 | f6c97079 | Antony Chazapis | return response
|
238 | f6c97079 | Antony Chazapis | response.status_code = 200
|
239 | f6c97079 | Antony Chazapis | response.content = '\n'.join(accounts) + '\n' |
240 | f6c97079 | Antony Chazapis | return response
|
241 | 2715ade4 | Sofia Papagiannaki | |
242 | f6c97079 | Antony Chazapis | account_meta = [] |
243 | f6c97079 | Antony Chazapis | for x in accounts: |
244 | 690747fe | Antony Chazapis | if x == request.user_uniq:
|
245 | 690747fe | Antony Chazapis | continue
|
246 | f6c97079 | Antony Chazapis | try:
|
247 | 2715ade4 | Sofia Papagiannaki | meta = request.backend.get_account_meta( |
248 | 3b8f938b | Sofia Papagiannaki | request.user_uniq, x, 'pithos', include_user_defined=False) |
249 | 61efb530 | Antony Chazapis | groups = request.backend.get_account_groups(request.user_uniq, x) |
250 | f6c97079 | Antony Chazapis | except NotAllowedError:
|
251 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
252 | f6c97079 | Antony Chazapis | else:
|
253 | 804e8fe7 | Antony Chazapis | rename_meta_key(meta, 'modified', 'last_modified') |
254 | 2715ade4 | Sofia Papagiannaki | rename_meta_key( |
255 | 2715ade4 | Sofia Papagiannaki | meta, 'until_timestamp', 'x_account_until_timestamp') |
256 | 690747fe | Antony Chazapis | if groups:
|
257 | 2715ade4 | Sofia Papagiannaki | meta['X-Account-Group'] = printable_header_dict(
|
258 | 2715ade4 | Sofia Papagiannaki | dict([(k, ','.join(v)) for k, v in groups.iteritems()])) |
259 | f6c97079 | Antony Chazapis | account_meta.append(printable_header_dict(meta)) |
260 | 469d0997 | Georgios D. Tsoukalas | |
261 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
262 | 469d0997 | Georgios D. Tsoukalas | uuids = list(d['name'] for d in account_meta) |
263 | 469d0997 | Georgios D. Tsoukalas | catalog = retrieve_displaynames( |
264 | 67100dd2 | Ilias Tsitsimpis | getattr(request, 'token', None), uuids, return_dict=True) |
265 | 469d0997 | Georgios D. Tsoukalas | for meta in account_meta: |
266 | 469d0997 | Georgios D. Tsoukalas | meta['name'] = catalog.get(meta.get('name')) |
267 | 469d0997 | Georgios D. Tsoukalas | |
268 | f6c97079 | Antony Chazapis | if request.serialization == 'xml': |
269 | f6c97079 | Antony Chazapis | data = render_to_string('accounts.xml', {'accounts': account_meta}) |
270 | 2715ade4 | Sofia Papagiannaki | elif request.serialization == 'json': |
271 | f6c97079 | Antony Chazapis | data = json.dumps(account_meta) |
272 | f6c97079 | Antony Chazapis | response.status_code = 200
|
273 | f6c97079 | Antony Chazapis | response.content = data |
274 | f6c97079 | Antony Chazapis | return response
|
275 | f6c97079 | Antony Chazapis | |
276 | 2715ade4 | Sofia Papagiannaki | |
277 | 65bbcd43 | Christos Stavrakakis | @api_method('HEAD', user_required=True, logger=logger) |
278 | b956618e | Antony Chazapis | def account_meta(request, v_account): |
279 | b956618e | Antony Chazapis | # Normal Response Codes: 204
|
280 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
281 | 297513ba | Antony Chazapis | # forbidden (403),
|
282 | b956618e | Antony Chazapis | # badRequest (400)
|
283 | 2715ade4 | Sofia Papagiannaki | |
284 | 1495b972 | Antony Chazapis | until = get_int_parameter(request.GET.get('until'))
|
285 | cca6c617 | Antony Chazapis | try:
|
286 | 2715ade4 | Sofia Papagiannaki | meta = request.backend.get_account_meta( |
287 | 3b8f938b | Sofia Papagiannaki | request.user_uniq, v_account, 'pithos', until)
|
288 | 2715ade4 | Sofia Papagiannaki | groups = request.backend.get_account_groups( |
289 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account) |
290 | 469d0997 | Georgios D. Tsoukalas | |
291 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
292 | 469d0997 | Georgios D. Tsoukalas | for k in groups: |
293 | 469d0997 | Georgios D. Tsoukalas | groups[k] = retrieve_displaynames( |
294 | 67100dd2 | Ilias Tsitsimpis | getattr(request, 'token', None), groups[k]) |
295 | 2715ade4 | Sofia Papagiannaki | policy = request.backend.get_account_policy( |
296 | 3b8f938b | Sofia Papagiannaki | request.user_uniq, v_account) |
297 | 78e1f8da | Sofia Papagiannaki | logger.debug(policy) |
298 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
299 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
300 | 2715ade4 | Sofia Papagiannaki | |
301 | a8326bef | Antony Chazapis | validate_modification_preconditions(request, meta) |
302 | 2715ade4 | Sofia Papagiannaki | |
303 | b956618e | Antony Chazapis | response = HttpResponse(status=204)
|
304 | 647a5f48 | Antony Chazapis | put_account_headers(response, meta, groups, policy) |
305 | b956618e | Antony Chazapis | return response
|
306 | b956618e | Antony Chazapis | |
307 | 2715ade4 | Sofia Papagiannaki | |
308 | 65bbcd43 | Christos Stavrakakis | @api_method('POST', user_required=True, logger=logger) |
309 | b956618e | Antony Chazapis | def account_update(request, v_account): |
310 | b956618e | Antony Chazapis | # Normal Response Codes: 202
|
311 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
312 | 297513ba | Antony Chazapis | # forbidden (403),
|
313 | b956618e | Antony Chazapis | # badRequest (400)
|
314 | 2715ade4 | Sofia Papagiannaki | |
315 | 02c0c3fa | Antony Chazapis | meta, groups = get_account_headers(request) |
316 | 469d0997 | Georgios D. Tsoukalas | for k in groups: |
317 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
318 | 469d0997 | Georgios D. Tsoukalas | try:
|
319 | 469d0997 | Georgios D. Tsoukalas | groups[k] = retrieve_uuids( |
320 | 67100dd2 | Ilias Tsitsimpis | getattr(request, 'token', None), |
321 | 67100dd2 | Ilias Tsitsimpis | groups[k], |
322 | 67100dd2 | Ilias Tsitsimpis | fail_silently=False)
|
323 | 469d0997 | Georgios D. Tsoukalas | except ItemNotExists, e:
|
324 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest(
|
325 | 67100dd2 | Ilias Tsitsimpis | 'Bad X-Account-Group header value: %s' % e)
|
326 | 469d0997 | Georgios D. Tsoukalas | else:
|
327 | 469d0997 | Georgios D. Tsoukalas | try:
|
328 | 469d0997 | Georgios D. Tsoukalas | retrieve_displaynames( |
329 | 469d0997 | Georgios D. Tsoukalas | getattr(request, 'token', None), |
330 | 469d0997 | Georgios D. Tsoukalas | groups[k], |
331 | 469d0997 | Georgios D. Tsoukalas | fail_silently=False)
|
332 | 469d0997 | Georgios D. Tsoukalas | except ItemNotExists, e:
|
333 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest(
|
334 | 67100dd2 | Ilias Tsitsimpis | 'Bad X-Account-Group header value: %s' % e)
|
335 | a6eb13e9 | Antony Chazapis | replace = True
|
336 | a6eb13e9 | Antony Chazapis | if 'update' in request.GET: |
337 | b18ef3ad | Antony Chazapis | replace = False
|
338 | 02c0c3fa | Antony Chazapis | if groups:
|
339 | 02c0c3fa | Antony Chazapis | try:
|
340 | 61efb530 | Antony Chazapis | request.backend.update_account_groups(request.user_uniq, v_account, |
341 | 2715ade4 | Sofia Papagiannaki | groups, replace) |
342 | 02c0c3fa | Antony Chazapis | except NotAllowedError:
|
343 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
344 | 02c0c3fa | Antony Chazapis | except ValueError: |
345 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid groups header') |
346 | 77edd23d | Antony Chazapis | if meta or replace: |
347 | 77edd23d | Antony Chazapis | try:
|
348 | 808cea65 | Antony Chazapis | request.backend.update_account_meta(request.user_uniq, v_account, |
349 | 808cea65 | Antony Chazapis | 'pithos', meta, replace)
|
350 | 77edd23d | Antony Chazapis | except NotAllowedError:
|
351 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
352 | b956618e | Antony Chazapis | return HttpResponse(status=202) |
353 | b956618e | Antony Chazapis | |
354 | 2715ade4 | Sofia Papagiannaki | |
355 | 6b560707 | Sofia Papagiannaki | @api_method('GET', format_allowed=True, user_required=True, logger=logger, |
356 | ee565728 | Kostas Papadimitriou | serializations=["text", "xml", "json"]) |
357 | b956618e | Antony Chazapis | def container_list(request, v_account): |
358 | b956618e | Antony Chazapis | # Normal Response Codes: 200, 204
|
359 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
360 | b956618e | Antony Chazapis | # itemNotFound (404),
|
361 | 297513ba | Antony Chazapis | # forbidden (403),
|
362 | b956618e | Antony Chazapis | # badRequest (400)
|
363 | 2715ade4 | Sofia Papagiannaki | |
364 | 1495b972 | Antony Chazapis | until = get_int_parameter(request.GET.get('until'))
|
365 | cca6c617 | Antony Chazapis | try:
|
366 | 2715ade4 | Sofia Papagiannaki | meta = request.backend.get_account_meta( |
367 | 3b8f938b | Sofia Papagiannaki | request.user_uniq, v_account, 'pithos', until)
|
368 | 2715ade4 | Sofia Papagiannaki | groups = request.backend.get_account_groups( |
369 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account) |
370 | 2715ade4 | Sofia Papagiannaki | policy = request.backend.get_account_policy( |
371 | 3b8f938b | Sofia Papagiannaki | request.user_uniq, v_account) |
372 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
373 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
374 | 2715ade4 | Sofia Papagiannaki | |
375 | b956618e | Antony Chazapis | validate_modification_preconditions(request, meta) |
376 | 2715ade4 | Sofia Papagiannaki | |
377 | b956618e | Antony Chazapis | response = HttpResponse() |
378 | 647a5f48 | Antony Chazapis | put_account_headers(response, meta, groups, policy) |
379 | 2715ade4 | Sofia Papagiannaki | |
380 | b956618e | Antony Chazapis | marker = request.GET.get('marker')
|
381 | f6c97079 | Antony Chazapis | limit = get_int_parameter(request.GET.get('limit'))
|
382 | f6c97079 | Antony Chazapis | if not limit: |
383 | 3bdb9222 | Sofia Papagiannaki | limit = settings.API_LIST_LIMIT |
384 | 2715ade4 | Sofia Papagiannaki | |
385 | b18ef3ad | Antony Chazapis | shared = False
|
386 | b18ef3ad | Antony Chazapis | if 'shared' in request.GET: |
387 | b18ef3ad | Antony Chazapis | shared = True
|
388 | c8860319 | Sofia Papagiannaki | |
389 | c8860319 | Sofia Papagiannaki | public_requested = 'public' in request.GET |
390 | c8860319 | Sofia Papagiannaki | public_granted = public_requested and request.user_uniq == v_account
|
391 | c8860319 | Sofia Papagiannaki | |
392 | c8860319 | Sofia Papagiannaki | if public_requested and not public_granted: |
393 | c8860319 | Sofia Papagiannaki | raise faults.Forbidden(
|
394 | c8860319 | Sofia Papagiannaki | 'PUblic container listing is not allowed to non path owners')
|
395 | 2715ade4 | Sofia Papagiannaki | |
396 | b956618e | Antony Chazapis | try:
|
397 | 2715ade4 | Sofia Papagiannaki | containers = request.backend.list_containers( |
398 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
399 | c8860319 | Sofia Papagiannaki | marker, limit, shared, until, public_granted) |
400 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
401 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
402 | b956618e | Antony Chazapis | except NameError: |
403 | b956618e | Antony Chazapis | containers = [] |
404 | 2715ade4 | Sofia Papagiannaki | |
405 | b956618e | Antony Chazapis | if request.serialization == 'text': |
406 | b956618e | Antony Chazapis | if len(containers) == 0: |
407 | b956618e | Antony Chazapis | # The cloudfiles python bindings expect 200 if json/xml.
|
408 | b956618e | Antony Chazapis | response.status_code = 204
|
409 | b956618e | Antony Chazapis | return response
|
410 | b956618e | Antony Chazapis | response.status_code = 200
|
411 | f6c97079 | Antony Chazapis | response.content = '\n'.join(containers) + '\n' |
412 | b956618e | Antony Chazapis | return response
|
413 | 2715ade4 | Sofia Papagiannaki | |
414 | b956618e | Antony Chazapis | container_meta = [] |
415 | b956618e | Antony Chazapis | for x in containers: |
416 | f6c97079 | Antony Chazapis | try:
|
417 | 2715ade4 | Sofia Papagiannaki | meta = request.backend.get_container_meta( |
418 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
419 | 2715ade4 | Sofia Papagiannaki | x, 'pithos', until, include_user_defined=False) |
420 | 61efb530 | Antony Chazapis | policy = request.backend.get_container_policy(request.user_uniq, |
421 | 2715ade4 | Sofia Papagiannaki | v_account, x) |
422 | f6c97079 | Antony Chazapis | except NotAllowedError:
|
423 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
424 | f6c97079 | Antony Chazapis | except NameError: |
425 | f6c97079 | Antony Chazapis | pass
|
426 | f6c97079 | Antony Chazapis | else:
|
427 | 804e8fe7 | Antony Chazapis | rename_meta_key(meta, 'modified', 'last_modified') |
428 | 2715ade4 | Sofia Papagiannaki | rename_meta_key( |
429 | 2715ade4 | Sofia Papagiannaki | meta, 'until_timestamp', 'x_container_until_timestamp') |
430 | 690747fe | Antony Chazapis | if policy:
|
431 | 2715ade4 | Sofia Papagiannaki | meta['X-Container-Policy'] = printable_header_dict(
|
432 | 2715ade4 | Sofia Papagiannaki | dict([(k, v) for k, v in policy.iteritems()])) |
433 | f6c97079 | Antony Chazapis | container_meta.append(printable_header_dict(meta)) |
434 | b956618e | Antony Chazapis | if request.serialization == 'xml': |
435 | 2715ade4 | Sofia Papagiannaki | data = render_to_string('containers.xml', {'account': |
436 | 2715ade4 | Sofia Papagiannaki | v_account, 'containers': container_meta})
|
437 | 2715ade4 | Sofia Papagiannaki | elif request.serialization == 'json': |
438 | b956618e | Antony Chazapis | data = json.dumps(container_meta) |
439 | b956618e | Antony Chazapis | response.status_code = 200
|
440 | b956618e | Antony Chazapis | response.content = data |
441 | b956618e | Antony Chazapis | return response
|
442 | b956618e | Antony Chazapis | |
443 | 2715ade4 | Sofia Papagiannaki | |
444 | 65bbcd43 | Christos Stavrakakis | @api_method('HEAD', user_required=True, logger=logger) |
445 | b956618e | Antony Chazapis | def container_meta(request, v_account, v_container): |
446 | b956618e | Antony Chazapis | # Normal Response Codes: 204
|
447 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
448 | b956618e | Antony Chazapis | # itemNotFound (404),
|
449 | 297513ba | Antony Chazapis | # forbidden (403),
|
450 | b956618e | Antony Chazapis | # badRequest (400)
|
451 | 2715ade4 | Sofia Papagiannaki | |
452 | 1495b972 | Antony Chazapis | until = get_int_parameter(request.GET.get('until'))
|
453 | b956618e | Antony Chazapis | try:
|
454 | 61efb530 | Antony Chazapis | meta = request.backend.get_container_meta(request.user_uniq, v_account, |
455 | 2715ade4 | Sofia Papagiannaki | v_container, 'pithos', until)
|
456 | 67100dd2 | Ilias Tsitsimpis | meta['object_meta'] = \
|
457 | 67100dd2 | Ilias Tsitsimpis | request.backend.list_container_meta(request.user_uniq, |
458 | 67100dd2 | Ilias Tsitsimpis | v_account, v_container, |
459 | 67100dd2 | Ilias Tsitsimpis | 'pithos', until)
|
460 | 2715ade4 | Sofia Papagiannaki | policy = request.backend.get_container_policy( |
461 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
462 | 2715ade4 | Sofia Papagiannaki | v_container) |
463 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
464 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
465 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
466 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
467 | 2715ade4 | Sofia Papagiannaki | |
468 | a8326bef | Antony Chazapis | validate_modification_preconditions(request, meta) |
469 | 2715ade4 | Sofia Papagiannaki | |
470 | b956618e | Antony Chazapis | response = HttpResponse(status=204)
|
471 | 39593b2b | Giorgos Verigakis | put_container_headers(request, response, meta, policy) |
472 | b956618e | Antony Chazapis | return response
|
473 | b956618e | Antony Chazapis | |
474 | 2715ade4 | Sofia Papagiannaki | |
475 | 65bbcd43 | Christos Stavrakakis | @api_method('PUT', user_required=True, logger=logger) |
476 | b956618e | Antony Chazapis | def container_create(request, v_account, v_container): |
477 | b956618e | Antony Chazapis | # Normal Response Codes: 201, 202
|
478 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
479 | b956618e | Antony Chazapis | # itemNotFound (404),
|
480 | 297513ba | Antony Chazapis | # forbidden (403),
|
481 | b956618e | Antony Chazapis | # badRequest (400)
|
482 | 2715ade4 | Sofia Papagiannaki | |
483 | 3ab38c43 | Antony Chazapis | meta, policy = get_container_headers(request) |
484 | 2715ade4 | Sofia Papagiannaki | |
485 | b956618e | Antony Chazapis | try:
|
486 | 2715ade4 | Sofia Papagiannaki | request.backend.put_container( |
487 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, v_container, policy) |
488 | b956618e | Antony Chazapis | ret = 201
|
489 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
490 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
491 | a8326bef | Antony Chazapis | except ValueError: |
492 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid policy header') |
493 | 7c09b0b7 | Sofia Papagiannaki | except ContainerExists:
|
494 | b956618e | Antony Chazapis | ret = 202
|
495 | 2715ade4 | Sofia Papagiannaki | |
496 | c5d308c6 | Antony Chazapis | if ret == 202 and policy: |
497 | cca6c617 | Antony Chazapis | try:
|
498 | 2715ade4 | Sofia Papagiannaki | request.backend.update_container_policy( |
499 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
500 | 2715ade4 | Sofia Papagiannaki | v_container, policy, replace=False)
|
501 | c5d308c6 | Antony Chazapis | except NotAllowedError:
|
502 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
503 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
504 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
505 | c5d308c6 | Antony Chazapis | except ValueError: |
506 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid policy header') |
507 | 78e1f8da | Sofia Papagiannaki | except QuotaError, e:
|
508 | 78e1f8da | Sofia Papagiannaki | raise faults.RequestEntityTooLarge('Quota error: %s' % e) |
509 | c5d308c6 | Antony Chazapis | if meta:
|
510 | c5d308c6 | Antony Chazapis | try:
|
511 | 61efb530 | Antony Chazapis | request.backend.update_container_meta(request.user_uniq, v_account, |
512 | 67100dd2 | Ilias Tsitsimpis | v_container, 'pithos',
|
513 | 67100dd2 | Ilias Tsitsimpis | meta, replace=False)
|
514 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
515 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
516 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
517 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
518 | 2715ade4 | Sofia Papagiannaki | |
519 | b956618e | Antony Chazapis | return HttpResponse(status=ret)
|
520 | b956618e | Antony Chazapis | |
521 | 2715ade4 | Sofia Papagiannaki | |
522 | 48bb9c89 | Sofia Papagiannaki | @api_method('POST', format_allowed=True, user_required=True, logger=logger, |
523 | 48bb9c89 | Sofia Papagiannaki | lock_container_path=True)
|
524 | b956618e | Antony Chazapis | def container_update(request, v_account, v_container): |
525 | b956618e | Antony Chazapis | # Normal Response Codes: 202
|
526 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
527 | b956618e | Antony Chazapis | # itemNotFound (404),
|
528 | 297513ba | Antony Chazapis | # forbidden (403),
|
529 | b956618e | Antony Chazapis | # badRequest (400)
|
530 | 2715ade4 | Sofia Papagiannaki | |
531 | 3ab38c43 | Antony Chazapis | meta, policy = get_container_headers(request) |
532 | a6eb13e9 | Antony Chazapis | replace = True
|
533 | a6eb13e9 | Antony Chazapis | if 'update' in request.GET: |
534 | a6eb13e9 | Antony Chazapis | replace = False
|
535 | 3ab38c43 | Antony Chazapis | if policy:
|
536 | 3ab38c43 | Antony Chazapis | try:
|
537 | 2715ade4 | Sofia Papagiannaki | request.backend.update_container_policy( |
538 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
539 | 2715ade4 | Sofia Papagiannaki | v_container, policy, replace) |
540 | 3ab38c43 | Antony Chazapis | except NotAllowedError:
|
541 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
542 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
543 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
544 | 3ab38c43 | Antony Chazapis | except ValueError: |
545 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid policy header') |
546 | 78e1f8da | Sofia Papagiannaki | except QuotaError, e:
|
547 | 78e1f8da | Sofia Papagiannaki | raise faults.RequestEntityTooLarge('Quota error: %s' % e) |
548 | 77edd23d | Antony Chazapis | if meta or replace: |
549 | 77edd23d | Antony Chazapis | try:
|
550 | 61efb530 | Antony Chazapis | request.backend.update_container_meta(request.user_uniq, v_account, |
551 | 67100dd2 | Ilias Tsitsimpis | v_container, 'pithos',
|
552 | 67100dd2 | Ilias Tsitsimpis | meta, replace) |
553 | 77edd23d | Antony Chazapis | except NotAllowedError:
|
554 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
555 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
556 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
557 | 2715ade4 | Sofia Papagiannaki | |
558 | 5144b772 | Antony Chazapis | content_length = -1
|
559 | 5144b772 | Antony Chazapis | if request.META.get('HTTP_TRANSFER_ENCODING') != 'chunked': |
560 | 2715ade4 | Sofia Papagiannaki | content_length = get_int_parameter( |
561 | 2715ade4 | Sofia Papagiannaki | request.META.get('CONTENT_LENGTH', 0)) |
562 | bd08f5c0 | Antony Chazapis | content_type = request.META.get('CONTENT_TYPE')
|
563 | 5144b772 | Antony Chazapis | hashmap = [] |
564 | 67100dd2 | Ilias Tsitsimpis | if (content_type
|
565 | 67100dd2 | Ilias Tsitsimpis | and content_type == 'application/octet-stream' |
566 | 67100dd2 | Ilias Tsitsimpis | and content_length != 0): |
567 | 2560c061 | Sofia Papagiannaki | |
568 | 2560c061 | Sofia Papagiannaki | try:
|
569 | 2560c061 | Sofia Papagiannaki | request.backend.can_write_container(request.user_uniq, v_account, |
570 | 2560c061 | Sofia Papagiannaki | v_container) |
571 | 2560c061 | Sofia Papagiannaki | except NotAllowedError:
|
572 | 2560c061 | Sofia Papagiannaki | raise faults.Forbidden('Not allowed') |
573 | 2560c061 | Sofia Papagiannaki | |
574 | 5144b772 | Antony Chazapis | for data in socket_read_iterator(request, content_length, |
575 | 2715ade4 | Sofia Papagiannaki | request.backend.block_size): |
576 | 5144b772 | Antony Chazapis | # TODO: Raise 408 (Request Timeout) if this takes too long.
|
577 | 67100dd2 | Ilias Tsitsimpis | # TODO: Raise 499 (Client Disconnect) if a length is defined
|
578 | 67100dd2 | Ilias Tsitsimpis | # and we stop before getting this much data.
|
579 | 5144b772 | Antony Chazapis | hashmap.append(request.backend.put_block(data)) |
580 | 2715ade4 | Sofia Papagiannaki | |
581 | 5144b772 | Antony Chazapis | response = HttpResponse(status=202)
|
582 | 5144b772 | Antony Chazapis | if hashmap:
|
583 | af7bb62f | Antony Chazapis | response.content = simple_list_response(request, hashmap) |
584 | 5144b772 | Antony Chazapis | return response
|
585 | b956618e | Antony Chazapis | |
586 | 2715ade4 | Sofia Papagiannaki | |
587 | 48bb9c89 | Sofia Papagiannaki | @api_method('DELETE', user_required=True, logger=logger, |
588 | 48bb9c89 | Sofia Papagiannaki | lock_container_path=True)
|
589 | b956618e | Antony Chazapis | def container_delete(request, v_account, v_container): |
590 | b956618e | Antony Chazapis | # Normal Response Codes: 204
|
591 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
592 | b956618e | Antony Chazapis | # conflict (409),
|
593 | b956618e | Antony Chazapis | # itemNotFound (404),
|
594 | 297513ba | Antony Chazapis | # forbidden (403),
|
595 | b956618e | Antony Chazapis | # badRequest (400)
|
596 | dfa2d4ba | Sofia Papagiannaki | # requestentitytoolarge (413)
|
597 | 2715ade4 | Sofia Papagiannaki | |
598 | bbd20b55 | Antony Chazapis | until = get_int_parameter(request.GET.get('until'))
|
599 | 2715ade4 | Sofia Papagiannaki | |
600 | e46b2bcf | Sofia Papagiannaki | delimiter = request.GET.get('delimiter')
|
601 | 2715ade4 | Sofia Papagiannaki | |
602 | b956618e | Antony Chazapis | try:
|
603 | 2715ade4 | Sofia Papagiannaki | request.backend.delete_container( |
604 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, v_container, |
605 | 2715ade4 | Sofia Papagiannaki | until, delimiter=delimiter) |
606 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
607 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
608 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
609 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
610 | 7efc9f86 | Sofia Papagiannaki | except ContainerNotEmpty:
|
611 | bd40abfa | Christos Stavrakakis | raise faults.Conflict('Container is not empty') |
612 | dfa2d4ba | Sofia Papagiannaki | except QuotaError, e:
|
613 | bd40abfa | Christos Stavrakakis | raise faults.RequestEntityTooLarge('Quota error: %s' % e) |
614 | b956618e | Antony Chazapis | return HttpResponse(status=204) |
615 | b956618e | Antony Chazapis | |
616 | 2715ade4 | Sofia Papagiannaki | |
617 | 6b560707 | Sofia Papagiannaki | @api_method('GET', format_allowed=True, user_required=True, logger=logger, |
618 | ee565728 | Kostas Papadimitriou | serializations=["text", "xml", "json"]) |
619 | b956618e | Antony Chazapis | def object_list(request, v_account, v_container): |
620 | b956618e | Antony Chazapis | # Normal Response Codes: 200, 204
|
621 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
622 | b956618e | Antony Chazapis | # itemNotFound (404),
|
623 | 297513ba | Antony Chazapis | # forbidden (403),
|
624 | b956618e | Antony Chazapis | # badRequest (400)
|
625 | 2715ade4 | Sofia Papagiannaki | |
626 | 1495b972 | Antony Chazapis | until = get_int_parameter(request.GET.get('until'))
|
627 | b956618e | Antony Chazapis | try:
|
628 | 61efb530 | Antony Chazapis | meta = request.backend.get_container_meta(request.user_uniq, v_account, |
629 | 2715ade4 | Sofia Papagiannaki | v_container, 'pithos', until)
|
630 | 67100dd2 | Ilias Tsitsimpis | meta['object_meta'] = \
|
631 | 67100dd2 | Ilias Tsitsimpis | request.backend.list_container_meta(request.user_uniq, |
632 | 67100dd2 | Ilias Tsitsimpis | v_account, v_container, |
633 | 67100dd2 | Ilias Tsitsimpis | 'pithos', until)
|
634 | 2715ade4 | Sofia Papagiannaki | policy = request.backend.get_container_policy( |
635 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
636 | 2715ade4 | Sofia Papagiannaki | v_container) |
637 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
638 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
639 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
640 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
641 | 2715ade4 | Sofia Papagiannaki | |
642 | b956618e | Antony Chazapis | validate_modification_preconditions(request, meta) |
643 | 2715ade4 | Sofia Papagiannaki | |
644 | b956618e | Antony Chazapis | response = HttpResponse() |
645 | 39593b2b | Giorgos Verigakis | put_container_headers(request, response, meta, policy) |
646 | 2715ade4 | Sofia Papagiannaki | |
647 | b956618e | Antony Chazapis | path = request.GET.get('path')
|
648 | b956618e | Antony Chazapis | prefix = request.GET.get('prefix')
|
649 | b956618e | Antony Chazapis | delimiter = request.GET.get('delimiter')
|
650 | 2715ade4 | Sofia Papagiannaki | |
651 | b956618e | Antony Chazapis | # Path overrides prefix and delimiter.
|
652 | b956618e | Antony Chazapis | virtual = True
|
653 | b956618e | Antony Chazapis | if path:
|
654 | b956618e | Antony Chazapis | prefix = path |
655 | b956618e | Antony Chazapis | delimiter = '/'
|
656 | b956618e | Antony Chazapis | virtual = False
|
657 | 2715ade4 | Sofia Papagiannaki | |
658 | b956618e | Antony Chazapis | # Naming policy.
|
659 | dcffd53e | Antony Chazapis | if prefix and delimiter and not prefix.endswith(delimiter): |
660 | b956618e | Antony Chazapis | prefix = prefix + delimiter |
661 | b956618e | Antony Chazapis | if not prefix: |
662 | b956618e | Antony Chazapis | prefix = ''
|
663 | b956618e | Antony Chazapis | prefix = prefix.lstrip('/')
|
664 | 2715ade4 | Sofia Papagiannaki | |
665 | b956618e | Antony Chazapis | marker = request.GET.get('marker')
|
666 | f6c97079 | Antony Chazapis | limit = get_int_parameter(request.GET.get('limit'))
|
667 | f6c97079 | Antony Chazapis | if not limit: |
668 | 3bdb9222 | Sofia Papagiannaki | limit = settings.API_LIST_LIMIT |
669 | 2715ade4 | Sofia Papagiannaki | |
670 | 22dab079 | Antony Chazapis | keys = request.GET.get('meta')
|
671 | 22dab079 | Antony Chazapis | if keys:
|
672 | 2715ade4 | Sofia Papagiannaki | keys = [smart_str(x.strip()) for x in keys.split(',') |
673 | 2715ade4 | Sofia Papagiannaki | if x.strip() != ''] |
674 | 1713c946 | Antony Chazapis | included, excluded, opers = parse_filters(keys) |
675 | 1713c946 | Antony Chazapis | keys = [] |
676 | 1713c946 | Antony Chazapis | keys += [format_header_key('X-Object-Meta-' + x) for x in included] |
677 | 2715ade4 | Sofia Papagiannaki | keys += ['!' + format_header_key('X-Object-Meta-' + x) |
678 | 2715ade4 | Sofia Papagiannaki | for x in excluded] |
679 | 2715ade4 | Sofia Papagiannaki | keys += ['%s%s%s' % (format_header_key(
|
680 | 2715ade4 | Sofia Papagiannaki | 'X-Object-Meta-' + k), o, v) for k, o, v in opers] |
681 | 22dab079 | Antony Chazapis | else:
|
682 | 22dab079 | Antony Chazapis | keys = [] |
683 | 2715ade4 | Sofia Papagiannaki | |
684 | b18ef3ad | Antony Chazapis | shared = False
|
685 | b18ef3ad | Antony Chazapis | if 'shared' in request.GET: |
686 | b18ef3ad | Antony Chazapis | shared = True
|
687 | 8a0c7040 | Georgios D. Tsoukalas | |
688 | 8a0c7040 | Georgios D. Tsoukalas | public_requested = 'public' in request.GET |
689 | 8a0c7040 | Georgios D. Tsoukalas | public_granted = public_requested and request.user_uniq == v_account
|
690 | 2715ade4 | Sofia Papagiannaki | |
691 | c8860319 | Sofia Papagiannaki | if public_requested and not public_granted: |
692 | c8860319 | Sofia Papagiannaki | raise faults.Forbidden(
|
693 | c8860319 | Sofia Papagiannaki | 'PUblic object listing is not allowed to non path owners')
|
694 | c8860319 | Sofia Papagiannaki | |
695 | b956618e | Antony Chazapis | if request.serialization == 'text': |
696 | 371d907a | Antony Chazapis | try:
|
697 | 2715ade4 | Sofia Papagiannaki | objects = request.backend.list_objects( |
698 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
699 | 2715ade4 | Sofia Papagiannaki | v_container, prefix, delimiter, marker, |
700 | 2715ade4 | Sofia Papagiannaki | limit, virtual, 'pithos', keys, shared,
|
701 | 8a0c7040 | Georgios D. Tsoukalas | until, None, public_granted)
|
702 | 371d907a | Antony Chazapis | except NotAllowedError:
|
703 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
704 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
705 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
706 | 2715ade4 | Sofia Papagiannaki | |
707 | b956618e | Antony Chazapis | if len(objects) == 0: |
708 | b956618e | Antony Chazapis | # The cloudfiles python bindings expect 200 if json/xml.
|
709 | b956618e | Antony Chazapis | response.status_code = 204
|
710 | b956618e | Antony Chazapis | return response
|
711 | b956618e | Antony Chazapis | response.status_code = 200
|
712 | 83dd59c5 | Antony Chazapis | response.content = '\n'.join([x[0] for x in objects]) + '\n' |
713 | b956618e | Antony Chazapis | return response
|
714 | dcffd53e | Antony Chazapis | |
715 | 371d907a | Antony Chazapis | try:
|
716 | 2715ade4 | Sofia Papagiannaki | objects = request.backend.list_object_meta( |
717 | 29148653 | Sofia Papagiannaki | request.user_uniq, v_account, v_container, prefix, delimiter, |
718 | 29148653 | Sofia Papagiannaki | marker, limit, virtual, 'pithos', keys, shared, until, None, |
719 | 29148653 | Sofia Papagiannaki | public_granted) |
720 | 15a96c3e | Antony Chazapis | object_permissions = {} |
721 | 15a96c3e | Antony Chazapis | object_public = {} |
722 | 15a96c3e | Antony Chazapis | if until is None: |
723 | ddea3095 | Sofia Papagiannaki | name = '/'.join((v_account, v_container, '')) |
724 | ddea3095 | Sofia Papagiannaki | name_idx = len(name)
|
725 | dc88754b | Nanakos Chrysostomos | objects_bulk = [] |
726 | 67100dd2 | Ilias Tsitsimpis | for x in request.backend.list_object_permissions( |
727 | 67100dd2 | Ilias Tsitsimpis | request.user_uniq, v_account, v_container, prefix): |
728 | ddea3095 | Sofia Papagiannaki | |
729 | ddea3095 | Sofia Papagiannaki | # filter out objects which are not under the container
|
730 | ddea3095 | Sofia Papagiannaki | if name != x[:name_idx]:
|
731 | ddea3095 | Sofia Papagiannaki | continue
|
732 | dc88754b | Nanakos Chrysostomos | objects_bulk.append(x[name_idx:]) |
733 | f759041f | Ilias Tsitsimpis | |
734 | dc88754b | Nanakos Chrysostomos | if len(objects_bulk) > 0: |
735 | dc88754b | Nanakos Chrysostomos | object_permissions = \ |
736 | dc88754b | Nanakos Chrysostomos | request.backend.get_object_permissions_bulk( |
737 | dc88754b | Nanakos Chrysostomos | request.user_uniq, v_account, v_container, |
738 | dc88754b | Nanakos Chrysostomos | objects_bulk) |
739 | 8a0c7040 | Georgios D. Tsoukalas | |
740 | 1a3eff62 | Sofia Papagiannaki | if request.user_uniq == v_account:
|
741 | 1a3eff62 | Sofia Papagiannaki | # Bring public information only if the request user
|
742 | 1a3eff62 | Sofia Papagiannaki | # is the object owner
|
743 | 8a0c7040 | Georgios D. Tsoukalas | for k, v in request.backend.list_object_public( |
744 | 8a0c7040 | Georgios D. Tsoukalas | request.user_uniq, v_account, |
745 | 8a0c7040 | Georgios D. Tsoukalas | v_container, prefix).iteritems(): |
746 | 8a0c7040 | Georgios D. Tsoukalas | object_public[k[name_idx:]] = v |
747 | 371d907a | Antony Chazapis | except NotAllowedError:
|
748 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
749 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
750 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
751 | 2715ade4 | Sofia Papagiannaki | |
752 | b956618e | Antony Chazapis | object_meta = [] |
753 | 371d907a | Antony Chazapis | for meta in objects: |
754 | 469d0997 | Georgios D. Tsoukalas | if TRANSLATE_UUIDS:
|
755 | 469d0997 | Georgios D. Tsoukalas | modified_by = meta.get('modified_by')
|
756 | 469d0997 | Georgios D. Tsoukalas | if modified_by:
|
757 | 469d0997 | Georgios D. Tsoukalas | l = retrieve_displaynames( |
758 | 67100dd2 | Ilias Tsitsimpis | getattr(request, 'token', None), [meta['modified_by']]) |
759 | 469d0997 | Georgios D. Tsoukalas | if l is not None and len(l) == 1: |
760 | 469d0997 | Georgios D. Tsoukalas | meta['modified_by'] = l[0] |
761 | 469d0997 | Georgios D. Tsoukalas | |
762 | 371d907a | Antony Chazapis | if len(meta) == 1: |
763 | b956618e | Antony Chazapis | # Virtual objects/directories.
|
764 | 371d907a | Antony Chazapis | object_meta.append(meta) |
765 | 83dd59c5 | Antony Chazapis | else:
|
766 | 2715ade4 | Sofia Papagiannaki | rename_meta_key( |
767 | 2715ade4 | Sofia Papagiannaki | meta, 'hash', 'x_object_hash') # Will be replaced by checksum. |
768 | 371d907a | Antony Chazapis | rename_meta_key(meta, 'checksum', 'hash') |
769 | 371d907a | Antony Chazapis | rename_meta_key(meta, 'type', 'content_type') |
770 | 371d907a | Antony Chazapis | rename_meta_key(meta, 'uuid', 'x_object_uuid') |
771 | 371d907a | Antony Chazapis | if until is not None and 'modified' in meta: |
772 | 371d907a | Antony Chazapis | del(meta['modified']) |
773 | 038f1ae9 | Antony Chazapis | else:
|
774 | 804e8fe7 | Antony Chazapis | rename_meta_key(meta, 'modified', 'last_modified') |
775 | 371d907a | Antony Chazapis | rename_meta_key(meta, 'modified_by', 'x_object_modified_by') |
776 | 371d907a | Antony Chazapis | rename_meta_key(meta, 'version', 'x_object_version') |
777 | 2715ade4 | Sofia Papagiannaki | rename_meta_key( |
778 | 2715ade4 | Sofia Papagiannaki | meta, 'version_timestamp', 'x_object_version_timestamp') |
779 | 15a96c3e | Antony Chazapis | permissions = object_permissions.get(meta['name'], None) |
780 | 15a96c3e | Antony Chazapis | if permissions:
|
781 | 2715ade4 | Sofia Papagiannaki | update_sharing_meta(request, permissions, v_account, |
782 | 2715ade4 | Sofia Papagiannaki | v_container, meta['name'], meta)
|
783 | 8a0c7040 | Georgios D. Tsoukalas | public_url = object_public.get(meta['name'], None) |
784 | 1a3eff62 | Sofia Papagiannaki | if request.user_uniq == v_account:
|
785 | 1a3eff62 | Sofia Papagiannaki | # Return public information only if the request user
|
786 | 1a3eff62 | Sofia Papagiannaki | # is the object owner
|
787 | 8a0c7040 | Georgios D. Tsoukalas | update_public_meta(public_url, meta) |
788 | 371d907a | Antony Chazapis | object_meta.append(printable_header_dict(meta)) |
789 | 469d0997 | Georgios D. Tsoukalas | |
790 | b956618e | Antony Chazapis | if request.serialization == 'xml': |
791 | 2715ade4 | Sofia Papagiannaki | data = render_to_string( |
792 | 2715ade4 | Sofia Papagiannaki | 'objects.xml', {'container': v_container, 'objects': object_meta}) |
793 | 2715ade4 | Sofia Papagiannaki | elif request.serialization == 'json': |
794 | c48acbfd | Sofia Papagiannaki | data = json.dumps(object_meta, default=json_encode_decimal) |
795 | b956618e | Antony Chazapis | response.status_code = 200
|
796 | b956618e | Antony Chazapis | response.content = data |
797 | b956618e | Antony Chazapis | return response
|
798 | b956618e | Antony Chazapis | |
799 | 2715ade4 | Sofia Papagiannaki | |
800 | 65bbcd43 | Christos Stavrakakis | @api_method('HEAD', user_required=True, logger=logger) |
801 | b956618e | Antony Chazapis | def object_meta(request, v_account, v_container, v_object): |
802 | b956618e | Antony Chazapis | # Normal Response Codes: 204
|
803 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
804 | b956618e | Antony Chazapis | # itemNotFound (404),
|
805 | 297513ba | Antony Chazapis | # forbidden (403),
|
806 | b956618e | Antony Chazapis | # badRequest (400)
|
807 | 2715ade4 | Sofia Papagiannaki | |
808 | 104626e3 | Antony Chazapis | version = request.GET.get('version')
|
809 | b956618e | Antony Chazapis | try:
|
810 | 61efb530 | Antony Chazapis | meta = request.backend.get_object_meta(request.user_uniq, v_account, |
811 | 67100dd2 | Ilias Tsitsimpis | v_container, v_object, |
812 | 67100dd2 | Ilias Tsitsimpis | 'pithos', version)
|
813 | e8886082 | Antony Chazapis | if version is None: |
814 | 2715ade4 | Sofia Papagiannaki | permissions = request.backend.get_object_permissions( |
815 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, |
816 | 2715ade4 | Sofia Papagiannaki | v_account, v_container, v_object) |
817 | 2715ade4 | Sofia Papagiannaki | public = request.backend.get_object_public( |
818 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
819 | 2715ade4 | Sofia Papagiannaki | v_container, v_object) |
820 | e8886082 | Antony Chazapis | else:
|
821 | e8886082 | Antony Chazapis | permissions = None
|
822 | e0f916bb | Antony Chazapis | public = None
|
823 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
824 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
825 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
826 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
827 | 7efc9f86 | Sofia Papagiannaki | except VersionNotExists:
|
828 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Version does not exist') |
829 | 2715ade4 | Sofia Papagiannaki | |
830 | 8cb45c13 | Antony Chazapis | update_manifest_meta(request, v_account, meta) |
831 | 2715ade4 | Sofia Papagiannaki | update_sharing_meta( |
832 | 2715ade4 | Sofia Papagiannaki | request, permissions, v_account, v_container, v_object, meta) |
833 | 6fe32fb6 | Sofia Papagiannaki | if request.user_uniq == v_account:
|
834 | 6fe32fb6 | Sofia Papagiannaki | update_public_meta(public, meta) |
835 | 2715ade4 | Sofia Papagiannaki | |
836 | a8326bef | Antony Chazapis | # Evaluate conditions.
|
837 | a8326bef | Antony Chazapis | validate_modification_preconditions(request, meta) |
838 | a8326bef | Antony Chazapis | try:
|
839 | a8326bef | Antony Chazapis | validate_matching_preconditions(request, meta) |
840 | bd40abfa | Christos Stavrakakis | except faults.NotModified:
|
841 | a8326bef | Antony Chazapis | response = HttpResponse(status=304)
|
842 | 133e3fcf | Sofia Papagiannaki | response['ETag'] = meta['hash'] if not UPDATE_MD5 else meta['checksum'] |
843 | a8326bef | Antony Chazapis | return response
|
844 | 2715ade4 | Sofia Papagiannaki | |
845 | cb146cf9 | Antony Chazapis | response = HttpResponse(status=200)
|
846 | 469d0997 | Georgios D. Tsoukalas | put_object_headers(response, meta, token=getattr(request, 'token', None)) |
847 | b956618e | Antony Chazapis | return response
|
848 | b956618e | Antony Chazapis | |
849 | 2715ade4 | Sofia Papagiannaki | |
850 | 65bbcd43 | Christos Stavrakakis | @api_method('GET', format_allowed=True, user_required=True, logger=logger) |
851 | b956618e | Antony Chazapis | def object_read(request, v_account, v_container, v_object): |
852 | 63de12cf | Sofia Papagiannaki | return _object_read(request, v_account, v_container, v_object)
|
853 | 63de12cf | Sofia Papagiannaki | |
854 | 63de12cf | Sofia Papagiannaki | |
855 | 63de12cf | Sofia Papagiannaki | def _object_read(request, v_account, v_container, v_object): |
856 | b956618e | Antony Chazapis | # Normal Response Codes: 200, 206
|
857 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
858 | b956618e | Antony Chazapis | # rangeNotSatisfiable (416),
|
859 | b956618e | Antony Chazapis | # preconditionFailed (412),
|
860 | b956618e | Antony Chazapis | # itemNotFound (404),
|
861 | 297513ba | Antony Chazapis | # forbidden (403),
|
862 | b956618e | Antony Chazapis | # badRequest (400),
|
863 | b956618e | Antony Chazapis | # notModified (304)
|
864 | 2715ade4 | Sofia Papagiannaki | |
865 | 104626e3 | Antony Chazapis | version = request.GET.get('version')
|
866 | 2715ade4 | Sofia Papagiannaki | |
867 | e8886082 | Antony Chazapis | # Reply with the version list. Do this first, as the object may be deleted.
|
868 | 104626e3 | Antony Chazapis | if version == 'list': |
869 | e8886082 | Antony Chazapis | if request.serialization == 'text': |
870 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('No format specified for version list.') |
871 | 2715ade4 | Sofia Papagiannaki | |
872 | cca6c617 | Antony Chazapis | try:
|
873 | 61efb530 | Antony Chazapis | v = request.backend.list_versions(request.user_uniq, v_account, |
874 | 2715ade4 | Sofia Papagiannaki | v_container, v_object) |
875 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
876 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
877 | 02b8c298 | Sofia Papagiannaki | except ItemNotExists:
|
878 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
879 | cca6c617 | Antony Chazapis | d = {'versions': v}
|
880 | e8886082 | Antony Chazapis | if request.serialization == 'xml': |
881 | e8886082 | Antony Chazapis | d['object'] = v_object
|
882 | e8886082 | Antony Chazapis | data = render_to_string('versions.xml', d)
|
883 | 2715ade4 | Sofia Papagiannaki | elif request.serialization == 'json': |
884 | c48acbfd | Sofia Papagiannaki | data = json.dumps(d, default=json_encode_decimal) |
885 | 2715ade4 | Sofia Papagiannaki | |
886 | e8886082 | Antony Chazapis | response = HttpResponse(data, status=200)
|
887 | e8886082 | Antony Chazapis | response['Content-Length'] = len(data) |
888 | e8886082 | Antony Chazapis | return response
|
889 | 2715ade4 | Sofia Papagiannaki | |
890 | b956618e | Antony Chazapis | try:
|
891 | 61efb530 | Antony Chazapis | meta = request.backend.get_object_meta(request.user_uniq, v_account, |
892 | 67100dd2 | Ilias Tsitsimpis | v_container, v_object, |
893 | 67100dd2 | Ilias Tsitsimpis | 'pithos', version)
|
894 | e8886082 | Antony Chazapis | if version is None: |
895 | 2715ade4 | Sofia Papagiannaki | permissions = request.backend.get_object_permissions( |
896 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, |
897 | 2715ade4 | Sofia Papagiannaki | v_account, v_container, v_object) |
898 | 2715ade4 | Sofia Papagiannaki | public = request.backend.get_object_public( |
899 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
900 | 2715ade4 | Sofia Papagiannaki | v_container, v_object) |
901 | e8886082 | Antony Chazapis | else:
|
902 | e8886082 | Antony Chazapis | permissions = None
|
903 | e0f916bb | Antony Chazapis | public = None
|
904 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
905 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
906 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
907 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
908 | 7efc9f86 | Sofia Papagiannaki | except VersionNotExists:
|
909 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Version does not exist') |
910 | 2715ade4 | Sofia Papagiannaki | |
911 | 8cb45c13 | Antony Chazapis | update_manifest_meta(request, v_account, meta) |
912 | 2715ade4 | Sofia Papagiannaki | update_sharing_meta( |
913 | 2715ade4 | Sofia Papagiannaki | request, permissions, v_account, v_container, v_object, meta) |
914 | 6fe32fb6 | Sofia Papagiannaki | if request.user_uniq == v_account:
|
915 | 6fe32fb6 | Sofia Papagiannaki | update_public_meta(public, meta) |
916 | 2715ade4 | Sofia Papagiannaki | |
917 | 22dab079 | Antony Chazapis | # Evaluate conditions.
|
918 | b956618e | Antony Chazapis | validate_modification_preconditions(request, meta) |
919 | 22dab079 | Antony Chazapis | try:
|
920 | 22dab079 | Antony Chazapis | validate_matching_preconditions(request, meta) |
921 | bd40abfa | Christos Stavrakakis | except faults.NotModified:
|
922 | 22dab079 | Antony Chazapis | response = HttpResponse(status=304)
|
923 | 133e3fcf | Sofia Papagiannaki | response['ETag'] = meta['hash'] if not UPDATE_MD5 else meta['checksum'] |
924 | 22dab079 | Antony Chazapis | return response
|
925 | 2715ade4 | Sofia Papagiannaki | |
926 | 2fd10ff4 | Antony Chazapis | hashmap_reply = False
|
927 | 2fd10ff4 | Antony Chazapis | if 'hashmap' in request.GET and request.serialization != 'text': |
928 | 2fd10ff4 | Antony Chazapis | hashmap_reply = True
|
929 | 2715ade4 | Sofia Papagiannaki | |
930 | 8cb45c13 | Antony Chazapis | sizes = [] |
931 | 8cb45c13 | Antony Chazapis | hashmaps = [] |
932 | 2fd10ff4 | Antony Chazapis | if 'X-Object-Manifest' in meta and not hashmap_reply: |
933 | 8cb45c13 | Antony Chazapis | try:
|
934 | 2715ade4 | Sofia Papagiannaki | src_container, src_name = split_container_object_string( |
935 | 2715ade4 | Sofia Papagiannaki | '/' + meta['X-Object-Manifest']) |
936 | 2715ade4 | Sofia Papagiannaki | objects = request.backend.list_objects( |
937 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
938 | 2715ade4 | Sofia Papagiannaki | src_container, prefix=src_name, virtual=False)
|
939 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
940 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
941 | 8cb45c13 | Antony Chazapis | except ValueError: |
942 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid X-Object-Manifest header') |
943 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
944 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
945 | 2715ade4 | Sofia Papagiannaki | |
946 | 8cb45c13 | Antony Chazapis | try:
|
947 | 8cb45c13 | Antony Chazapis | for x in objects: |
948 | 67100dd2 | Ilias Tsitsimpis | s, h = \ |
949 | 29148653 | Sofia Papagiannaki | request.backend.get_object_hashmap( |
950 | 29148653 | Sofia Papagiannaki | request.user_uniq, v_account, src_container, x[0],
|
951 | 29148653 | Sofia Papagiannaki | x[1])
|
952 | 8cb45c13 | Antony Chazapis | sizes.append(s) |
953 | 8cb45c13 | Antony Chazapis | hashmaps.append(h) |
954 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
955 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
956 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
957 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
958 | 7efc9f86 | Sofia Papagiannaki | except VersionNotExists:
|
959 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Version does not exist') |
960 | 8cb45c13 | Antony Chazapis | else:
|
961 | 8cb45c13 | Antony Chazapis | try:
|
962 | 2715ade4 | Sofia Papagiannaki | s, h = request.backend.get_object_hashmap( |
963 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
964 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, version) |
965 | 8cb45c13 | Antony Chazapis | sizes.append(s) |
966 | 8cb45c13 | Antony Chazapis | hashmaps.append(h) |
967 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
968 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
969 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
970 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
971 | 7efc9f86 | Sofia Papagiannaki | except VersionNotExists:
|
972 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Version does not exist') |
973 | 2715ade4 | Sofia Papagiannaki | |
974 | 22dab079 | Antony Chazapis | # Reply with the hashmap.
|
975 | 2fd10ff4 | Antony Chazapis | if hashmap_reply:
|
976 | 8cb45c13 | Antony Chazapis | size = sum(sizes)
|
977 | 8cb45c13 | Antony Chazapis | hashmap = sum(hashmaps, [])
|
978 | 39593b2b | Giorgos Verigakis | d = { |
979 | 39593b2b | Giorgos Verigakis | 'block_size': request.backend.block_size,
|
980 | 39593b2b | Giorgos Verigakis | 'block_hash': request.backend.hash_algorithm,
|
981 | 39593b2b | Giorgos Verigakis | 'bytes': size,
|
982 | 39593b2b | Giorgos Verigakis | 'hashes': hashmap}
|
983 | 22dab079 | Antony Chazapis | if request.serialization == 'xml': |
984 | 6bc372a4 | Antony Chazapis | d['object'] = v_object
|
985 | 6bc372a4 | Antony Chazapis | data = render_to_string('hashes.xml', d)
|
986 | 2715ade4 | Sofia Papagiannaki | elif request.serialization == 'json': |
987 | 6bc372a4 | Antony Chazapis | data = json.dumps(d) |
988 | 2715ade4 | Sofia Papagiannaki | |
989 | 22dab079 | Antony Chazapis | response = HttpResponse(data, status=200)
|
990 | 469d0997 | Georgios D. Tsoukalas | put_object_headers( |
991 | 67100dd2 | Ilias Tsitsimpis | response, meta, token=getattr(request, 'token', None)) |
992 | 22dab079 | Antony Chazapis | response['Content-Length'] = len(data) |
993 | 22dab079 | Antony Chazapis | return response
|
994 | 2715ade4 | Sofia Papagiannaki | |
995 | 2715ade4 | Sofia Papagiannaki | request.serialization = 'text' # Unset. |
996 | 8cb45c13 | Antony Chazapis | return object_data_response(request, sizes, hashmaps, meta)
|
997 | b956618e | Antony Chazapis | |
998 | 2715ade4 | Sofia Papagiannaki | |
999 | b90584d0 | Sofia Papagiannaki | @api_method('PUT', format_allowed=True, user_required=True, logger=logger, |
1000 | b90584d0 | Sofia Papagiannaki | lock_container_path=True)
|
1001 | b956618e | Antony Chazapis | def object_write(request, v_account, v_container, v_object): |
1002 | b956618e | Antony Chazapis | # Normal Response Codes: 201
|
1003 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
1004 | b956618e | Antony Chazapis | # unprocessableEntity (422),
|
1005 | b956618e | Antony Chazapis | # lengthRequired (411),
|
1006 | 3436eeb0 | Antony Chazapis | # conflict (409),
|
1007 | b956618e | Antony Chazapis | # itemNotFound (404),
|
1008 | 297513ba | Antony Chazapis | # forbidden (403),
|
1009 | b956618e | Antony Chazapis | # badRequest (400)
|
1010 | dfa2d4ba | Sofia Papagiannaki | # requestentitytoolarge (413)
|
1011 | 2715ade4 | Sofia Papagiannaki | |
1012 | a8326bef | Antony Chazapis | # Evaluate conditions.
|
1013 | 67100dd2 | Ilias Tsitsimpis | if (request.META.get('HTTP_IF_MATCH') |
1014 | 67100dd2 | Ilias Tsitsimpis | or request.META.get('HTTP_IF_NONE_MATCH')): |
1015 | a8326bef | Antony Chazapis | try:
|
1016 | 2715ade4 | Sofia Papagiannaki | meta = request.backend.get_object_meta( |
1017 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
1018 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, 'pithos')
|
1019 | a8326bef | Antony Chazapis | except NotAllowedError:
|
1020 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1021 | a8326bef | Antony Chazapis | except NameError: |
1022 | a8326bef | Antony Chazapis | meta = {} |
1023 | a8326bef | Antony Chazapis | validate_matching_preconditions(request, meta) |
1024 | 2715ade4 | Sofia Papagiannaki | |
1025 | 88283e9e | Antony Chazapis | copy_from = request.META.get('HTTP_X_COPY_FROM')
|
1026 | 88283e9e | Antony Chazapis | move_from = request.META.get('HTTP_X_MOVE_FROM')
|
1027 | b956618e | Antony Chazapis | if copy_from or move_from: |
1028 | 4d15c94e | Sofia Papagiannaki | delimiter = request.GET.get('delimiter')
|
1029 | 2715ade4 | Sofia Papagiannaki | content_length = get_content_length(request) # Required by the API.
|
1030 | 2715ade4 | Sofia Papagiannaki | |
1031 | 88283e9e | Antony Chazapis | src_account = request.META.get('HTTP_X_SOURCE_ACCOUNT')
|
1032 | f483f65d | Sofia Papagiannaki | |
1033 | 79bb41b7 | Antony Chazapis | if not src_account: |
1034 | 61efb530 | Antony Chazapis | src_account = request.user_uniq |
1035 | f483f65d | Sofia Papagiannaki | else:
|
1036 | f483f65d | Sofia Papagiannaki | if TRANSLATE_UUIDS:
|
1037 | f483f65d | Sofia Papagiannaki | try:
|
1038 | 29148653 | Sofia Papagiannaki | src_account = retrieve_uuid( |
1039 | 29148653 | Sofia Papagiannaki | getattr(request, 'token', None), src_account) |
1040 | f483f65d | Sofia Papagiannaki | except ItemNotExists:
|
1041 | bd40abfa | Christos Stavrakakis | faults.ItemNotFound('Invalid source account')
|
1042 | f483f65d | Sofia Papagiannaki | |
1043 | b956618e | Antony Chazapis | if move_from:
|
1044 | 83dd59c5 | Antony Chazapis | try:
|
1045 | 2715ade4 | Sofia Papagiannaki | src_container, src_name = split_container_object_string( |
1046 | 2715ade4 | Sofia Papagiannaki | move_from) |
1047 | 83dd59c5 | Antony Chazapis | except ValueError: |
1048 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid X-Move-From header') |
1049 | 2715ade4 | Sofia Papagiannaki | version_id = copy_or_move_object( |
1050 | 2715ade4 | Sofia Papagiannaki | request, src_account, src_container, src_name, |
1051 | 67100dd2 | Ilias Tsitsimpis | v_account, v_container, v_object, |
1052 | 67100dd2 | Ilias Tsitsimpis | move=True, delimiter=delimiter)
|
1053 | b956618e | Antony Chazapis | else:
|
1054 | 83dd59c5 | Antony Chazapis | try:
|
1055 | 2715ade4 | Sofia Papagiannaki | src_container, src_name = split_container_object_string( |
1056 | 2715ade4 | Sofia Papagiannaki | copy_from) |
1057 | 83dd59c5 | Antony Chazapis | except ValueError: |
1058 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid X-Copy-From header') |
1059 | 2715ade4 | Sofia Papagiannaki | version_id = copy_or_move_object( |
1060 | 2715ade4 | Sofia Papagiannaki | request, src_account, src_container, src_name, |
1061 | 67100dd2 | Ilias Tsitsimpis | v_account, v_container, v_object, |
1062 | 67100dd2 | Ilias Tsitsimpis | move=False, delimiter=delimiter)
|
1063 | 7dd293a0 | Antony Chazapis | response = HttpResponse(status=201)
|
1064 | 7dd293a0 | Antony Chazapis | response['X-Object-Version'] = version_id
|
1065 | 7dd293a0 | Antony Chazapis | return response
|
1066 | 2715ade4 | Sofia Papagiannaki | |
1067 | 66ce2ca5 | Antony Chazapis | content_type, meta, permissions, public = get_object_headers(request) |
1068 | b956618e | Antony Chazapis | content_length = -1
|
1069 | b956618e | Antony Chazapis | if request.META.get('HTTP_TRANSFER_ENCODING') != 'chunked': |
1070 | 22dab079 | Antony Chazapis | content_length = get_content_length(request) |
1071 | b956618e | Antony Chazapis | # Should be BadRequest, but API says otherwise.
|
1072 | dcffd53e | Antony Chazapis | if content_type is None: |
1073 | bd40abfa | Christos Stavrakakis | raise faults.LengthRequired('Missing Content-Type header') |
1074 | 2715ade4 | Sofia Papagiannaki | |
1075 | f9f15f92 | Antony Chazapis | if 'hashmap' in request.GET: |
1076 | f9f15f92 | Antony Chazapis | if request.serialization not in ('json', 'xml'): |
1077 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid hashmap format') |
1078 | 2715ade4 | Sofia Papagiannaki | |
1079 | 76985443 | Sofia Papagiannaki | data = ''
|
1080 | 39593b2b | Giorgos Verigakis | for block in socket_read_iterator(request, content_length, |
1081 | 2715ade4 | Sofia Papagiannaki | request.backend.block_size): |
1082 | 76985443 | Sofia Papagiannaki | data = '%s%s' % (data, block)
|
1083 | 2715ade4 | Sofia Papagiannaki | |
1084 | 32a437b1 | Sofia Papagiannaki | if request.serialization == 'json': |
1085 | 32a437b1 | Sofia Papagiannaki | d = json.loads(data) |
1086 | 32a437b1 | Sofia Papagiannaki | if not hasattr(d, '__getitem__'): |
1087 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid data formating') |
1088 | 32a437b1 | Sofia Papagiannaki | try:
|
1089 | 32a437b1 | Sofia Papagiannaki | hashmap = d['hashes']
|
1090 | f899c7b4 | Antony Chazapis | size = int(d['bytes']) |
1091 | f899c7b4 | Antony Chazapis | except:
|
1092 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid data formatting') |
1093 | 32a437b1 | Sofia Papagiannaki | elif request.serialization == 'xml': |
1094 | 32a437b1 | Sofia Papagiannaki | try:
|
1095 | 32a437b1 | Sofia Papagiannaki | xml = minidom.parseString(data) |
1096 | 32a437b1 | Sofia Papagiannaki | obj = xml.getElementsByTagName('object')[0] |
1097 | f899c7b4 | Antony Chazapis | size = int(obj.attributes['bytes'].value) |
1098 | 2715ade4 | Sofia Papagiannaki | |
1099 | 32a437b1 | Sofia Papagiannaki | hashes = xml.getElementsByTagName('hash')
|
1100 | 32a437b1 | Sofia Papagiannaki | hashmap = [] |
1101 | 32a437b1 | Sofia Papagiannaki | for hash in hashes: |
1102 | 32a437b1 | Sofia Papagiannaki | hashmap.append(hash.firstChild.data)
|
1103 | f899c7b4 | Antony Chazapis | except:
|
1104 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid data formatting') |
1105 | 2715ade4 | Sofia Papagiannaki | |
1106 | 2715ade4 | Sofia Papagiannaki | checksum = '' # Do not set to None (will copy previous value). |
1107 | 76985443 | Sofia Papagiannaki | else:
|
1108 | 133e3fcf | Sofia Papagiannaki | etag = request.META.get('HTTP_ETAG')
|
1109 | 133e3fcf | Sofia Papagiannaki | checksum_compute = Checksum() if etag or UPDATE_MD5 else NoChecksum() |
1110 | 76985443 | Sofia Papagiannaki | size = 0
|
1111 | 76985443 | Sofia Papagiannaki | hashmap = [] |
1112 | 39593b2b | Giorgos Verigakis | for data in socket_read_iterator(request, content_length, |
1113 | 2715ade4 | Sofia Papagiannaki | request.backend.block_size): |
1114 | 76985443 | Sofia Papagiannaki | # TODO: Raise 408 (Request Timeout) if this takes too long.
|
1115 | 67100dd2 | Ilias Tsitsimpis | # TODO: Raise 499 (Client Disconnect) if a length is defined
|
1116 | 67100dd2 | Ilias Tsitsimpis | # and we stop before getting this much data.
|
1117 | 76985443 | Sofia Papagiannaki | size += len(data)
|
1118 | 39593b2b | Giorgos Verigakis | hashmap.append(request.backend.put_block(data)) |
1119 | 133e3fcf | Sofia Papagiannaki | checksum_compute.update(data) |
1120 | 2715ade4 | Sofia Papagiannaki | |
1121 | 133e3fcf | Sofia Papagiannaki | checksum = checksum_compute.hexdigest() |
1122 | 33b4e4a6 | Antony Chazapis | if etag and parse_etags(etag)[0].lower() != checksum: |
1123 | bd40abfa | Christos Stavrakakis | raise faults.UnprocessableEntity('Object ETag does not match') |
1124 | 2715ade4 | Sofia Papagiannaki | |
1125 | 22dab079 | Antony Chazapis | try:
|
1126 | 133e3fcf | Sofia Papagiannaki | version_id, merkle = request.backend.update_object_hashmap( |
1127 | 133e3fcf | Sofia Papagiannaki | request.user_uniq, v_account, v_container, v_object, size, |
1128 | 133e3fcf | Sofia Papagiannaki | content_type, hashmap, checksum, 'pithos', meta, True, permissions |
1129 | 133e3fcf | Sofia Papagiannaki | ) |
1130 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
1131 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1132 | 76985443 | Sofia Papagiannaki | except IndexError, e: |
1133 | e9d94604 | Sofia Papagiannaki | missing_blocks = e.data |
1134 | e9d94604 | Sofia Papagiannaki | response = HttpResponse(status=409)
|
1135 | e9d94604 | Sofia Papagiannaki | response.content = simple_list_response(request, missing_blocks) |
1136 | e9d94604 | Sofia Papagiannaki | return response
|
1137 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1138 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
1139 | 3436eeb0 | Antony Chazapis | except ValueError: |
1140 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid sharing header') |
1141 | ccfd4e44 | Sofia Papagiannaki | except QuotaError, e:
|
1142 | bd40abfa | Christos Stavrakakis | raise faults.RequestEntityTooLarge('Quota error: %s' % e) |
1143 | 3a5994a8 | Sofia Papagiannaki | except InvalidHash, e:
|
1144 | 3a5994a8 | Sofia Papagiannaki | raise faults.BadRequest('Invalid hash: %s' % e) |
1145 | 8efd183f | Antony Chazapis | if not checksum and UPDATE_MD5: |
1146 | cddcf432 | chazapis | # Update the MD5 after the hashmap, as there may be missing hashes.
|
1147 | b3155065 | Antony Chazapis | checksum = hashmap_md5(request.backend, hashmap, size) |
1148 | cddcf432 | chazapis | try:
|
1149 | b3155065 | Antony Chazapis | request.backend.update_object_checksum(request.user_uniq, |
1150 | 67100dd2 | Ilias Tsitsimpis | v_account, v_container, |
1151 | 67100dd2 | Ilias Tsitsimpis | v_object, version_id, |
1152 | 67100dd2 | Ilias Tsitsimpis | checksum) |
1153 | cddcf432 | chazapis | except NotAllowedError:
|
1154 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1155 | e0f916bb | Antony Chazapis | if public is not None: |
1156 | e0f916bb | Antony Chazapis | try:
|
1157 | 61efb530 | Antony Chazapis | request.backend.update_object_public(request.user_uniq, v_account, |
1158 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, public) |
1159 | e0f916bb | Antony Chazapis | except NotAllowedError:
|
1160 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1161 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1162 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1163 | 2715ade4 | Sofia Papagiannaki | |
1164 | 1993fea9 | Antony Chazapis | response = HttpResponse(status=201)
|
1165 | 133e3fcf | Sofia Papagiannaki | response['ETag'] = merkle if not UPDATE_MD5 else checksum |
1166 | 7dd293a0 | Antony Chazapis | response['X-Object-Version'] = version_id
|
1167 | b956618e | Antony Chazapis | return response
|
1168 | b956618e | Antony Chazapis | |
1169 | 2715ade4 | Sofia Papagiannaki | |
1170 | 29148653 | Sofia Papagiannaki | @api_method('POST', user_required=True, logger=logger, |
1171 | 29148653 | Sofia Papagiannaki | lock_container_path=True)
|
1172 | 1d5c57d3 | Antony Chazapis | def object_write_form(request, v_account, v_container, v_object): |
1173 | 1d5c57d3 | Antony Chazapis | # Normal Response Codes: 201
|
1174 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
1175 | 1d5c57d3 | Antony Chazapis | # itemNotFound (404),
|
1176 | 297513ba | Antony Chazapis | # forbidden (403),
|
1177 | 1d5c57d3 | Antony Chazapis | # badRequest (400)
|
1178 | dfa2d4ba | Sofia Papagiannaki | # requestentitytoolarge (413)
|
1179 | 2715ade4 | Sofia Papagiannaki | |
1180 | 817890f2 | Antony Chazapis | request.upload_handlers = [SaveToBackendHandler(request)] |
1181 | 2715ade4 | Sofia Papagiannaki | if 'X-Object-Data' not in request.FILES: |
1182 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Missing X-Object-Data field') |
1183 | 1d5c57d3 | Antony Chazapis | file = request.FILES['X-Object-Data']
|
1184 | 2715ade4 | Sofia Papagiannaki | |
1185 | 33b4e4a6 | Antony Chazapis | checksum = file.etag
|
1186 | 1d5c57d3 | Antony Chazapis | try:
|
1187 | 133e3fcf | Sofia Papagiannaki | version_id, merkle = request.backend.update_object_hashmap( |
1188 | 133e3fcf | Sofia Papagiannaki | request.user_uniq, v_account, v_container, v_object, file.size,
|
1189 | 133e3fcf | Sofia Papagiannaki | file.content_type, file.hashmap, checksum, 'pithos', {}, True |
1190 | 133e3fcf | Sofia Papagiannaki | ) |
1191 | 1d5c57d3 | Antony Chazapis | except NotAllowedError:
|
1192 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1193 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1194 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
1195 | ccfd4e44 | Sofia Papagiannaki | except QuotaError, e:
|
1196 | bd40abfa | Christos Stavrakakis | raise faults.RequestEntityTooLarge('Quota error: %s' % e) |
1197 | 2715ade4 | Sofia Papagiannaki | |
1198 | 1d5c57d3 | Antony Chazapis | response = HttpResponse(status=201)
|
1199 | 133e3fcf | Sofia Papagiannaki | response['ETag'] = merkle if not UPDATE_MD5 else checksum |
1200 | 7dd293a0 | Antony Chazapis | response['X-Object-Version'] = version_id
|
1201 | 33b4e4a6 | Antony Chazapis | response.content = checksum |
1202 | 1d5c57d3 | Antony Chazapis | return response
|
1203 | 1d5c57d3 | Antony Chazapis | |
1204 | 2715ade4 | Sofia Papagiannaki | |
1205 | b90584d0 | Sofia Papagiannaki | @api_method('COPY', format_allowed=True, user_required=True, logger=logger, |
1206 | b90584d0 | Sofia Papagiannaki | lock_container_path=True)
|
1207 | b956618e | Antony Chazapis | def object_copy(request, v_account, v_container, v_object): |
1208 | b956618e | Antony Chazapis | # Normal Response Codes: 201
|
1209 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
1210 | b956618e | Antony Chazapis | # itemNotFound (404),
|
1211 | 297513ba | Antony Chazapis | # forbidden (403),
|
1212 | b956618e | Antony Chazapis | # badRequest (400)
|
1213 | dfa2d4ba | Sofia Papagiannaki | # requestentitytoolarge (413)
|
1214 | 2715ade4 | Sofia Papagiannaki | |
1215 | 88283e9e | Antony Chazapis | dest_account = request.META.get('HTTP_DESTINATION_ACCOUNT')
|
1216 | 79bb41b7 | Antony Chazapis | if not dest_account: |
1217 | 61efb530 | Antony Chazapis | dest_account = request.user_uniq |
1218 | 88283e9e | Antony Chazapis | dest_path = request.META.get('HTTP_DESTINATION')
|
1219 | b956618e | Antony Chazapis | if not dest_path: |
1220 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Missing Destination header') |
1221 | 83dd59c5 | Antony Chazapis | try:
|
1222 | 83dd59c5 | Antony Chazapis | dest_container, dest_name = split_container_object_string(dest_path) |
1223 | 83dd59c5 | Antony Chazapis | except ValueError: |
1224 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid Destination header') |
1225 | 2715ade4 | Sofia Papagiannaki | |
1226 | a8326bef | Antony Chazapis | # Evaluate conditions.
|
1227 | 67100dd2 | Ilias Tsitsimpis | if (request.META.get('HTTP_IF_MATCH') |
1228 | 67100dd2 | Ilias Tsitsimpis | or request.META.get('HTTP_IF_NONE_MATCH')): |
1229 | a8326bef | Antony Chazapis | src_version = request.META.get('HTTP_X_SOURCE_VERSION')
|
1230 | a8326bef | Antony Chazapis | try:
|
1231 | 2715ade4 | Sofia Papagiannaki | meta = request.backend.get_object_meta( |
1232 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
1233 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, 'pithos', src_version)
|
1234 | a8326bef | Antony Chazapis | except NotAllowedError:
|
1235 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1236 | 7efc9f86 | Sofia Papagiannaki | except (ItemNotExists, VersionNotExists):
|
1237 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container or object does not exist') |
1238 | a8326bef | Antony Chazapis | validate_matching_preconditions(request, meta) |
1239 | 2715ade4 | Sofia Papagiannaki | |
1240 | 4d15c94e | Sofia Papagiannaki | delimiter = request.GET.get('delimiter')
|
1241 | 2715ade4 | Sofia Papagiannaki | |
1242 | 79bb41b7 | Antony Chazapis | version_id = copy_or_move_object(request, v_account, v_container, v_object, |
1243 | 67100dd2 | Ilias Tsitsimpis | dest_account, dest_container, dest_name, |
1244 | 67100dd2 | Ilias Tsitsimpis | move=False, delimiter=delimiter)
|
1245 | 7dd293a0 | Antony Chazapis | response = HttpResponse(status=201)
|
1246 | 7dd293a0 | Antony Chazapis | response['X-Object-Version'] = version_id
|
1247 | 7dd293a0 | Antony Chazapis | return response
|
1248 | b956618e | Antony Chazapis | |
1249 | 2715ade4 | Sofia Papagiannaki | |
1250 | b90584d0 | Sofia Papagiannaki | @api_method('MOVE', format_allowed=True, user_required=True, logger=logger, |
1251 | b90584d0 | Sofia Papagiannaki | lock_container_path=True)
|
1252 | b956618e | Antony Chazapis | def object_move(request, v_account, v_container, v_object): |
1253 | b956618e | Antony Chazapis | # Normal Response Codes: 201
|
1254 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
1255 | b956618e | Antony Chazapis | # itemNotFound (404),
|
1256 | 297513ba | Antony Chazapis | # forbidden (403),
|
1257 | b956618e | Antony Chazapis | # badRequest (400)
|
1258 | dfa2d4ba | Sofia Papagiannaki | # requestentitytoolarge (413)
|
1259 | 2715ade4 | Sofia Papagiannaki | |
1260 | 88283e9e | Antony Chazapis | dest_account = request.META.get('HTTP_DESTINATION_ACCOUNT')
|
1261 | 79bb41b7 | Antony Chazapis | if not dest_account: |
1262 | 61efb530 | Antony Chazapis | dest_account = request.user_uniq |
1263 | 88283e9e | Antony Chazapis | dest_path = request.META.get('HTTP_DESTINATION')
|
1264 | b956618e | Antony Chazapis | if not dest_path: |
1265 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Missing Destination header') |
1266 | 83dd59c5 | Antony Chazapis | try:
|
1267 | 83dd59c5 | Antony Chazapis | dest_container, dest_name = split_container_object_string(dest_path) |
1268 | 83dd59c5 | Antony Chazapis | except ValueError: |
1269 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid Destination header') |
1270 | 2715ade4 | Sofia Papagiannaki | |
1271 | a8326bef | Antony Chazapis | # Evaluate conditions.
|
1272 | 67100dd2 | Ilias Tsitsimpis | if (request.META.get('HTTP_IF_MATCH') |
1273 | 67100dd2 | Ilias Tsitsimpis | or request.META.get('HTTP_IF_NONE_MATCH')): |
1274 | a8326bef | Antony Chazapis | try:
|
1275 | 2715ade4 | Sofia Papagiannaki | meta = request.backend.get_object_meta( |
1276 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
1277 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, 'pithos')
|
1278 | a8326bef | Antony Chazapis | except NotAllowedError:
|
1279 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1280 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1281 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container or object does not exist') |
1282 | a8326bef | Antony Chazapis | validate_matching_preconditions(request, meta) |
1283 | 2715ade4 | Sofia Papagiannaki | |
1284 | 4d15c94e | Sofia Papagiannaki | delimiter = request.GET.get('delimiter')
|
1285 | 2715ade4 | Sofia Papagiannaki | |
1286 | 79bb41b7 | Antony Chazapis | version_id = copy_or_move_object(request, v_account, v_container, v_object, |
1287 | 67100dd2 | Ilias Tsitsimpis | dest_account, dest_container, dest_name, |
1288 | 67100dd2 | Ilias Tsitsimpis | move=True, delimiter=delimiter)
|
1289 | 7dd293a0 | Antony Chazapis | response = HttpResponse(status=201)
|
1290 | 7dd293a0 | Antony Chazapis | response['X-Object-Version'] = version_id
|
1291 | 7dd293a0 | Antony Chazapis | return response
|
1292 | b956618e | Antony Chazapis | |
1293 | 2715ade4 | Sofia Papagiannaki | |
1294 | b90584d0 | Sofia Papagiannaki | @api_method('POST', format_allowed=True, user_required=True, logger=logger, |
1295 | b90584d0 | Sofia Papagiannaki | lock_container_path=True)
|
1296 | b956618e | Antony Chazapis | def object_update(request, v_account, v_container, v_object): |
1297 | e9285524 | Antony Chazapis | # Normal Response Codes: 202, 204
|
1298 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
1299 | 3436eeb0 | Antony Chazapis | # conflict (409),
|
1300 | b956618e | Antony Chazapis | # itemNotFound (404),
|
1301 | 297513ba | Antony Chazapis | # forbidden (403),
|
1302 | b956618e | Antony Chazapis | # badRequest (400)
|
1303 | 2715ade4 | Sofia Papagiannaki | |
1304 | 66ce2ca5 | Antony Chazapis | content_type, meta, permissions, public = get_object_headers(request) |
1305 | 2715ade4 | Sofia Papagiannaki | |
1306 | cfe6939d | Antony Chazapis | try:
|
1307 | 2715ade4 | Sofia Papagiannaki | prev_meta = request.backend.get_object_meta( |
1308 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
1309 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, 'pithos')
|
1310 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
1311 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1312 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1313 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1314 | 2715ade4 | Sofia Papagiannaki | |
1315 | a8326bef | Antony Chazapis | # Evaluate conditions.
|
1316 | 67100dd2 | Ilias Tsitsimpis | if (request.META.get('HTTP_IF_MATCH') |
1317 | 67100dd2 | Ilias Tsitsimpis | or request.META.get('HTTP_IF_NONE_MATCH')): |
1318 | a8326bef | Antony Chazapis | validate_matching_preconditions(request, prev_meta) |
1319 | 2715ade4 | Sofia Papagiannaki | |
1320 | ac62f6da | Antony Chazapis | replace = True
|
1321 | ac62f6da | Antony Chazapis | if 'update' in request.GET: |
1322 | ac62f6da | Antony Chazapis | replace = False
|
1323 | 2715ade4 | Sofia Papagiannaki | |
1324 | ab2e317e | Antony Chazapis | # A Content-Type or X-Source-Object header indicates data updates.
|
1325 | ab2e317e | Antony Chazapis | src_object = request.META.get('HTTP_X_SOURCE_OBJECT')
|
1326 | 67100dd2 | Ilias Tsitsimpis | if ((not content_type or content_type != 'application/octet-stream') |
1327 | 67100dd2 | Ilias Tsitsimpis | and not src_object): |
1328 | 77edd23d | Antony Chazapis | response = HttpResponse(status=202)
|
1329 | 2715ade4 | Sofia Papagiannaki | |
1330 | cca6c617 | Antony Chazapis | # Do permissions first, as it may fail easier.
|
1331 | cca6c617 | Antony Chazapis | if permissions is not None: |
1332 | ac62f6da | Antony Chazapis | try:
|
1333 | 29148653 | Sofia Papagiannaki | request.backend.update_object_permissions( |
1334 | 29148653 | Sofia Papagiannaki | request.user_uniq, v_account, v_container, v_object, |
1335 | 29148653 | Sofia Papagiannaki | permissions) |
1336 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
1337 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1338 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1339 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1340 | ac62f6da | Antony Chazapis | except ValueError: |
1341 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid sharing header') |
1342 | e0f916bb | Antony Chazapis | if public is not None: |
1343 | e0f916bb | Antony Chazapis | try:
|
1344 | 2715ade4 | Sofia Papagiannaki | request.backend.update_object_public( |
1345 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, |
1346 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, public) |
1347 | e0f916bb | Antony Chazapis | except NotAllowedError:
|
1348 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1349 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1350 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1351 | 77edd23d | Antony Chazapis | if meta or replace: |
1352 | 77edd23d | Antony Chazapis | try:
|
1353 | 2715ade4 | Sofia Papagiannaki | version_id = request.backend.update_object_meta( |
1354 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, |
1355 | 2715ade4 | Sofia Papagiannaki | v_account, v_container, v_object, 'pithos', meta, replace)
|
1356 | 77edd23d | Antony Chazapis | except NotAllowedError:
|
1357 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1358 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1359 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1360 | 77edd23d | Antony Chazapis | response['X-Object-Version'] = version_id
|
1361 | 2715ade4 | Sofia Papagiannaki | |
1362 | 7dd293a0 | Antony Chazapis | return response
|
1363 | 2715ade4 | Sofia Papagiannaki | |
1364 | cfe6939d | Antony Chazapis | # Single range update. Range must be in Content-Range.
|
1365 | 22dab079 | Antony Chazapis | # Based on: http://code.google.com/p/gears/wiki/ContentRangePostProposal
|
1366 | cfe6939d | Antony Chazapis | # (with the addition that '*' is allowed for the range - will append).
|
1367 | 22dab079 | Antony Chazapis | content_range = request.META.get('HTTP_CONTENT_RANGE')
|
1368 | 22dab079 | Antony Chazapis | if not content_range: |
1369 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Missing Content-Range header') |
1370 | 22dab079 | Antony Chazapis | ranges = get_content_range(request) |
1371 | 22dab079 | Antony Chazapis | if not ranges: |
1372 | bd40abfa | Christos Stavrakakis | raise faults.RangeNotSatisfiable('Invalid Content-Range header') |
1373 | 2715ade4 | Sofia Papagiannaki | |
1374 | cfe6939d | Antony Chazapis | try:
|
1375 | 67100dd2 | Ilias Tsitsimpis | size, hashmap = \ |
1376 | 29148653 | Sofia Papagiannaki | request.backend.get_object_hashmap( |
1377 | 29148653 | Sofia Papagiannaki | request.user_uniq, v_account, v_container, v_object) |
1378 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
1379 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1380 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1381 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1382 | 2715ade4 | Sofia Papagiannaki | |
1383 | cfe6939d | Antony Chazapis | offset, length, total = ranges |
1384 | cfe6939d | Antony Chazapis | if offset is None: |
1385 | cfe6939d | Antony Chazapis | offset = size |
1386 | cb146cf9 | Antony Chazapis | elif offset > size:
|
1387 | 67100dd2 | Ilias Tsitsimpis | raise faults.RangeNotSatisfiable(
|
1388 | 67100dd2 | Ilias Tsitsimpis | 'Supplied offset is beyond object limits')
|
1389 | ab2e317e | Antony Chazapis | if src_object:
|
1390 | 88283e9e | Antony Chazapis | src_account = request.META.get('HTTP_X_SOURCE_ACCOUNT')
|
1391 | 2cd94d81 | Antony Chazapis | if not src_account: |
1392 | 61efb530 | Antony Chazapis | src_account = request.user_uniq |
1393 | ab2e317e | Antony Chazapis | try:
|
1394 | 752a2ddd | Sofia Papagiannaki | src_container, src_name = split_container_object_string(src_object) |
1395 | 752a2ddd | Sofia Papagiannaki | except ValueError: |
1396 | 752a2ddd | Sofia Papagiannaki | raise faults.BadRequest('Invalid source object') |
1397 | 752a2ddd | Sofia Papagiannaki | |
1398 | 752a2ddd | Sofia Papagiannaki | try:
|
1399 | 752a2ddd | Sofia Papagiannaki | src_version = request.META.get('HTTP_X_SOURCE_VERSION')
|
1400 | 2715ade4 | Sofia Papagiannaki | src_size, src_hashmap = request.backend.get_object_hashmap( |
1401 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, |
1402 | 2715ade4 | Sofia Papagiannaki | src_account, src_container, src_name, src_version) |
1403 | ab2e317e | Antony Chazapis | except NotAllowedError:
|
1404 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1405 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1406 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Source object does not exist') |
1407 | 2715ade4 | Sofia Papagiannaki | |
1408 | ab2e317e | Antony Chazapis | if length is None: |
1409 | ab2e317e | Antony Chazapis | length = src_size |
1410 | ab2e317e | Antony Chazapis | elif length > src_size:
|
1411 | 67100dd2 | Ilias Tsitsimpis | raise faults.BadRequest(
|
1412 | 67100dd2 | Ilias Tsitsimpis | 'Object length is smaller than range length')
|
1413 | ab2e317e | Antony Chazapis | else:
|
1414 | ab2e317e | Antony Chazapis | # Require either a Content-Length, or 'chunked' Transfer-Encoding.
|
1415 | ab2e317e | Antony Chazapis | content_length = -1
|
1416 | ab2e317e | Antony Chazapis | if request.META.get('HTTP_TRANSFER_ENCODING') != 'chunked': |
1417 | ab2e317e | Antony Chazapis | content_length = get_content_length(request) |
1418 | 2715ade4 | Sofia Papagiannaki | |
1419 | ab2e317e | Antony Chazapis | if length is None: |
1420 | ab2e317e | Antony Chazapis | length = content_length |
1421 | ab2e317e | Antony Chazapis | else:
|
1422 | ab2e317e | Antony Chazapis | if content_length == -1: |
1423 | ab2e317e | Antony Chazapis | # TODO: Get up to length bytes in chunks.
|
1424 | ab2e317e | Antony Chazapis | length = content_length |
1425 | ab2e317e | Antony Chazapis | elif length != content_length:
|
1426 | 67100dd2 | Ilias Tsitsimpis | raise faults.BadRequest(
|
1427 | 67100dd2 | Ilias Tsitsimpis | 'Content length does not match range length')
|
1428 | 67100dd2 | Ilias Tsitsimpis | if (total is not None |
1429 | 67100dd2 | Ilias Tsitsimpis | and (total != size or offset >= size |
1430 | 7b40f056 | Sofia Papagiannaki | or (length > 0 and offset + length > size))): |
1431 | bd40abfa | Christos Stavrakakis | raise faults.RangeNotSatisfiable(
|
1432 | 2715ade4 | Sofia Papagiannaki | 'Supplied range will change provided object limits')
|
1433 | 2715ade4 | Sofia Papagiannaki | |
1434 | 1495b972 | Antony Chazapis | dest_bytes = request.META.get('HTTP_X_OBJECT_BYTES')
|
1435 | 1495b972 | Antony Chazapis | if dest_bytes is not None: |
1436 | 1495b972 | Antony Chazapis | dest_bytes = get_int_parameter(dest_bytes) |
1437 | 1495b972 | Antony Chazapis | if dest_bytes is None: |
1438 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid X-Object-Bytes header') |
1439 | 2715ade4 | Sofia Papagiannaki | |
1440 | ab2e317e | Antony Chazapis | if src_object:
|
1441 | 39593b2b | Giorgos Verigakis | if offset % request.backend.block_size == 0: |
1442 | ab2e317e | Antony Chazapis | # Update the hashes only.
|
1443 | ab2e317e | Antony Chazapis | sbi = 0
|
1444 | ab2e317e | Antony Chazapis | while length > 0: |
1445 | 39593b2b | Giorgos Verigakis | bi = int(offset / request.backend.block_size)
|
1446 | 39593b2b | Giorgos Verigakis | bl = min(length, request.backend.block_size)
|
1447 | ab2e317e | Antony Chazapis | if bi < len(hashmap): |
1448 | 39593b2b | Giorgos Verigakis | if bl == request.backend.block_size:
|
1449 | ab2e317e | Antony Chazapis | hashmap[bi] = src_hashmap[sbi] |
1450 | ab2e317e | Antony Chazapis | else:
|
1451 | 39593b2b | Giorgos Verigakis | data = request.backend.get_block(src_hashmap[sbi]) |
1452 | 29148653 | Sofia Papagiannaki | hashmap[bi] = request.backend.update_block( |
1453 | 29148653 | Sofia Papagiannaki | hashmap[bi], data[:bl], 0)
|
1454 | ab2e317e | Antony Chazapis | else:
|
1455 | ab2e317e | Antony Chazapis | hashmap.append(src_hashmap[sbi]) |
1456 | ab2e317e | Antony Chazapis | offset += bl |
1457 | ab2e317e | Antony Chazapis | length -= bl |
1458 | ab2e317e | Antony Chazapis | sbi += 1
|
1459 | ab2e317e | Antony Chazapis | else:
|
1460 | ab2e317e | Antony Chazapis | data = ''
|
1461 | ab2e317e | Antony Chazapis | sbi = 0
|
1462 | ab2e317e | Antony Chazapis | while length > 0: |
1463 | f5da7eaa | Sofia Papagiannaki | if sbi < len(src_hashmap): |
1464 | f5da7eaa | Sofia Papagiannaki | data += request.backend.get_block(src_hashmap[sbi]) |
1465 | 39593b2b | Giorgos Verigakis | if length < request.backend.block_size:
|
1466 | ab2e317e | Antony Chazapis | data = data[:length] |
1467 | 39593b2b | Giorgos Verigakis | bytes = put_object_block(request, hashmap, data, offset) |
1468 | ab2e317e | Antony Chazapis | offset += bytes
|
1469 | ab2e317e | Antony Chazapis | data = data[bytes:]
|
1470 | ab2e317e | Antony Chazapis | length -= bytes
|
1471 | ab2e317e | Antony Chazapis | sbi += 1
|
1472 | ab2e317e | Antony Chazapis | else:
|
1473 | ab2e317e | Antony Chazapis | data = ''
|
1474 | 39593b2b | Giorgos Verigakis | for d in socket_read_iterator(request, length, |
1475 | 2715ade4 | Sofia Papagiannaki | request.backend.block_size): |
1476 | ab2e317e | Antony Chazapis | # TODO: Raise 408 (Request Timeout) if this takes too long.
|
1477 | 67100dd2 | Ilias Tsitsimpis | # TODO: Raise 499 (Client Disconnect) if a length is defined
|
1478 | 67100dd2 | Ilias Tsitsimpis | # and we stop before getting this much data.
|
1479 | ab2e317e | Antony Chazapis | data += d |
1480 | 39593b2b | Giorgos Verigakis | bytes = put_object_block(request, hashmap, data, offset) |
1481 | ab2e317e | Antony Chazapis | offset += bytes
|
1482 | ab2e317e | Antony Chazapis | data = data[bytes:]
|
1483 | ab2e317e | Antony Chazapis | if len(data) > 0: |
1484 | 80d668be | Sofia Papagiannaki | bytes = put_object_block(request, hashmap, data, offset) |
1485 | 80d668be | Sofia Papagiannaki | offset += bytes
|
1486 | 2715ade4 | Sofia Papagiannaki | |
1487 | cfe6939d | Antony Chazapis | if offset > size:
|
1488 | cfe6939d | Antony Chazapis | size = offset |
1489 | 1495b972 | Antony Chazapis | if dest_bytes is not None and dest_bytes < size: |
1490 | 1495b972 | Antony Chazapis | size = dest_bytes |
1491 | 39593b2b | Giorgos Verigakis | hashmap = hashmap[:(int((size - 1) / request.backend.block_size) + 1)] |
1492 | 2715ade4 | Sofia Papagiannaki | checksum = hashmap_md5( |
1493 | 2715ade4 | Sofia Papagiannaki | request.backend, hashmap, size) if UPDATE_MD5 else '' |
1494 | cfe6939d | Antony Chazapis | try:
|
1495 | 133e3fcf | Sofia Papagiannaki | version_id, merkle = request.backend.update_object_hashmap( |
1496 | 133e3fcf | Sofia Papagiannaki | request.user_uniq, v_account, v_container, v_object, size, |
1497 | 133e3fcf | Sofia Papagiannaki | prev_meta['type'], hashmap, checksum, 'pithos', meta, replace, |
1498 | 133e3fcf | Sofia Papagiannaki | permissions |
1499 | 133e3fcf | Sofia Papagiannaki | ) |
1500 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
1501 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1502 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1503 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Container does not exist') |
1504 | 3436eeb0 | Antony Chazapis | except ValueError: |
1505 | bd40abfa | Christos Stavrakakis | raise faults.BadRequest('Invalid sharing header') |
1506 | ccfd4e44 | Sofia Papagiannaki | except QuotaError, e:
|
1507 | bd40abfa | Christos Stavrakakis | raise faults.RequestEntityTooLarge('Quota error: %s' % e) |
1508 | e0f916bb | Antony Chazapis | if public is not None: |
1509 | e0f916bb | Antony Chazapis | try:
|
1510 | 61efb530 | Antony Chazapis | request.backend.update_object_public(request.user_uniq, v_account, |
1511 | 2715ade4 | Sofia Papagiannaki | v_container, v_object, public) |
1512 | e0f916bb | Antony Chazapis | except NotAllowedError:
|
1513 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1514 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1515 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1516 | 2715ade4 | Sofia Papagiannaki | |
1517 | e9285524 | Antony Chazapis | response = HttpResponse(status=204)
|
1518 | 133e3fcf | Sofia Papagiannaki | response['ETag'] = merkle if not UPDATE_MD5 else checksum |
1519 | 7dd293a0 | Antony Chazapis | response['X-Object-Version'] = version_id
|
1520 | e9285524 | Antony Chazapis | return response
|
1521 | b956618e | Antony Chazapis | |
1522 | 2715ade4 | Sofia Papagiannaki | |
1523 | b90584d0 | Sofia Papagiannaki | @api_method('DELETE', user_required=True, logger=logger, |
1524 | b90584d0 | Sofia Papagiannaki | lock_container_path=True)
|
1525 | b956618e | Antony Chazapis | def object_delete(request, v_account, v_container, v_object): |
1526 | b956618e | Antony Chazapis | # Normal Response Codes: 204
|
1527 | 08de868d | Antony Chazapis | # Error Response Codes: internalServerError (500),
|
1528 | b956618e | Antony Chazapis | # itemNotFound (404),
|
1529 | 297513ba | Antony Chazapis | # forbidden (403),
|
1530 | b956618e | Antony Chazapis | # badRequest (400)
|
1531 | dfa2d4ba | Sofia Papagiannaki | # requestentitytoolarge (413)
|
1532 | 2715ade4 | Sofia Papagiannaki | |
1533 | bbd20b55 | Antony Chazapis | until = get_int_parameter(request.GET.get('until'))
|
1534 | 4d15c94e | Sofia Papagiannaki | delimiter = request.GET.get('delimiter')
|
1535 | 2715ade4 | Sofia Papagiannaki | |
1536 | b956618e | Antony Chazapis | try:
|
1537 | 2715ade4 | Sofia Papagiannaki | request.backend.delete_object( |
1538 | 2715ade4 | Sofia Papagiannaki | request.user_uniq, v_account, v_container, |
1539 | 2715ade4 | Sofia Papagiannaki | v_object, until, delimiter=delimiter) |
1540 | cca6c617 | Antony Chazapis | except NotAllowedError:
|
1541 | bd40abfa | Christos Stavrakakis | raise faults.Forbidden('Not allowed') |
1542 | 7efc9f86 | Sofia Papagiannaki | except ItemNotExists:
|
1543 | bd40abfa | Christos Stavrakakis | raise faults.ItemNotFound('Object does not exist') |
1544 | dfa2d4ba | Sofia Papagiannaki | except QuotaError, e:
|
1545 | bd40abfa | Christos Stavrakakis | raise faults.RequestEntityTooLarge('Quota error: %s' % e) |
1546 | b956618e | Antony Chazapis | return HttpResponse(status=204) |