Set "Content-Disposition" header in `file` multipart failed
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 54.3k
- Forks
- 10.4k
- Avg merge
- 16h 43m
- Merged PRs (30d)
- 3
Description
Summary.
- Source: requests/models.py
class RequestEncodingMixin(object):
...
def _encode_files(files, data):
...
rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
rf.make_multipart(content_type=ft)
Variable fh holdes the 4th tuple item passed from
files = {'settings': (filename, io.BytesIO(b'some,data,to,send\nanother,row,to,send\n'),
'app/xml', {'Content-Disposition':'attachment'} )}
The rf.header dict get set passing headers=fh with 'Content-Disposition':....
Calling rf.make_multipart(content_type=ft), at the next line, only passing the 3trd tuple item.
The method make_multipart - urllib3/fields.py is defined as
def make_multipart(
self, content_disposition=None, content_type=None, content_location=None
):
self.headers["Content-Disposition"] = content_disposition or u"form-data"
...
which replaces, as content_disposition is None, the allready set self.headers["Content-Disposition"] with the default u"form-data".
Expected Result
--e96a4935b8d5b2355f1da3070faa4b28
Content-Disposition: attachment; name="settings"; filename="settings.xml"
Content-Type: app/xml
some,data,to,send
another,row,to,send
--e96a4935b8d5b2355f1da3070faa4b28--
Actual Result
--e96a4935b8d5b2355f1da3070faa4b28
Content-Disposition: form-data; name="settings"; filename="settings.xml"
Content-Type: app/xml
some,data,to,send
another,row,to,send
--e96a4935b8d5b2355f1da3070faa4b28--
Reproduction Steps
import requests
url = 'http://127.0.0.1:8080'
filename = "settings.xml"
files = {'settings': (filename, io.BytesIO(b'some,data,to,send\nanother,row,to,send\n'),
'app/xml', {'Content-Disposition':'attachment'} )}
r = requests.post(url, files=files)
System Information
Tested with Python: 3.5 - urllib3: 1.23 - requests: 2.19.1
Possible Solution
Pass all three parameter explicit to .make_multipart(..., e.g.
rf.make_multipart(content_disposition=fh.get('Content-Disposition'),
content_type=ft,
content_location=fh.get('Content-Location')
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in requests/models.py at RequestEncodingMixin._encode_files and compare how urllib3/fields.py handles RequestField.make_multipart. Reproduce the supplied files payload, then verify that the resulting multipart request preserves the requested Content-Disposition header and still includes the content type.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100