inclusion of timeout parameter on PUT causes error 14, 'Bad address'

Here's my minimal reproducing script:

``` python
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
#!/usr/bin/env python
import requests

url = 'https://prod-vision-analysis.s3.amazonaws.com/3ad6c771-52aa-4a1a-b2b6-6cdb17068321-40-real?Signature=khZjzyCjahKuK7z0QFrLhdIP6iE%3D&Expires=1438388766&AWSAccessKeyId=AKIAJEDT3K6WCNEGLKTA'

data = 190079 # works
data = 190080 # does not
image = b'1' * data
requests.put(url, data=image[:data], headers={'Content-Type': 'image/png'}, timeout=60, verify=False)
```

Executing that script, provided my signed S3 URL doesn't expire, will cause the following stack trace on my mac:

```
/usr/local/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
Traceback (most recent call last):
  File "./test-upload.py", line 9, in <module>
    requests.put(url, data=image[:data], headers={'Content-Type': 'image/png'}, timeout=60, verify=False)
  File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 122, in put
    return request('put', url, data=data, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/api.py", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 415, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', error(14, 'Bad address'))
```

If I change the script to use 190079 rather than 190080 for the data length the request goes through just fine.
If I change the script to not have a timeout the request goes through just fine
If I change the script to set the timeout to be any other value, anything at all, it will still fail. It just has to be non-zero and non-None and long enough that the request can reasonably go through


So I just ran your script as is and I get a 403, not a ConnectionError. So I guess authentication needs to succeed before this behaviour can be confirmed.


Yeah, sorry, as mentioned it's a signed URL with a timeout. I'll generate a custom URL for this script that times out in like a year and repost


Okay, I created a new URL that has a one-year timeout, which should work. Interestingly I had to bump the payload by one to reproduce. Here's the new minimally reproducing script:

``` python
#!/usr/bin/env python
import requests

url = 'https://dev-vision-analysis.s3.amazonaws.com:443/c61888ab-58ea-467f-ab8e-201592b075b9-10-real?Signature=Qwe31z3yJvttQPaqamFbyzlNwV0%3D&Expires=1470328603&AWSAccessKeyId=AKIAJFMV35HPPDAUG66A'

data = 190080 # works
data = 190081 # does not

image = b'1' * data
requests.put(url, data=image[:data], headers={'Content-Type': 'image/png'}, timeout=1.0)
```


Odd, I'm not getting a bad address message.

``` py
Traceback (most recent call last):
  File "test2700.py", line 10, in <module>
    requests.put(url, data=image[:data], headers={'Content-Type': 'image/png'}, timeout=1.0)
  File "/Users/ian/sandbox/requests/requests/api.py", line 122, in put
    return request('put', url, data=data, **kwargs)
  File "/Users/ian/sandbox/requests/requests/api.py", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File "/Users/ian/sandbox/requests/requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/ian/sandbox/requests/requests/sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "/Users/ian/sandbox/requests/requests/adapters.py", line 418, in send
    raise ConnectTimeout(e, request=request)
requests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='dev-vision-analysis.s3.amazonaws.com', port=443): Max retries exceeded with url: /c61888ab-58ea-467f-ab8e-201592b075b9-10-real?Signature=Qwe31z3yJvttQPaqamFbyzlNwV0%3D&Expires=1470328603&AWSAccessKeyId=AKIAJFMV35HPPDAUG66A (Caused by ConnectTimeoutError(<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x1025b1210>, 'Connection to dev-vision-analysis.s3.amazonaws.com timed out. (connect timeout=1.0)'))
```

It does cause a connection time out. That said, when I use the smaller data size (by 1 byte) then I get a Read timeout.


The read timeout I could understand if there's some kind of limit imposed by S3 (the service handling the PUT request). I'll look into that. Is there something more I can test on my end to find out why I'd be getting a 'Bad address' error?


> The read timeout I could understand if there's some kind of limit imposed by S3 (the service handling the PUT request).

I'm confused by this. The timeout is from the timeout parameter.

> Is there something more I can test on my end to find out why I'd be getting a 'Bad address' error?

You could try doing 

``` py
import socket

s = socket.socket()
s.settimeout(1.0)
s.connect(('dev-vision-analysis.s3.amazonaws.com', 443))
```

That _should_ emulate the `ReadTimeout`. That said, emulating the `ConnectTimeout` will be a bit more work and I'm still researching how we implement that.


> > The read timeout I could understand if there's some kind of limit imposed by S3 (the service handling >>the PUT request).
> 
> I'm confused by this. The timeout is from the timeout parameter.

Yeah, don't worry about it, you're right. I was just trying to brainstorm ideas for why we might see the behavior I'm seeing and didn't think about what actually causes a `ReadTimeout`

> You could try doing

Did that. The first time I ran it I got a `ReadTimeout` as you expected. After that successive attempts did not raise an error at all.


> After that successive attempts did not raise an error at all.

Can you show your successive attempts? Did you re-run the script or call `.connect(` over and over again?


I created a script with these contents:

``` python
(ve)12:42:52 {AE-697} ~/src/archer$ cat test-connect.py
#!/usr/bin/env python

import socket

s = socket.socket()
s.settimeout(1.0)
s.connect(('dev-vision-analysis.s3.amazonaws.com', 443))
print('made it through')
```

Got this console output:

```
12:43:51 {AE-697} ~/src/archer$ ./test-connect.py
made it through
12:44:00 {AE-697} ~/src/archer$ ./test-connect.py
made it through
12:44:01 {AE-697} ~/src/archer$ ./test-connect.py
made it through
12:44:03 {AE-697} ~/src/archer$ ./test-connect.py
made it through
12:44:04 {AE-697} ~/src/archer$ ./test-connect.py
made it through
12:44:05 {AE-697} ~/src/archer$ ./test-connect.py
made it through
12:44:06 {AE-697} ~/src/archer$ ./test-connect.py
made it through
12:44:07 {AE-697} ~/src/archer$ ./test-connect.py
made it through
```

I can't give you the output on the first run when it actually emitted the exception since I didn't save it and I can't reproduce it.