0

I'm trying to use Requests to upload a file to a form but I'm getting back an error from the Tomcat server saying:

The request sent by the client was syntactically incorrect.

After reading this answer I've managed to print the request that I'm making and when comparing it to the request made in the browser I've noticed that the request payload name is not aligned so I'm guessing this is my issue.

The Requests docs for POSTing multipart-encoded files shows that you can override the filename, content_type and headers explicitly:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}

This seems to work fine but as mentioned above, I also need to set the name as well as the filename and the content-type.

Digging around on the GitHub repo I found the _encode_files method in models.py which seems to allow for specifying the name:

rf = RequestField(name=k, data=fp.read(),
                  filename=fn, headers=fh)

But I can't seem to get this to work and in my application, as with the above example, I have filename specified before the reference to the file:

files = {'file': (filename, open(filePath, 'rb'), 'application/x-zip-compressed')}

What am I missing here?

Community
  • 1
  • 1
ydaetskcoR
  • 53,225
  • 8
  • 158
  • 177

1 Answers1

2

The name is set from the key in your files dictionary. Just alter that key to set the name field to the desired value:

>>> import requests
>>> files = {'foobar': ('foo.txt', 'foo\ncontents\n','text/plain')}
>>> req = requests.Request('POST', 'http://httpbin.org/post', files=files).prepare()
>>> print req.body
--49773910d9514216894b697cb70e9f21
Content-Disposition: form-data; name="foobar"; filename="foo.txt"
Content-Type: text/plain

foo
contents

--49773910d9514216894b697cb70e9f21--

Note the name="foobar" element of the per-part Content-Disposition header.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343