from django.template.loader import render_to_string
from django.utils import simplejson as json
from django.utils.http import parse_etags
-from django.utils.encoding import smart_unicode, smart_str
+from django.utils.encoding import smart_str
from xml.dom import minidom
+from pithos.lib.filter import parse_filters
+
from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, Forbidden, ItemNotFound, Conflict,
LengthRequired, PreconditionFailed, RequestEntityTooLarge, RangeNotSatisfiable, UnprocessableEntity)
from pithos.api.util import (rename_meta_key, format_header_key, printable_header_dict, get_account_headers,
put_account_headers, get_container_headers, put_container_headers, get_object_headers, put_object_headers,
update_manifest_meta, update_sharing_meta, update_public_meta, 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,
+ get_int_parameter, get_content_length, get_content_range, socket_read_iterator, SaveToBackendHandler,
object_data_response, put_object_block, hashmap_hash, api_method, json_encode_decimal)
from pithos.backends.base import NotAllowedError, QuotaError
uri = uri[:uri.find('?')]
response['X-Auth-Token'] = x_auth_key
- response['X-Storage-Url'] = uri + (uri.endswith('/') and '' or '/') + x_auth_user
+ response['X-Storage-Url'] = uri + ('' if uri.endswith('/') else '/') + x_auth_user
return response
@api_method('GET', format_allowed=True)
account_meta = []
for x in accounts:
+ if x == request.user_uniq:
+ continue
try:
- meta = request.backend.get_account_meta(request.user_uniq, x)
+ meta = request.backend.get_account_meta(request.user_uniq, x, 'pithos')
groups = request.backend.get_account_groups(request.user_uniq, x)
except NotAllowedError:
raise Forbidden('Not allowed')
else:
rename_meta_key(meta, 'modified', 'last_modified')
rename_meta_key(meta, 'until_timestamp', 'x_account_until_timestamp')
- for k, v in groups.iteritems():
- meta['X-Container-Group-' + k] = ','.join(v)
+ m = dict([(k[15:], v) for k, v in meta.iteritems() if k.startswith('X-Account-Meta-')])
+ for k in m:
+ del(meta['X-Account-Meta-' + k])
+ if m:
+ meta['X-Account-Meta'] = printable_header_dict(m)
+ if groups:
+ meta['X-Account-Group'] = printable_header_dict(dict([(k, ','.join(v)) for k, v in groups.iteritems()]))
account_meta.append(printable_header_dict(meta))
if request.serialization == 'xml':
data = render_to_string('accounts.xml', {'accounts': account_meta})
until = get_int_parameter(request.GET.get('until'))
try:
- meta = request.backend.get_account_meta(request.user_uniq, v_account, until)
+ meta = request.backend.get_account_meta(request.user_uniq, v_account, 'pithos', until)
groups = request.backend.get_account_groups(request.user_uniq, v_account)
policy = request.backend.get_account_policy(request.user_uniq, v_account)
except NotAllowedError:
raise BadRequest('Invalid groups header')
if meta or replace:
try:
- request.backend.update_account_meta(request.user_uniq, v_account, meta,
- replace)
+ request.backend.update_account_meta(request.user_uniq, v_account,
+ 'pithos', meta, replace)
except NotAllowedError:
raise Forbidden('Not allowed')
return HttpResponse(status=202)
until = get_int_parameter(request.GET.get('until'))
try:
- meta = request.backend.get_account_meta(request.user_uniq, v_account, until)
+ meta = request.backend.get_account_meta(request.user_uniq, v_account, 'pithos', until)
groups = request.backend.get_account_groups(request.user_uniq, v_account)
policy = request.backend.get_account_policy(request.user_uniq, v_account)
except NotAllowedError:
for x in containers:
try:
meta = request.backend.get_container_meta(request.user_uniq, v_account,
- x, until)
+ x, 'pithos', until)
policy = request.backend.get_container_policy(request.user_uniq,
v_account, x)
except NotAllowedError:
else:
rename_meta_key(meta, 'modified', 'last_modified')
rename_meta_key(meta, 'until_timestamp', 'x_container_until_timestamp')
- for k, v in policy.iteritems():
- meta['X-Container-Policy-' + k] = v
+ m = dict([(k[17:], v) for k, v in meta.iteritems() if k.startswith('X-Container-Meta-')])
+ for k in m:
+ del(meta['X-Container-Meta-' + k])
+ if m:
+ meta['X-Container-Meta'] = printable_header_dict(m)
+ if policy:
+ meta['X-Container-Policy'] = printable_header_dict(dict([(k, v) for k, v in policy.iteritems()]))
container_meta.append(printable_header_dict(meta))
if request.serialization == 'xml':
data = render_to_string('containers.xml', {'account': v_account, 'containers': container_meta})
until = get_int_parameter(request.GET.get('until'))
try:
meta = request.backend.get_container_meta(request.user_uniq, v_account,
- v_container, until)
+ v_container, 'pithos', until)
meta['object_meta'] = request.backend.list_object_meta(request.user_uniq,
- v_account, v_container, until)
+ v_account, v_container, 'pithos', until)
policy = request.backend.get_container_policy(request.user_uniq, v_account,
v_container)
except NotAllowedError:
if meta:
try:
request.backend.update_container_meta(request.user_uniq, v_account,
- v_container, meta, replace=False)
+ v_container, 'pithos', meta, replace=False)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
if meta or replace:
try:
request.backend.update_container_meta(request.user_uniq, v_account,
- v_container, meta, replace)
+ v_container, 'pithos', meta, replace)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
until = get_int_parameter(request.GET.get('until'))
try:
meta = request.backend.get_container_meta(request.user_uniq, v_account,
- v_container, until)
+ v_container, 'pithos', until)
meta['object_meta'] = request.backend.list_object_meta(request.user_uniq,
- v_account, v_container, until)
+ v_account, v_container, 'pithos', until)
policy = request.backend.get_container_policy(request.user_uniq, v_account,
v_container)
except NotAllowedError:
keys = request.GET.get('meta')
if keys:
- keys = keys.split(',')
- l = [smart_str(x) for x in keys if x.strip() != '']
- keys = [format_header_key('X-Object-Meta-' + x.strip()) for x in l]
+ keys = [smart_str(x.strip()) for x in keys.split(',') if x.strip() != '']
+ included, excluded, opers = parse_filters(keys)
+ keys = []
+ keys += [format_header_key('X-Object-Meta-' + x) for x in included]
+ keys += [format_header_key('!X-Object-Meta-' + x) for x in excluded]
+ keys += ['%s%s%s' % (format_header_key('X-Object-Meta-' + k), o, v) for k, o, v in opers]
else:
keys = []
try:
objects = request.backend.list_objects(request.user_uniq, v_account,
v_container, prefix, delimiter, marker,
- limit, virtual, keys, shared, until)
+ limit, virtual, 'pithos', keys, shared, until)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
else:
try:
meta = request.backend.get_object_meta(request.user_uniq, v_account,
- v_container, x[0], x[1])
+ v_container, x[0], 'pithos', x[1])
if until is None:
permissions = request.backend.get_object_permissions(
request.user_uniq, v_account, v_container, x[0])
rename_meta_key(meta, 'modified_by', 'x_object_modified_by')
rename_meta_key(meta, 'version', 'x_object_version')
rename_meta_key(meta, 'version_timestamp', 'x_object_version_timestamp')
+ m = dict([(k[14:], v) for k, v in meta.iteritems() if k.startswith('X-Object-Meta-')])
+ for k in m:
+ del(meta['X-Object-Meta-' + k])
+ if m:
+ meta['X-Object-Meta'] = printable_header_dict(m)
update_sharing_meta(request, permissions, v_account, v_container, x[0], meta)
update_public_meta(public, meta)
object_meta.append(printable_header_dict(meta))
version = request.GET.get('version')
try:
meta = request.backend.get_object_meta(request.user_uniq, v_account,
- v_container, v_object, version)
+ v_container, v_object, 'pithos', version)
if version is None:
permissions = request.backend.get_object_permissions(request.user_uniq,
v_account, v_container, v_object)
try:
meta = request.backend.get_object_meta(request.user_uniq, v_account,
- v_container, v_object, version)
+ v_container, v_object, 'pithos', version)
if version is None:
permissions = request.backend.get_object_permissions(request.user_uniq,
v_account, v_container, v_object)
if request.META.get('HTTP_IF_MATCH') or request.META.get('HTTP_IF_NONE_MATCH'):
try:
meta = request.backend.get_object_meta(request.user_uniq, v_account,
- v_container, v_object)
+ v_container, v_object, 'pithos')
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
meta = {}
validate_matching_preconditions(request, meta)
- copy_from = smart_unicode(request.META.get('HTTP_X_COPY_FROM'), strings_only=True)
- move_from = smart_unicode(request.META.get('HTTP_X_MOVE_FROM'), strings_only=True)
+ copy_from = request.META.get('HTTP_X_COPY_FROM')
+ move_from = request.META.get('HTTP_X_MOVE_FROM')
if copy_from or move_from:
content_length = get_content_length(request) # Required by the API.
- src_account = smart_unicode(request.META.get('HTTP_X_SOURCE_ACCOUNT'), strings_only=True)
+ src_account = request.META.get('HTTP_X_SOURCE_ACCOUNT')
if not src_account:
src_account = request.user_uniq
if move_from:
try:
version_id = request.backend.update_object_hashmap(request.user_uniq,
- v_account, v_container, v_object, size, hashmap, meta,
- True, permissions)
+ v_account, v_container, v_object, size, hashmap,
+ 'pithos', meta, True, permissions)
except NotAllowedError:
raise Forbidden('Not allowed')
except IndexError, e:
# forbidden (403),
# badRequest (400)
+ request.upload_handlers = [SaveToBackendHandler(request)]
if not request.FILES.has_key('X-Object-Data'):
raise BadRequest('Missing X-Object-Data field')
file = request.FILES['X-Object-Data']
meta = {}
meta['Content-Type'] = file.content_type
-
- md5 = hashlib.md5()
- size = 0
- hashmap = []
- for data in file.chunks(request.backend.block_size):
- size += len(data)
- hashmap.append(request.backend.put_block(data))
- md5.update(data)
-
- meta['ETag'] = md5.hexdigest().lower()
+ meta['ETag'] = file.etag
try:
version_id = request.backend.update_object_hashmap(request.user_uniq,
- v_account, v_container, v_object, size, hashmap, meta, True)
+ v_account, v_container, v_object, file.size, file.hashmap,
+ 'pithos', meta, True)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
# forbidden (403),
# badRequest (400)
- dest_account = smart_unicode(request.META.get('HTTP_DESTINATION_ACCOUNT'), strings_only=True)
+ dest_account = request.META.get('HTTP_DESTINATION_ACCOUNT')
if not dest_account:
dest_account = request.user_uniq
- dest_path = smart_unicode(request.META.get('HTTP_DESTINATION'), strings_only=True)
+ dest_path = request.META.get('HTTP_DESTINATION')
if not dest_path:
raise BadRequest('Missing Destination header')
try:
src_version = request.META.get('HTTP_X_SOURCE_VERSION')
try:
meta = request.backend.get_object_meta(request.user_uniq, v_account,
- v_container, v_object, src_version)
+ v_container, v_object, 'pithos', src_version)
except NotAllowedError:
raise Forbidden('Not allowed')
except (NameError, IndexError):
# forbidden (403),
# badRequest (400)
- dest_account = smart_unicode(request.META.get('HTTP_DESTINATION_ACCOUNT'), strings_only=True)
+ dest_account = request.META.get('HTTP_DESTINATION_ACCOUNT')
if not dest_account:
dest_account = request.user_uniq
- dest_path = smart_unicode(request.META.get('HTTP_DESTINATION'), strings_only=True)
+ dest_path = request.META.get('HTTP_DESTINATION')
if not dest_path:
raise BadRequest('Missing Destination header')
try:
if request.META.get('HTTP_IF_MATCH') or request.META.get('HTTP_IF_NONE_MATCH'):
try:
meta = request.backend.get_object_meta(request.user_uniq, v_account,
- v_container, v_object)
+ v_container, v_object, 'pithos')
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
try:
prev_meta = request.backend.get_object_meta(request.user_uniq, v_account,
- v_container, v_object)
+ v_container, v_object, 'pithos')
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
if meta or replace:
try:
version_id = request.backend.update_object_meta(request.user_uniq,
- v_account, v_container, v_object, meta, replace)
+ v_account, v_container, v_object, 'pithos', meta, replace)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
elif offset > size:
raise RangeNotSatisfiable('Supplied offset is beyond object limits')
if src_object:
- src_account = smart_unicode(request.META.get('HTTP_X_SOURCE_ACCOUNT'), strings_only=True)
+ src_account = request.META.get('HTTP_X_SOURCE_ACCOUNT')
if not src_account:
src_account = request.user_uniq
src_container, src_name = split_container_object_string(src_object)
- src_container = smart_unicode(src_container, strings_only=True)
- src_name = smart_unicode(src_name, strings_only=True)
src_version = request.META.get('HTTP_X_SOURCE_VERSION')
try:
src_size, src_hashmap = request.backend.get_object_hashmap(request.user_uniq,
meta.update({'ETag': hashmap_hash(request, hashmap)}) # Update ETag.
try:
version_id = request.backend.update_object_hashmap(request.user_uniq,
- v_account, v_container, v_object, size, hashmap, meta,
- replace, permissions)
+ v_account, v_container, v_object, size, hashmap,
+ 'pithos', meta, replace, permissions)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError: