Ability to set timeout after response

For devs who use this great library, it would be very beneficial to be able to set the timeout AFTER initial connection. There are a few scenarios where this is useful but one of the main patterns/use cases is this:

```

import requests
import socket

# May or may not subclass threading.Thread
class Getter(object):
    def __init__(self):
        self.request = requests.get(url, stream=True)

    def run(self):
        with open(path, 'r+b') as file:

            bytes_consumed = 0
            while True:
                try:

                    chunk = self.request.raw.read(size)
                    if not chunk:
                        break
                    chunk_length = len(chunk)

                    file.write(chunk)
                    bytes_consumed += chunk_length

                except socket.timeout:
                    # handle incomplete download by using range header next time, etc.
```

Handling incomplete downloads due to connection loss is common and especially important when downloading large or many files (or both). As you can see, this can be achieved in a fairly straightforward way. The issue is there is really no good way to write tests for this. Each method would involve OS specific code which would also be a no-go for CI services.

What would be an option is the ability to set the timeout after establishing a connection. This way in a test you could do "r.timeout = (None, 0.00001)" and during reading it would simulate a timeout.

To my knowledge this is no way currently to inject a new Timeout class retroactively. Is this correct?


Out of interest, why do you need to set the timeout retroactively? You could just set the timeout in the constructor, could you not?


To test connection loss handling as explained above. Is there already some way to do this? I was looking through the code but couldn't quite wrap my head around how one might do it.


Oh I'm sorry, I see what you're doing. 

There is no way to change the timeout midway through handling, but it's not a widely useful feature. It'll likely be most effective for you just to either reach into the socket object directly to set the timeout, or to mock out the calls in order to test the connection loss. 


Thank you for your swift reply. Could you please explain the first approach?


So the socket object lives `response.raw._fp.fp`. You can call [`socket.settimeout()`](https://docs.python.org/2/library/socket.html#socket.socket.settimeout) on it. That's fundamentally how the timeouts work in requests.


Great thanks! So like this? `response.raw._fp.fp.raw._sock.settimeout(0.00001)`


Yup, that should work fine.


Hmm, doing that doesn't seem to affect `response.raw.read` at all even when setting timeout to extremely low. Though based on your help I _think_ I found a solution in `response.raw._fp.fp.raw._timeout_occurred = True`. Is that switch internally how it works? If I do a read after that it does indeed raise:

`requests.packages.urllib3.exceptions.ProtocolError: ("Connection broken: OSError('cannot read from timed out object',)", OSError('cannot read from timed out object',))`

So that's the correct timeout error, right?


That's not the correct timeout error, no: the one to expect is a urllib3 `ReadTimeoutError`.

At this point I have to ask why you're not just mocking out here to get the expected behaviour.


I guess I'm unsure how to do that in this case..


In this case replacing `self.request.raw` with a mock object, and then add a side-effect that raises the appropriate exception.


Thank you very much!