Skip to content

Commit

Permalink
Fix handling of multi-value file fields
Browse files Browse the repository at this point in the history
Some clients (e.g. Swagger), rather than specifying `file1`, `file2`, etc... will
specify multiple values for `file` when uploading multiple files.
This code change will handle lists of values for individual fields.
  • Loading branch information
ehlertjd committed Feb 23, 2018
1 parent 58866be commit 1a21390
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
20 changes: 16 additions & 4 deletions api/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,13 @@ def process_upload(request, strategy, container_type=None, id_=None, origin=None
# Here, we accept any

# Non-file form fields may have an empty string as filename, check for 'falsy' values
file_fields = [x for x in form if form[x].filename]
file_fields = extract_file_fields(form)
# TODO: Change schemas to enabled targeted uploads of more than one file.
# Ref docs from placer.TargetedPlacer for details.
if strategy == Strategy.targeted and len(file_fields) > 1:
raise FileFormException("Targeted uploads can only send one file")



for field in file_fields:
field = form[field]
# Augment the cgi.FieldStorage with a variety of custom fields.
# Not the best practice. Open to improvements.
# These are presumbed to be required by every function later called with field as a parameter.
Expand Down Expand Up @@ -270,3 +267,18 @@ def clean_packfile_tokens(self):
'directories': cleaned,
}
}

def extract_file_fields(form):
"""Returns a list of file fields in the form, handling multiple values"""
result = []
for fieldname in form:
field = form[fieldname]
if isinstance(field, list):
for field_entry in field:
if field_entry.filename:
result.append(field_entry)

elif field.filename:
result.append(field)

return result
7 changes: 6 additions & 1 deletion tests/integration_tests/python/test_uploads.py
Original file line number Diff line number Diff line change
Expand Up @@ -1197,9 +1197,14 @@ def test_packfile_upload(data_builder, file_form, as_admin, as_root, api_db):
assert r.ok
token = r.json()['token']

files = [
('file', file_form('two.csv')['file']) ,
('file', file_form('three.csv')['file'])
]

# upload to packfile
r = as_admin.post('/projects/' + project + '/packfile',
params={'token': token}, files=file_form('two.csv'))
params={'token': token}, files=files)
assert r.ok

# expire upload token
Expand Down

0 comments on commit 1a21390

Please sign in to comment.