author: Sylvain Viollon
date: Mon Jul 29 15:35:11 2013 +0200
revision: 5:35e5fb68d74f in infrae.fileupload
branch:
details: https://hg.infrae.com/infrae.fileupload?cmd=changeset;node=35e5fb68d74f
modified: src/infrae/fileupload/upload.py
added:
removed:
log: Keep the errors on the file system too so you can poll them.
diffstat:
src/infrae/fileupload/upload.py | 48 +++++++++++++++++++++++++++-------------
1 files changed, 32 insertions(+), 16 deletions(-)
diffs (109 lines):
diff -r 22b326137fed -r 35e5fb68d74f src/infrae/fileupload/upload.py
--- a/src/infrae/fileupload/upload.py Thu Jul 25 18:26:25 2013 +0200
+++ b/src/infrae/fileupload/upload.py Mon Jul 29 15:35:11 2013 +0200
@@ -105,8 +105,6 @@
except:
done = 0
status['uploaded-length'] = done
- if done == status['request-length']:
- status['upload-finished'] = True
self._status = status
return status
@@ -160,6 +158,17 @@
self._done_descriptor = open_data(self._done, '0')
self._data_descriptor = open_data(self._data)
+ def metadata(self, finished=False, error=None):
+ status = self.get_status()
+ if finished:
+ status['upload-finished'] = True
+ if error:
+ status['upload-error'] = error
+ self._metadata_descriptor.seek(0)
+ self._metadata_descriptor.write(json.dumps(status))
+ self._metadata_descriptor.flush()
+ self._status = None
+
def progress(self):
total = 0
while True:
@@ -167,11 +176,10 @@
read = yield
except GeneratorExit:
# Reload and save metadata.
- status = json.dumps(self.get_status())
- self._metadata_descriptor.seek(0)
- self._metadata_descriptor.write(status)
+ self.metadata(finished=(total == self._length))
self._metadata_descriptor.close()
self._done_descriptor.close()
+ self._status = None
raise StopIteration
total += read
self._done_descriptor.seek(0)
@@ -253,14 +261,24 @@
def upload(self, request, identifier):
"""Handle upload of a file.
"""
+ upload = None
+
+ def fail(error):
+ if upload is None:
+ failed = self.manager.create_upload_bucket(
+ identifier, '', 'n/a', '0')
+ else:
+ failed = upload
+ failed.metadata(error=error)
+ return exc.HTTPServerError(error)
+
length = request.content_length
if self.max_size and int(length) > self.max_size:
- return exc.HTTPServerError('Upload is too large')
+ return fail('Upload is too large')
_, options = cgi.parse_header(request.headers['content-type'])
if 'boundary' not in options:
- return exc.HTTPServerError(
- 'Upload request is malformed (boundary missing)')
+ return fail('Upload request is malformed #1')
part_boundary = '--' + options['boundary'] + EOL
end_boundary = '--' + options['boundary'] + '--' + EOL
@@ -269,8 +287,7 @@
# Read the first marker
marker = input_stream.read()
if marker != part_boundary:
- return exc.HTTPServerError(
- 'Upload request is malformed (invalid construction)')
+ return fail('Upload request is malformed #2')
# Read the headers
headers = {}
@@ -283,9 +300,9 @@
# We should have now the payload
if ('content-disposition' not in headers or
'content-type' not in headers or
- headers['content-disposition'][0] != 'form-data'):
- return exc.HTTPServerError(
- 'Upload request is malformed (missing payload)')
+ headers['content-disposition'][0] != 'form-data' or
+ not headers['content-disposition'][1].get('filename')):
+ return fail('Upload request is malformed #3')
upload = self.manager.create_upload_bucket(
identifier,
@@ -303,11 +320,10 @@
line = input_stream.read()
if line == part_boundary:
# Multipart, we don't handle that
+ error = fail('Upload request is malformed #4')
output_stream.close()
track_progress.close()
- upload.clean()
- return exc.HTTPServerError(
- 'Upload request is malformed (two fields)')
+ return error
# We are done uploading
output_stream.close()
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.