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
# 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, meta, True)
except NotAllowedError:
raise Forbidden('Not allowed')
except NameError:
from django.utils import simplejson as json
from django.utils.http import http_date, parse_etags
from django.utils.encoding import smart_str
+from django.core.files.uploadhandler import FileUploadHandler
+from django.core.files.uploadedfile import UploadedFile
from pithos.api.compat import parse_http_date_safe, parse_http_date
from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, Forbidden, ItemNotFound,
length -= len(data)
yield data
+class SaveToBackendHandler(FileUploadHandler):
+ """Handle a file from an HTML form the django way."""
+
+ def __init__(self, request=None):
+ super(SaveToBackendHandler, self).__init__(request)
+ self.backend = request.backend
+
+ def put_data(self, length):
+ if len(self.data) >= length:
+ block = self.data[:length]
+ self.file.hashmap.append(self.backend.put_block(block))
+ self.md5.update(block)
+ self.data = self.data[length:]
+
+ def new_file(self, field_name, file_name, content_type, content_length, charset=None):
+ self.md5 = hashlib.md5()
+ self.data = ''
+ self.file = UploadedFile(name=file_name, content_type=content_type, charset=charset)
+ self.file.size = 0
+ self.file.hashmap = []
+
+ def receive_data_chunk(self, raw_data, start):
+ self.data += raw_data
+ self.file.size += len(raw_data)
+ self.put_data(self.request.backend.block_size)
+ return None
+
+ def file_complete(self, file_size):
+ l = len(self.data)
+ if l > 0:
+ self.put_data(l)
+ self.file.etag = self.md5.hexdigest().lower()
+ return self.file
+
class ObjectWrapper(object):
"""Return the object's data block-per-block in each iteration.