Commit f126d0bf authored by Kirill Smelkov's avatar Kirill Smelkov

BigFile: Factor out code to append data chunk to ._appendData()

So that data could be appended on server code via direct calls too.

NOTE previously ._read_data() accepted data=None argument and callers
were either providing it with current .data to append or None to forget
old content and just add new fresh one.

We could drop data=None from _read_data() signature, but leave it as is
for compatibility with outside code (e.g. zope's
OFS.Image.File.manage_upload() calls ._read_data(file) without any data
argument and in that case file content should be recreated, not
appended).

On the other hand we rework our code in .PUT() so for both "new content"
and "append range" in the end it always does "append" operation. For it
to work this way "new content" simply truncates the file before
proceeding to "append".
Reviewed-by: Romain Courteaud's avatarRomain Courteaud <romain@nexedi.com>
parent f54e3fa6
...@@ -344,7 +344,8 @@ class BigFile(File): ...@@ -344,7 +344,8 @@ class BigFile(File):
content_range = REQUEST.get_header('Content-Range', None) content_range = REQUEST.get_header('Content-Range', None)
if content_range is None: if content_range is None:
btree = None # truncate the file
self._baseSetData(None)
else: else:
current_size = int(self.getSize()) current_size = int(self.getSize())
query_range = re.compile('bytes \*/\*') query_range = re.compile('bytes \*/\*')
...@@ -380,24 +381,29 @@ class BigFile(File): ...@@ -380,24 +381,29 @@ class BigFile(File):
RESPONSE.setStatus(400) RESPONSE.setStatus(400)
return RESPONSE return RESPONSE
else:
btree = self._baseGetData()
else: else:
RESPONSE.setHeader('X-Explanation', 'Can not parse range') RESPONSE.setHeader('X-Explanation', 'Can not parse range')
RESPONSE.setStatus(400) # Partial content RESPONSE.setStatus(400) # Partial content
return RESPONSE return RESPONSE
data, size = self._read_data(file, data=btree) self._appendData(file, content_type=type)
content_type=self._get_content_type(file, data, self.__name__,
type or self.content_type)
self.update_data(data, content_type, size)
RESPONSE.setStatus(204) RESPONSE.setStatus(204)
return RESPONSE return RESPONSE
def _appendData(self, data_chunk, content_type=None):
"""append data chunk to the end of the file
NOTE if content_type is specified, it will change content_type for the
whole file.
"""
data, size = self._read_data(data_chunk, data=self._baseGetData())
content_type=self._get_content_type(data_chunk, data, self.__name__,
content_type or self.content_type)
self.update_data(data, content_type, size)
# CMFFile also brings the IContentishInterface on CMF 2.2, remove it. # CMFFile also brings the IContentishInterface on CMF 2.2, remove it.
removeIContentishInterface(BigFile) removeIContentishInterface(BigFile)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment