diff -r eb26255e11f1 Lib/http/client.py --- a/Lib/http/client.py Wed Jan 28 11:06:04 2015 +0200 +++ b/Lib/http/client.py Thu Jan 29 17:11:42 2015 -0800 @@ -1028,20 +1028,21 @@ def _set_content_length(self, body): # Set the content-length based on the body. - thelen = None - try: - thelen = str(len(body)) - except TypeError as te: - # If this is a file-like object, try to - # fstat its file descriptor + if isinstance(body, list) or isinstance(body, tuple): + size = sum(len(line) for line in body) + else: try: - thelen = str(os.fstat(body.fileno()).st_size) - except (AttributeError, OSError): - # Don't send a length if this failed - if self.debuglevel > 0: print("Cannot stat!!") + size = len(body) + except TypeError: + try: + size = os.fstat(body.fileno()).st_size + except (AttributeError, OSError): + if self.debuglevel > 0: + print("Cannot stat!!") + size = None - if thelen is not None: - self.putheader('Content-Length', thelen) + if size is not None: + self.putheader('Content-Length', size) def _send_request(self, method, url, body, headers): # Honor explicitly requested Host: and Accept-Encoding: headers. diff -r eb26255e11f1 Lib/test/test_httplib.py --- a/Lib/test/test_httplib.py Wed Jan 28 11:06:04 2015 +0200 +++ b/Lib/test/test_httplib.py Thu Jan 29 17:11:42 2015 -0800 @@ -53,6 +53,8 @@ self.port = port def sendall(self, data): + if isinstance(data, str): + data = data.encode('ascii') self.sendall_calls += 1 self.data += data @@ -1161,7 +1163,6 @@ def setUp(self): self.conn = client.HTTPConnection('example.com') self.conn.sock = self.sock = FakeSocket("") - self.conn.sock = self.sock def get_headers_and_fp(self): f = io.BytesIO(self.sock.data) @@ -1226,6 +1227,24 @@ self.assertEqual("5", message.get("content-length")) self.assertEqual(b'body\xc1', f.read()) + def test_list_body(self): + cases = ( + ([b'foo', b'bar'], b'foobar'), + ([b'foo', 'bar'], b'foobar'), + ((b'foo', b'bar'), b'foobar'), + ((b'foo', 'bar'), b'foobar'), + ) + for body, expected in cases: + self.conn = client.HTTPConnection('example.com') + self.conn.sock = self.sock = FakeSocket('') + + self.conn.request('PUT', '/url', body) + msg, f = self.get_headers_and_fp() + self.assertEqual('text/plain', msg.get_content_type()) + self.assertIsNone(msg.get_charset()) + self.assertEqual(str(len(expected)), msg.get('content-length')) + self.assertEqual(expected, f.read()) + class HTTPResponseTest(TestCase):