# or implied, of GRNET S.A.
from xml.dom import minidom
+from urllib import unquote
from django.conf import settings
from django.http import HttpResponse
validate_modification_preconditions, validate_matching_preconditions, split_container_object_string,
copy_or_move_object, get_int_parameter, get_content_length, get_content_range, socket_read_iterator,
SaveToBackendHandler, object_data_response, put_object_block, hashmap_md5, simple_list_response, api_method)
-from pithos.api.settings import AUTHENTICATION_URL, AUTHENTICATION_USERS, COOKIE_NAME
+from pithos.api.settings import UPDATE_MD5
+
+from pithos.backends.base import NotAllowedError, QuotaError, ContainerNotEmpty, ItemNotExists, VersionNotExists
-from pithos.backends.base import NotAllowedError, QuotaError
from pithos.backends.filter import parse_filters
import logging
@csrf_exempt
def top_demux(request):
- get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS)
if request.method == 'GET':
- if getattr(request, 'user', None) is not None:
- return account_list(request)
- return authenticate(request)
+ return account_list(request)
else:
return method_not_allowed(request)
@csrf_exempt
def account_demux(request, v_account):
- get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS)
if request.method == 'HEAD':
return account_meta(request, v_account)
elif request.method == 'POST':
@csrf_exempt
def container_demux(request, v_account, v_container):
- get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS)
if request.method == 'HEAD':
return container_meta(request, v_account, v_container)
elif request.method == 'PUT':
@csrf_exempt
def object_demux(request, v_account, v_container, v_object):
# Helper to avoid placing the token in the URL when loading objects from a browser.
- token = None
- if request.method in ('HEAD', 'GET') and COOKIE_NAME in request.COOKIES:
- cookie_value = unquote(request.COOKIES.get('COOKIE_NAME', ''))
- if cookie_value and '|' in cookie_value:
- token = cookie_value.split('|', 1)[1]
- get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS, token)
if request.method == 'HEAD':
return object_meta(request, v_account, v_container, v_object)
elif request.method == 'GET':
# Normal Response Codes: 200, 204
# Error Response Codes: internalServerError (500),
# badRequest (400)
+ if getattr(request, 'user', None) is None:
+ return authenticate(request)
response = HttpResponse()
shared = False
if 'shared' in request.GET:
shared = True
+ public = False
+ if 'public' in request.GET:
+ public = True
try:
containers = request.backend.list_containers(request.user_uniq, v_account,
- marker, limit, shared, until)
+ marker, limit, shared, until, public)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
v_container)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
validate_modification_preconditions(request, meta)
v_container, policy, replace=False)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
except ValueError:
raise BadRequest('Invalid policy header')
v_container, 'pithos', meta, replace=False)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
return HttpResponse(status=ret)
v_container, policy, replace)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
except ValueError:
raise BadRequest('Invalid policy header')
v_container, 'pithos', meta, replace)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
content_length = -1
until)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
- except IndexError:
+ except ContainerNotEmpty:
raise Conflict('Container is not empty')
return HttpResponse(status=204)
v_container)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
validate_modification_preconditions(request, meta)
virtual = False
# Naming policy.
- if prefix and delimiter:
+ if prefix and delimiter and not prefix.endswith(delimiter):
prefix = prefix + delimiter
if not prefix:
prefix = ''
shared = False
if 'shared' in request.GET:
shared = True
+ public = False
+ if 'public' in request.GET:
+ public = True
if request.serialization == 'text':
try:
objects = request.backend.list_objects(request.user_uniq, v_account,
v_container, prefix, delimiter, marker,
- limit, virtual, 'pithos', keys, shared, until)
+ limit, virtual, 'pithos', keys, shared,
+ until, None, public)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
if len(objects) == 0:
response.status_code = 200
response.content = '\n'.join([x[0] for x in objects]) + '\n'
return response
-
+
try:
objects = request.backend.list_object_meta(request.user_uniq, v_account,
v_container, prefix, delimiter, marker,
- limit, virtual, 'pithos', keys, shared, until)
+ limit, virtual, 'pithos', keys, shared, until, None, public)
object_permissions = {}
object_public = {}
if until is None:
object_public[k[name_idx:]] = v
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
object_meta = []
public = None
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
- except IndexError:
+ except VersionNotExists:
raise ItemNotFound('Version does not exist')
update_manifest_meta(request, v_account, meta)
public = None
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
- except IndexError:
+ except VersionNotExists:
raise ItemNotFound('Version does not exist')
update_manifest_meta(request, v_account, meta)
raise Forbidden('Not allowed')
except ValueError:
raise BadRequest('Invalid X-Object-Manifest header')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
try:
hashmaps.append(h)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
- except IndexError:
+ except VersionNotExists:
raise ItemNotFound('Version does not exist')
else:
try:
hashmaps.append(h)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
- except IndexError:
+ except VersionNotExists:
raise ItemNotFound('Version does not exist')
# Reply with the hashmap.
copy_from = request.META.get('HTTP_X_COPY_FROM')
move_from = request.META.get('HTTP_X_MOVE_FROM')
if copy_from or move_from:
+ delimiter = request.GET.get('delimiter')
content_length = get_content_length(request) # Required by the API.
src_account = request.META.get('HTTP_X_SOURCE_ACCOUNT')
except ValueError:
raise BadRequest('Invalid X-Move-From header')
version_id = copy_or_move_object(request, src_account, src_container, src_name,
- v_account, v_container, v_object, move=True)
+ v_account, v_container, v_object, move=True, delimiter=delimiter)
else:
try:
src_container, src_name = split_container_object_string(copy_from)
except ValueError:
raise BadRequest('Invalid X-Copy-From header')
version_id = copy_or_move_object(request, src_account, src_container, src_name,
- v_account, v_container, v_object, move=False)
+ v_account, v_container, v_object, move=False, delimiter=delimiter)
response = HttpResponse(status=201)
response['X-Object-Version'] = version_id
return response
if request.META.get('HTTP_TRANSFER_ENCODING') != 'chunked':
content_length = get_content_length(request)
# Should be BadRequest, but API says otherwise.
- if not content_type:
+ if content_type is None:
raise LengthRequired('Missing Content-Type header')
if 'hashmap' in request.GET:
raise Forbidden('Not allowed')
except IndexError, e:
raise Conflict(simple_list_response(request, e.data))
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
except ValueError:
raise BadRequest('Invalid sharing header')
except QuotaError:
raise RequestEntityTooLarge('Quota exceeded')
- if not checksum:
+ if not checksum and UPDATE_MD5:
# Update the MD5 after the hashmap, as there may be missing hashes.
- checksum = hashmap_md5(request, hashmap, size)
+ checksum = hashmap_md5(request.backend, hashmap, size)
try:
- version_id = request.backend.update_object_checksum(request.user_uniq,
- v_account, v_container, v_object, version_id, checksum)
+ request.backend.update_object_checksum(request.user_uniq,
+ v_account, v_container, v_object, version_id, checksum)
except NotAllowedError:
raise Forbidden('Not allowed')
if public is not None:
v_container, v_object, public)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
response = HttpResponse(status=201)
file.hashmap, checksum, 'pithos', {}, True)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
except QuotaError:
raise RequestEntityTooLarge('Quota exceeded')
v_container, v_object, 'pithos', src_version)
except NotAllowedError:
raise Forbidden('Not allowed')
- except (NameError, IndexError):
+ except (ItemNotExists, VersionNotExists):
raise ItemNotFound('Container or object does not exist')
validate_matching_preconditions(request, meta)
+ delimiter = request.GET.get('delimiter')
+
version_id = copy_or_move_object(request, v_account, v_container, v_object,
- dest_account, dest_container, dest_name, move=False)
+ dest_account, dest_container, dest_name, move=False, delimiter=delimiter)
response = HttpResponse(status=201)
response['X-Object-Version'] = version_id
return response
v_container, v_object, 'pithos')
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container or object does not exist')
validate_matching_preconditions(request, meta)
+ delimiter = request.GET.get('delimiter')
+
version_id = copy_or_move_object(request, v_account, v_container, v_object,
- dest_account, dest_container, dest_name, move=True)
+ dest_account, dest_container, dest_name, move=True, delimiter=delimiter)
response = HttpResponse(status=201)
response['X-Object-Version'] = version_id
return response
v_container, v_object, 'pithos')
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
# Evaluate conditions.
v_account, v_container, v_object, permissions)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
except ValueError:
raise BadRequest('Invalid sharing header')
v_container, v_object, public)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
if meta or replace:
try:
v_account, v_container, v_object, 'pithos', meta, replace)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
response['X-Object-Version'] = version_id
v_account, v_container, v_object)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
offset, length, total = ranges
src_account, src_container, src_name, src_version)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Source object does not exist')
if length is None:
if dest_bytes is not None and dest_bytes < size:
size = dest_bytes
hashmap = hashmap[:(int((size - 1) / request.backend.block_size) + 1)]
- checksum = hashmap_md5(request, hashmap, size)
+ checksum = hashmap_md5(request.backend, hashmap, size) if UPDATE_MD5 else ''
try:
version_id = request.backend.update_object_hashmap(request.user_uniq,
v_account, v_container, v_object, size, prev_meta['type'],
hashmap, checksum, 'pithos', meta, replace, permissions)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Container does not exist')
except ValueError:
raise BadRequest('Invalid sharing header')
v_container, v_object, public)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
response = HttpResponse(status=204)
# badRequest (400)
until = get_int_parameter(request.GET.get('until'))
+ delimiter = request.GET.get('delimiter')
+
try:
request.backend.delete_object(request.user_uniq, v_account, v_container,
- v_object, until)
+ v_object, until, delimiter=delimiter)
except NotAllowedError:
raise Forbidden('Not allowed')
- except NameError:
+ except ItemNotExists:
raise ItemNotFound('Object does not exist')
return HttpResponse(status=204)