Julius
Julius

Reputation: 102

HTTP-Post with Requests fails: BadStatusLine

I got a problem with the following code. While trying to upload a file to the API using a POST-Request I get an error saying

File "upload.py", line 44, in <module>
    so.uploadData("./test.txt")
  File "upload.py", line 37, in uploadData
    req = requests.post("http://"+server, data=payload, headers=headers)
  File "/Library/Python/2.7/site-packages/requests/api.py", line 109, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/Library/Python/2.7/site-packages/requests/api.py", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File "/Library/Python/2.7/site-packages/requests/sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "/Library/Python/2.7/site-packages/requests/sessions.py", line 576, in send
    r = adapter.send(request, **kwargs)
  File "/Library/Python/2.7/site-packages/requests/adapters.py", line 412, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("''",))

My Code looks like this:

filedata= open(path, 'r')
payload = {'name': self.username, 'file':filedata}
headers = {
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36',
  'content-type': "multipart/form-data"}
req = requests.post("http://"+server, data=payload, headers=headers)

Does anyone have a solution for this problem? Best regards

Upvotes: 0

Views: 1769

Answers (1)

mhawke
mhawke

Reputation: 87074

Your code is not building a valid multipart/form-data POST request - it is building a application/x-www-form-urlencoded. Overriding the Content-type header does not change the way that the data is posted. The server sees an invalid request and drops the connection, which causes the error that you see in your client.

The easiest way to POST multipart/form-data with requests is to use the files parameter:

with open(path, 'rb') as filedata:
    payload = {'name': self.username}
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36'}
    req = requests.post(url, data=payload, headers=headers, files={'file': filedata})

This way requests will construct a valid multipart/form-data POST request.

The other way to do it, if you did not specifically require that the request use multipart/form-data is not to override the Content-type header:

with open(path, 'rb') as filedata:
    payload = {'name': self.username, 'file': filedata}
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36'}
    req = requests.post(url, data=payload, headers=headers)

Upvotes: 2

Related Questions