Binary POST data stopped working in requests 0.10.1

The following method for POSTing binary data worked with requests 0.10.0 on Python 2.7.1 (Ubuntu 11.04 x64) :

```
bodybytes = '\xDE\xAD\xBE\xEF'
r = requests.post(url, data=bodybytes)
```

With requests 0.10.1 on the same environment, it no longer works correctly. Specifically, the body data does not get appended correctly and passed onto the server.

A full example (including sample flask server) that works with 0.10.0 but not 0.10.1:

```
import flask, multiprocessing, requests

app = flask.Flask(__name__)

@app.route("/testpost", methods=['POST'])
def echopost():
    return str(len(flask.request.data))

web_process = multiprocessing.Process(target=lambda: app.run(host='127.0.0.1', port=5000)) 
web_process.start()
try:
    bodybytes = '\xDE\xAD\xBE\xEF'
    print('Original body length = '+str(len(bodybytes)))
    r = requests.post('http://127.0.0.1:5000/testpost', data=bodybytes )
    print('POST body length = '+str(r.content))
    assert(int(r.content) == len(bodybytes))
finally:
    web_process.terminate()
```

Any idea what may have caused this change in behavior?


Not sure if this is related but I also got problem uploading binary data with 0.10.1 which work just fine in 0.9.0. I have the following code which upload photo to Flickr API:-

<pre>
def upload_photo(self, inputfile, **kwargs):
        parameters = kwargs
        req = self.sign_request(UPLOAD_URL, parameters, method='POST')
        headers = req.to_header()

        files = {
            'photo': open(inputfile, 'rb'),
        }
        resp = requests.post(UPLOAD_URL, data=kwargs, files=files, headers=headers)

        xml = ET.XML(resp.content)
        if xml.attrib['stat'] == 'ok':
            class Photo(object): pass
            photo = Photo()
            photo.id = xml[0].text
            return photo
</pre>


Now when running using 0.10.1, got the following traceback:-

<pre>
Traceback (most recent call last):
  File "__init__.py", line 291, in <module>
    print flickrapi.upload_photo('/home/kamal/Pictures/Image2442.jpg')
  File "__init__.py", line 155, in upload_photo
    resp = requests.post(UPLOAD_URL, data=kwargs, files=files, headers=headers)
  File "/home/kamal/python/env/pyflickr/lib/python2.6/site-packages/requests/api.py", line 84, in post
    return request('post', url, data=data, **kwargs)
  File "/home/kamal/python/env/pyflickr/lib/python2.6/site-packages/requests/api.py", line 39, in request
    return s.request(method=method, url=url, **kwargs)
  File "/home/kamal/python/env/pyflickr/lib/python2.6/site-packages/requests/sessions.py", line 159, in request
    headers[k] = header_expand(v)
  File "/home/kamal/python/env/pyflickr/lib/python2.6/site-packages/requests/utils.py", line 152, in header_expand
    for i, (value, params) in enumerate(headers):
ValueError: need more than 1 value to unpack
</pre>


I have problem with binary data too. Everything works fine in 0.9.3.

requests own test suite fails with 4 errors (related to unicode data, and it raises the same exception that I am getting). I have reproduced the problem with Python 2.7.1 (Mac OS X Lion) and Python 2.7.2 (home-built on Debian Squeeze).

This issue seems to be triggering a Python 2.7 / httplib bug where the URL is getting (somehow) passed in as a Unicode string into httplib:
http://bugs.python.org/issue11898

I tried to bisect the error to find the commit that introduced the regression, starting from 0.9.3-ish to latest develop, but I could not get any good results since other unrelated errors cropped up all along the way.

This is the most simple program to demonstrate the bug:

```
# -*- coding: utf-8 -*-
import requests
utf8_string = (u'Smörgås').encode('utf-8')
requests.post('http://www.google.com/', data=utf8_string)
```

And the output:

```
[requests_dev] [develop] ~/code/requests $ python simpletest.py
Traceback (most recent call last):
  File "simpletest.py", line 4, in <module>
    requests.post('http://www.google.com/', data=utf8_string)
  File "/Users/andreas/code/requests/requests/api.py", line 84, in post
    return request('post', url, data=data, **kwargs)
  File "/Users/andreas/code/requests/requests/api.py", line 39, in request
    return s.request(method=method, url=url, **kwargs)
  File "/Users/andreas/code/requests/requests/sessions.py", line 200, in request
    r.send(prefetch=prefetch)
  File "/Users/andreas/code/requests/requests/models.py", line 527, in send
    timeout=self.timeout,
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 370, in urlopen
    body=body, headers=headers)
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 246, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 941, in request
    self._send_request(method, url, body, headers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 975, in _send_request
    self.endheaders(body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 937, in endheaders
    self._send_output(message_body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 795, in _send_output
    msg += message_body
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128)
```

This is the test suite output:

```
[requests_dev] [develop] ~/code/requests $ PORT=80 HTTPBIN_URL="http://httpbin.org/" python test_requests.py
............EEE.......................E..........
======================================================================
ERROR: test_POSTBIN_GET_POST_FILES (__main__.RequestsTestSuite)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_requests.py", line 220, in test_POSTBIN_GET_POST_FILES
    post2 = post(url, files={'some': open('test_requests.py')})
  File "/Users/andreas/code/requests/requests/api.py", line 84, in post
    return request('post', url, data=data, **kwargs)
  File "/Users/andreas/code/requests/requests/api.py", line 39, in request
    return s.request(method=method, url=url, **kwargs)
  File "/Users/andreas/code/requests/requests/sessions.py", line 200, in request
    r.send(prefetch=prefetch)
  File "/Users/andreas/code/requests/requests/models.py", line 527, in send
    timeout=self.timeout,
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 370, in urlopen
    body=body, headers=headers)
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 246, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 941, in request
    self._send_request(method, url, body, headers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 975, in _send_request
    self.endheaders(body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 937, in endheaders
    self._send_output(message_body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 795, in _send_output
    msg += message_body
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 7959: ordinal not in range(128)

======================================================================
ERROR: test_POSTBIN_GET_POST_FILES_WITH_HEADERS (__main__.RequestsTestSuite)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_requests.py", line 247, in test_POSTBIN_GET_POST_FILES_WITH_HEADERS
    headers = {'User-Agent': 'requests-tests'})
  File "/Users/andreas/code/requests/requests/api.py", line 84, in post
    return request('post', url, data=data, **kwargs)
  File "/Users/andreas/code/requests/requests/api.py", line 39, in request
    return s.request(method=method, url=url, **kwargs)
  File "/Users/andreas/code/requests/requests/sessions.py", line 200, in request
    r.send(prefetch=prefetch)
  File "/Users/andreas/code/requests/requests/models.py", line 527, in send
    timeout=self.timeout,
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 370, in urlopen
    body=body, headers=headers)
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 246, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 941, in request
    self._send_request(method, url, body, headers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 975, in _send_request
    self.endheaders(body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 937, in endheaders
    self._send_output(message_body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 795, in _send_output
    msg += message_body
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 7959: ordinal not in range(128)

======================================================================
ERROR: test_POSTBIN_GET_POST_FILES_WITH_PARAMS (__main__.RequestsTestSuite)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_requests.py", line 234, in test_POSTBIN_GET_POST_FILES_WITH_PARAMS
    data={'some': 'data'})
  File "/Users/andreas/code/requests/requests/api.py", line 84, in post
    return request('post', url, data=data, **kwargs)
  File "/Users/andreas/code/requests/requests/api.py", line 39, in request
    return s.request(method=method, url=url, **kwargs)
  File "/Users/andreas/code/requests/requests/sessions.py", line 200, in request
    r.send(prefetch=prefetch)
  File "/Users/andreas/code/requests/requests/models.py", line 527, in send
    timeout=self.timeout,
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 370, in urlopen
    body=body, headers=headers)
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 246, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 941, in request
    self._send_request(method, url, body, headers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 975, in _send_request
    self.endheaders(body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 937, in endheaders
    self._send_output(message_body)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 795, in _send_output
    msg += message_body
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 7959: ordinal not in range(128)

======================================================================
ERROR: test_session_with_unicode_headers (__main__.RequestsTestSuite)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_requests.py", line 117, in test_session_with_unicode_headers
    requests.get(url=httpbin('get'), headers=heads)
  File "/Users/andreas/code/requests/requests/api.py", line 51, in get
    return request('get', url, **kwargs)
  File "/Users/andreas/code/requests/requests/api.py", line 39, in request
    return s.request(method=method, url=url, **kwargs)
  File "/Users/andreas/code/requests/requests/sessions.py", line 200, in request
    r.send(prefetch=prefetch)
  File "/Users/andreas/code/requests/requests/models.py", line 527, in send
    timeout=self.timeout,
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 370, in urlopen
    body=body, headers=headers)
  File "/Users/andreas/code/requests/requests/packages/urllib3/connectionpool.py", line 246, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 941, in request
    self._send_request(method, url, body, headers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 974, in _send_request
    self.putheader(hdr, value)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 921, in putheader
    hdr = '%s: %s' % (header, '\r\n\t'.join([str(v) for v in values]))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

----------------------------------------------------------------------
Ran 49 tests in 21.474s

FAILED (errors=4)
```


Fixed!


I think that I'm still experiencing the same issue:

``` python
>>> files = {"xml": open("photos.xml", "r"), "image": open("Vienna-Orchestra.jpg", "rb")}
>>> r = requests.post(url, files=files, auth=('***', '***'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build/bdist.linux-i686/egg/requests/api.py", line 84, in post
  File "build/bdist.linux-i686/egg/requests/api.py", line 39, in request
  File "build/bdist.linux-i686/egg/requests/sessions.py", line 200, in request
  File "build/bdist.linux-i686/egg/requests/models.py", line 535, in send
  File "build/bdist.linux-i686/egg/requests/packages/urllib3/connectionpool.py", line 370, in urlopen
  File "build/bdist.linux-i686/egg/requests/packages/urllib3/connectionpool.py", line 246, in _make_request
  File "/usr/local/lib/python2.7/httplib.py", line 946, in request
    self._send_request(method, url, body, headers)
  File "/usr/local/lib/python2.7/httplib.py", line 987, in _send_request
    self.endheaders(body)
  File "/usr/local/lib/python2.7/httplib.py", line 940, in endheaders
    self._send_output(message_body)
  File "/usr/local/lib/python2.7/httplib.py", line 801, in _send_output
    msg += message_body
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 484: ordinal not in range(128)
>>> print requests.__version__
0.10.2
```

Nevertheless, this code is working:

``` python
bodybytes = '\xDE\xAD\xBE\xEF'
r = requests.post(url, data=bodybytes)
```


Today, I was struggling with UnicodeDecodeError at line 801 of /httplib.py in _send_output. Worked fine on Mac (2.7.2). Not working on Windows (2.7 r27 2010-07-04).  Thought that looked a bit old. Installed latest Python version (2.7.3 2012-04-10) and the problem has disappeared. (Shame I wasted about 4 hours trying to fix it!)