diff --git a/requests/models.py b/requests/models.py index 3a0818dd..71cb6adf 100644 --- a/requests/models.py +++ b/requests/models.py @@ -90,7 +90,7 @@ class Request(object): #: HTTP Method to use. self.method = method - #: Dictionary or byte of request body data to attach to the + #: Dictionary, bytes or file stream of request body data to attach to the #: :class:`Request `. self.data = None @@ -323,6 +323,8 @@ class Request(object): return data if isinstance(data, str): return data + elif hasattr(data, 'read'): + return data elif hasattr(data, '__iter__'): try: dict(data) @@ -507,7 +509,7 @@ class Request(object): if self.data: body = self._encode_params(self.data) - if isinstance(self.data, str): + if isinstance(self.data, str) or hasattr(self.data, 'read'): content_type = None else: content_type = 'application/x-www-form-urlencoded' diff --git a/tests/test_requests.py b/tests/test_requests.py index de34cfac..817fd635 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -12,6 +12,7 @@ import json import os import unittest import pickle +import tempfile import requests from requests.compat import str, StringIO @@ -463,6 +464,26 @@ class RequestsTestSuite(TestSetup, TestBaseMixin, unittest.TestCase): assert rbody.get('form') in (None, {}) self.assertEqual(rbody.get('data'), 'fooaowpeuf') + def test_file_post_data(self): + + filecontent = "fooaowpeufbarasjhf" + testfile = tempfile.NamedTemporaryFile() + testfile.write(filecontent) + testfile.flush() + + for service in SERVICES: + + r = post(service('post'), data=open(testfile.name, "rb"), + headers={"content-type": "application/octet-stream"}) + + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers['content-type'], 'application/json') + self.assertEqual(r.url, service('post')) + + rbody = json.loads(r.text) + assert rbody.get('form') in (None, {}) + self.assertEqual(rbody.get('data'), filecontent) + def test_urlencoded_post_querystring(self): for service in SERVICES: